From: Lukasz Stanislawski Date: Thu, 24 Sep 2015 11:43:06 +0000 (+0200) Subject: lua: add lua engine to process internal logic X-Git-Tag: accepted/tizen/tv/20160311.055419~21 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5f959737dd27e5dd374bcd6db77e0770d49379fc;p=profile%2Ftv%2Fapps%2Fnative%2Fscreen-reader.git lua: add lua engine to process internal logic Change-Id: Idd194972e06d1c6764d9fde4178afb54eebfeafa --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 8044755..da4d5df 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ SET(SRCS ${CMAKE_SOURCE_DIR}/src/app_tracker.c ${CMAKE_SOURCE_DIR}/src/screen_reader_tts.c ${CMAKE_SOURCE_DIR}/src/screen_reader_vconf.c ${CMAKE_SOURCE_DIR}/src/smart_notification.c + ${CMAKE_SOURCE_DIR}/src/lua_engine.c ) @@ -23,6 +24,7 @@ SET(SRCS ${CMAKE_SOURCE_DIR}/src/app_tracker.c INCLUDE(CMakeLists.sub) SET(RESOURCE_DIR "${CMAKE_SOURCE_DIR}/res") SET(LOCALEDIR "/usr/apps/org.tizen.screen-reader/res/locale") +ADD_DEFINITIONS(-DSCRIPTDIR="/usr/apps/org.tizen.screen-reader/res/scripts") IF("${SEC_FEATURE_TAPI_ENABLE}" STREQUAL "1") MESSAGE("SEC_FEATURE_TAPI_ENABLE: ${SEC_FEATURE_TAPI_ENABLE}") @@ -65,6 +67,7 @@ pkg_check_modules(pkgs REQUIRED capi-network-bluetooth notification capi-network-wifi + lua ${TAPI_REQUIRED_PKG} ${CONDITIONAL_PACKAGES} ) @@ -85,6 +88,7 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${SLP_LD_PATH_FLAGS} ${SLP # Install INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) INSTALL(DIRECTORY ${RESOURCE_DIR}/icons DESTINATION res) +INSTALL(DIRECTORY ${RESOURCE_DIR}/scripts DESTINATION res) # Install Manifest File INSTALL(FILES org.tizen.screen-reader.xml DESTINATION /usr/share/packages) diff --git a/include/lua_engine.h b/include/lua_engine.h new file mode 100644 index 0000000..7ca15ea --- /dev/null +++ b/include/lua_engine.h @@ -0,0 +1,64 @@ +#ifndef _LUA_ENGINE_H__ +#define _LUA_ENGINE_H__ + +#include + +/** + * @brief Registers additional AT-SPI2 related method on given lua state. + * + * + * List of additional lua functions: + * + * desktop() -- global function returning desktop frame object. + * T() -- returns translated string using gettext function. + * + * # Accessible object class methods + * name() -- return string with accessible name of object. + * description() -- return string with accessible description of object. + * children() -- return table with accessible children references. + * parent() -- return accessible parent reference. + * role() -- return accessible role of object. + * inRelation(r) -- return table with references to accessible objects in relation 'd'. + * roleName() -- return string with name of the role. + * is(s) -- return true is accessible object has state 's'. + * index() -- return index of accessible object in its parent list. + * value() -- return reference to value object or nil + * selection() -- return reference to selection object or nil + * + * # Value object class methods + * current() -- return current value of value object. + * range() -- return minimal and maximal (tuple: min, max) values of value object. + * increment() -- return minimal incremetation value of value object. + * + * # Selection object class methods + * count() -- return number of selected children of selection object. + * isSelected(i) -- return true if 'i' child of selection object is selected. + * + * @param absolute path to lua script. + * @return 0 on success, different value on failure. + */ +int lua_engine_init(const char *script); + +/* + * @brief Create a description for given accessible object. + * + * Internally it calls 'describeObject' function from lua script loaded in + * lua_engine_init + * + * Function 'describeObject' must have following prototype: + * + * function describeObject(obj) + * return "some string" + * end + * + * @param AtspiAccessible reference + * @return string with a text describing object 'obj'. Should be free. + */ +char *lua_engine_describe_object(AtspiAccessible *obj); + +/* + * @brief Shutdowns lua engine + */ +void lua_engine_shutdown(); + +#endif diff --git a/include/screen_reader.h b/include/screen_reader.h index 7608a6f..28829ff 100644 --- a/include/screen_reader.h +++ b/include/screen_reader.h @@ -63,6 +63,7 @@ typedef struct _Service_Data char **available_apps; const char *text_from_dbus; + const char *lua_script_path; } Service_Data; Service_Data *get_pointer_to_service_data_struct(); diff --git a/include/screen_reader_spi.h b/include/screen_reader_spi.h index c616369..d020790 100644 --- a/include/screen_reader_spi.h +++ b/include/screen_reader_spi.h @@ -7,5 +7,6 @@ void spi_init(Service_Data *sd); void spi_event_listener_cb(AtspiEvent *event, void *user_data); char *spi_event_get_text_to_read(AtspiEvent *event, void *user_data); +void spi_shutdown(Service_Data *sd); #endif /* SCREEN_READER_SPI_H_ */ diff --git a/packaging/org.tizen.screen-reader.spec b/packaging/org.tizen.screen-reader.spec index 9d10be4..f75613f 100755 --- a/packaging/org.tizen.screen-reader.spec +++ b/packaging/org.tizen.screen-reader.spec @@ -37,6 +37,7 @@ BuildRequires: pkgconfig(capi-network-wifi) %if "%{?profile}" != "tv" BuildRequires: pkgconfig(tapi) %endif +BuildRequires: pkgconfig(lua) %description An utility library for developers of the menu screen. @@ -84,3 +85,4 @@ rm -rf %{buildroot} %{AppInstallPath}/res/icons/screen-reader.png %{AppInstallPath}/res/locale/*/LC_MESSAGES/* /usr/share/packages/%{name}.xml +%{AppInstallPath}/res/scripts/* diff --git a/res/po/en_US.po b/res/po/en_US.po index 04325e4..4476e6d 100644 --- a/res/po/en_US.po +++ b/res/po/en_US.po @@ -51,7 +51,7 @@ msgid "IDS_TRAIT_GROUP_INDEX_COLLAPSED" msgstr "Expandable list, Double tap to expand" msgid "IDS_TRAIT_MENU_ITEM_TAB_INDEX" -msgstr "Tab %1$d of %2$d" +msgstr "Tab %d of %d" msgid "IDS_TRAIT_TEXT_EDIT" msgstr "Double tap to edit" diff --git a/res/scripts/mobile.lua b/res/scripts/mobile.lua new file mode 100644 index 0000000..c53c2e0 --- /dev/null +++ b/res/scripts/mobile.lua @@ -0,0 +1,129 @@ +function entry_trait(obj) + local ret = "" + if obj:is(FOCUSED) then + ret = T("IDS_TRAIT_TEXT_EDIT_FOCUSED") + else + ret = T("IDS_TRAIT_TEXT_EDIT") + end + return obj:roleName() .. ", " .. ret +end + +function menu_item_trait(obj) + n = table.getn(obj:parent():children()) + return string.format(T("IDS_TRAIT_MENU_ITEM_TAB_INDEX"), obj:index() + 1, n) +end + +function popup_menu_trait(obj) + local tr = { T("IDS_TRAIT_CTX_POPUP") , T("IDS_TRAIT_SHOWING") , tostring(table.getn(obj:children())), + T("IDS_TRAIT_ITEMS") , T("IDS_TRAIT_POPUP_CLOSE")} + return table.concat(tr, " ") +end + +function dialog_trait(obj) + local n = table.getn(obj:children()) + local ret = T("IDS_TRAIT_POPUP") + if n > 0 then + ret = ret .. T("IDS_TRAIT_SHOWING") .. " " .. tostring(n) .. " " .. T("IDS_TRAIT_ITEMS") + end + return ret .. T("IDS_TRAIT_POPUP_CLOSE") +end + +function list_item_trait(obj) + local ret = "" + local p = obj:parent() + if p and p:is(MULTISELECTABLE) then + if obj:is(SELECTED) then + ret = ret .. T("IDS_TRAIT_ITEM_SELECTED") + end + if p:selection() then + ret = ret .. string.format(T("IDS_TRAIT_ITEM_SELECTED_COUNT"), p:selection():count()) + end + else + if obj:is(EXPANDABLE) then + if obj:is(EXPANDED) then + ret = ret .. T("IDS_TRAIT_GROUP_INDEX_EXPANDED") + else + ret = ret .. T("IDS_TRAIT_GROUP_INDEX_COLLAPSED") + end + end + end + return ret +end + +function check_radio_trait(obj) + if obj:is(CHECKED) then + return T("IDS_TRAIT_CHECK_BOX_SELECTED") + else + return T("IDS_TRAIT_CHECK_BOX_NOT_SELECTED") + end +end + +function push_button_trait(obj) + return T("IDS_TRAIT_PUSH_BUTTON") +end + +function progress_bar_trait(obj) + if obj:value() then + cv = obj:value():current() + if cv >= 0 then + return string.format(T("IDS_TRAIT_PD_PROGRESSBAR_PERCENT"), cv * 100) + else + return T("IDS_TRAIT_PD_PROGRESSBAR") + end + end + return "" +end + +function toggle_button_trait(obj) + if obj:is(CHECKED) then + local state = T("IDS_TRAIT_TOGGLE_BUTTON_ON") + else + local state = T("IDS_TRAIT_TOGGLE_BUTTON_OFF") + end + return T("IDS_TRAIT_TOGGLE_BUTTON") .. ", " .. state +end + +function heading_trait(obj) + return "" +end + +function default_trait(obj) + return obj:roleName() +end + +local trait_map = { + [ENTRY] = entry_trait, + [MENU_ITEM] = menu_item_trait, + [POPUP_MENU] = popup_menu_trait, + [DIALOG] = dialog_trait, + [LIST_ITEM] = list_item_trait, + [CHECK_BOX] = check_radio_trait, + [RADIO_BUTTON] = check_radio_trait, + [PUSH_BUTTON] = push_button_trait, + [PROGRESS_BAR] = progress_bar_trait, + [TOGGLE_BUTTON] = toggle_button_trait, + [HEADING] = heading_trait, +} + +function trait(obj) + local func = trait_map[obj:role()] + if func ~= nil then + return func(obj) + else + return default_trait(obj) + end +end + +function describeObject(obj) + local related_trait = {} + for k, target in ipairs(obj:inRelation(RELATION_DESCRIBED_BY)) do + table.insert(related_trait, trait(target)) + end + local ret = {obj:name(), trait(obj), obj:description(), table.concat(related_trait, ", ")} + for i=#ret,1,-1 do + if ret[i] == nil or ret[i] == "" then + table.remove(ret, i) + end + end + return table.concat(ret, ", ") +end diff --git a/src/lua_engine.c b/src/lua_engine.c new file mode 100644 index 0000000..b2d8207 --- /dev/null +++ b/src/lua_engine.c @@ -0,0 +1,809 @@ +#include +#include +#include + +#include +#include + +#include "logger.h" +#include "lua_engine.h" + +#include + +#define ACCESSIBLE_CLASS_NAME "Accessible" +#define VALUE_CLASS_NAME "Value" +#define SELECTION_CLASS_NAME "Selection" + +#define GERROR_CHECK(err) \ + if (err) { lua_error(L); printf("GError: %s\n", err->message); g_error_free(err); } + +static lua_State *L; + + +static void *_pop_class_obj(lua_State *L, int index, int narg, const char *class) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void **ret = lua_touserdata(L, index); + if (!ret) luaL_typerror(L, narg, class); + return *ret; +} + +static void _push_class_obj(lua_State *L, void *obj, const char *class) +{ + void **ptr = lua_newuserdata(L, sizeof(void*)); + *ptr = obj; + luaL_getmetatable(L, class); + lua_setmetatable(L, -2); +} + +static int _accessible_name(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, -1, 1, ACCESSIBLE_CLASS_NAME); + GError *err = NULL; + if (!obj) return 0; + + char *name = atspi_accessible_get_name(obj, &err); + GERROR_CHECK(err); + + lua_pushstring(L, name); + g_free(name); + return 1; +} + +static int _accessible_description(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + GError *err = NULL; + if (!obj) + return 0; + char *name = atspi_accessible_get_description(obj, &err); + GERROR_CHECK(err); + + lua_pushstring(L, name); + g_free(name); + return 1; +} + +static int l_get_root(lua_State *L) { + AtspiAccessible *root = atspi_get_desktop(0); + _push_class_obj(L, root, ACCESSIBLE_CLASS_NAME); + return 1; +} + +static int l_get_translation(lua_State *L) { + const char *str = lua_tostring(L, -1); + lua_pushstring(L, _(str)); + return 1; +} + +static int _accessible_children(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + GError *err = NULL; + if (!obj) + return 0; + int i, n = atspi_accessible_get_child_count(obj, &err); + GERROR_CHECK(err); + + lua_createtable(L, n, 0); + + for (i = 0; i < n; i++) + { + AtspiAccessible *child = atspi_accessible_get_child_at_index(obj, i, &err); + if (!child) continue; + GERROR_CHECK(err); + lua_pushinteger(L, i + 1); + _push_class_obj(L, child, ACCESSIBLE_CLASS_NAME); + lua_settable(L, -3); + } + return 1; +} + +static int _accessible_parent(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + GError *err = NULL; + if (!obj) return 0; + + AtspiAccessible *parent = atspi_accessible_get_parent(obj, &err); + if (!parent) return 0; + GERROR_CHECK(err); + _push_class_obj(L, parent, ACCESSIBLE_CLASS_NAME); + + return 1; +} + +static int _accessible_role(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + GError *err = NULL; + if (!obj) return 0; + + AtspiRole role = atspi_accessible_get_role(obj, &err); + GERROR_CHECK(err); + + lua_pushinteger(L, role); + + return 1; +} + +static int _accessible_role_name(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + GError *err = NULL; + if (!obj) { + return 0; + } + char *name = atspi_accessible_get_localized_role_name(obj, &err); + GERROR_CHECK(err); + + lua_pushstring(L, name); + g_free(name); + return 1; +} + +static int _accessible_is(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + AtspiStateType type = lua_tonumber(L, -1); + + AtspiStateSet *ss = atspi_accessible_get_state_set(obj); + + if (atspi_state_set_contains(ss, type)) + lua_pushboolean(L, 1); + else + lua_pushboolean(L, 0); + + return 1; +} + +static int _accessible_index(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + GError *err = NULL; + if (!obj) return 0; + + int idx = atspi_accessible_get_index_in_parent(obj, &err); + GERROR_CHECK(err); + + lua_pushinteger(L, idx); + return 1; +} + +static int _accessible_relations(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + AtspiRelationType type = lua_tonumber(L, -1); + GError *err = NULL; + int i, j; + + lua_newtable(L); + if (!obj) return 1; + GArray *rels = atspi_accessible_get_relation_set(obj, &err); + GERROR_CHECK(err); + if (!rels) return 1; + + for (i = 0; i < rels->len; i++) + { + AtspiRelation *rel = g_array_index(rels, AtspiRelation*, i); + if (atspi_relation_get_relation_type(rel) == type) + { + for (j = 0; j < atspi_relation_get_n_targets(rel); j++) + { + AtspiAccessible *target = atspi_relation_get_target(rel, j); + if (!target) continue; + lua_pushinteger(L, j); + _push_class_obj(L, target, ACCESSIBLE_CLASS_NAME); + lua_settable(L, -3); + } + } + g_object_unref(rel); + } + g_array_free(rels, TRUE); + + return 1; +} + +static int _accessible_value(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + AtspiValue *val = atspi_accessible_get_value_iface(obj); + if (!val) + { + lua_pushnil(L); + return 1; + } + _push_class_obj(L, val, VALUE_CLASS_NAME); + return 1; +} + +static int _accessible_selection(lua_State *L) { + AtspiAccessible *obj = _pop_class_obj(L, 1, 1, ACCESSIBLE_CLASS_NAME); + AtspiSelection *sel = atspi_accessible_get_selection_iface(obj); + if (!sel) + { + lua_pushnil(L); + return 1; + } + _push_class_obj(L, sel, SELECTION_CLASS_NAME); + return 1; +} + +static int _gobject_unref(lua_State *L) { +#ifdef SCREEN_READER_FLAT_NAVI_TEST_DUMMY_IMPLEMENTATION + return 0; +#else + void **ret = lua_touserdata(L, -1); + g_object_unref(*ret); + return 0; +#endif +} + +static const luaL_reg _meta_methods[] = { + { "__gc", _gobject_unref}, + { NULL, NULL} +}; + +static const luaL_reg _accessible_methods[] = { + { "name", _accessible_name }, + { "description", _accessible_description }, + { "children", _accessible_children }, + { "parent", _accessible_parent }, + { "role", _accessible_role }, + { "inRelation", _accessible_relations }, + { "roleName", _accessible_role_name }, + { "is", _accessible_is }, + { "index", _accessible_index }, + { "value", _accessible_value }, + { "selection", _accessible_selection }, + { NULL, NULL} +}; + +static int _value_current_value(lua_State *L) { + AtspiValue *val = _pop_class_obj(L, -1, 1, VALUE_CLASS_NAME); + GError *err = NULL; + + double cv = atspi_value_get_current_value(val, &err); + GERROR_CHECK(err); + + lua_pushnumber(L, cv); + + return 1; +} + +static int _value_range(lua_State *L) { + AtspiValue *val = _pop_class_obj(L, -1, 1, VALUE_CLASS_NAME); + GError *err = NULL; + double max, min; + + max = atspi_value_get_maximum_value(val, &err); + GERROR_CHECK(err); + + min = atspi_value_get_minimum_value(val, &err); + GERROR_CHECK(err); + + lua_pushnumber(L, min); + lua_pushnumber(L, max); + + return 2; +} + +static int _value_increment(lua_State *L) { + AtspiValue *val = _pop_class_obj(L, 1, 1, VALUE_CLASS_NAME); + GError *err = NULL; + + double mi = atspi_value_get_minimum_increment(val, &err); + GERROR_CHECK(err); + + lua_pushnumber(L, mi); + + return 1; +} + +static const luaL_reg _value_methods[] = { + { "current", _value_current_value }, + { "range", _value_range }, + { "increment", _value_increment }, + { NULL, NULL} +}; + +static int _selection_is_selected(lua_State *L) { + AtspiSelection *sel = _pop_class_obj(L, 1, 1, SELECTION_CLASS_NAME); + GError *err = NULL; + int id = lua_tointeger(L, -1); + + gboolean ret = atspi_selection_is_child_selected(sel, id, &err); + GERROR_CHECK(err); + + lua_pushboolean(L, ret); + + return 1; +} + +static int _selection_count(lua_State *L) { + AtspiSelection *sel = _pop_class_obj(L, 1, 1, SELECTION_CLASS_NAME); + GError *err = NULL; + + int mi = atspi_selection_get_n_selected_children(sel, &err); + GERROR_CHECK(err); + + lua_pushinteger(L, mi); + + return 1; +} + +static const luaL_reg _selection_methods[] = { + { "count", _selection_count }, + { "isSelected", _selection_is_selected }, + { NULL, NULL} +}; + +static void _register_role_enums(lua_State *L) +{ + lua_pushinteger(L, ATSPI_ROLE_INVALID); + lua_setglobal(L, "INVALID"); + lua_pushinteger(L, ATSPI_ROLE_ACCELERATOR_LABEL); + lua_setglobal(L, "ACCELERATOR_LABEL"); + lua_pushinteger(L, ATSPI_ROLE_ALERT); + lua_setglobal(L, "ALERT"); + lua_pushinteger(L, ATSPI_ROLE_ANIMATION); + lua_setglobal(L, "ANIMATION"); + lua_pushinteger(L, ATSPI_ROLE_ARROW); + lua_setglobal(L, "ARROW"); + lua_pushinteger(L, ATSPI_ROLE_CALENDAR); + lua_setglobal(L, "CALENDAR"); + lua_pushinteger(L, ATSPI_ROLE_CANVAS); + lua_setglobal(L, "CANVAS"); + lua_pushinteger(L, ATSPI_ROLE_CHECK_BOX); + lua_setglobal(L, "CHECK_BOX"); + lua_pushinteger(L, ATSPI_ROLE_CHECK_MENU_ITEM); + lua_setglobal(L, "CHECK_MENU_ITEM"); + lua_pushinteger(L, ATSPI_ROLE_COLOR_CHOOSER); + lua_setglobal(L, "COLOR_CHOOSER"); + lua_pushinteger(L, ATSPI_ROLE_COLUMN_HEADER); + lua_setglobal(L, "COLUMN_HEADER"); + lua_pushinteger(L, ATSPI_ROLE_COMBO_BOX); + lua_setglobal(L, "COMBO_BOX"); + lua_pushinteger(L, ATSPI_ROLE_DATE_EDITOR); + lua_setglobal(L, "DATE_EDITOR"); + lua_pushinteger(L, ATSPI_ROLE_DESKTOP_ICON); + lua_setglobal(L, "DESKTOP_ICON"); + lua_pushinteger(L, ATSPI_ROLE_DESKTOP_FRAME); + lua_setglobal(L, "DESKTOP_FRAME"); + lua_pushinteger(L, ATSPI_ROLE_DIAL); + lua_setglobal(L, "DIAL"); + lua_pushinteger(L, ATSPI_ROLE_DIALOG); + lua_setglobal(L, "DIALOG"); + lua_pushinteger(L, ATSPI_ROLE_DIRECTORY_PANE); + lua_setglobal(L, "DIRECTORY_PANE"); + lua_pushinteger(L, ATSPI_ROLE_DRAWING_AREA); + lua_setglobal(L, "DRAWING_AREA"); + lua_pushinteger(L, ATSPI_ROLE_FILE_CHOOSER); + lua_setglobal(L, "FILE_CHOOSER"); + lua_pushinteger(L, ATSPI_ROLE_FILLER); + lua_setglobal(L, "FILLER"); + lua_pushinteger(L, ATSPI_ROLE_FOCUS_TRAVERSABLE); + lua_setglobal(L, "FOCUS_TRAVERSABLE"); + lua_pushinteger(L, ATSPI_ROLE_FONT_CHOOSER); + lua_setglobal(L, "FONT_CHOOSER"); + lua_pushinteger(L, ATSPI_ROLE_FRAME); + lua_setglobal(L, "FRAME"); + lua_pushinteger(L, ATSPI_ROLE_GLASS_PANE); + lua_setglobal(L, "GLASS_PANE"); + lua_pushinteger(L, ATSPI_ROLE_HTML_CONTAINER); + lua_setglobal(L, "HTML_CONTAINER"); + lua_pushinteger(L, ATSPI_ROLE_ICON); + lua_setglobal(L, "ICON"); + lua_pushinteger(L, ATSPI_ROLE_IMAGE); + lua_setglobal(L, "IMAGE"); + lua_pushinteger(L, ATSPI_ROLE_INTERNAL_FRAME); + lua_setglobal(L, "INTERNAL_FRAME"); + lua_pushinteger(L, ATSPI_ROLE_LABEL); + lua_setglobal(L, "LABEL"); + lua_pushinteger(L, ATSPI_ROLE_LAYERED_PANE); + lua_setglobal(L, "LAYERED_PANE"); + lua_pushinteger(L, ATSPI_ROLE_LIST); + lua_setglobal(L, "LIST"); + lua_pushinteger(L, ATSPI_ROLE_LIST_ITEM); + lua_setglobal(L, "LIST_ITEM"); + lua_pushinteger(L, ATSPI_ROLE_MENU); + lua_setglobal(L, "MENU"); + lua_pushinteger(L, ATSPI_ROLE_MENU_BAR); + lua_setglobal(L, "MENU_BAR"); + lua_pushinteger(L, ATSPI_ROLE_MENU_ITEM); + lua_setglobal(L, "MENU_ITEM"); + lua_pushinteger(L, ATSPI_ROLE_OPTION_PANE); + lua_setglobal(L, "OPTION_PANE"); + lua_pushinteger(L, ATSPI_ROLE_PAGE_TAB); + lua_setglobal(L, "PAGE_TAB"); + lua_pushinteger(L, ATSPI_ROLE_PAGE_TAB_LIST); + lua_setglobal(L, "PAGE_TAB_LIST"); + lua_pushinteger(L, ATSPI_ROLE_PANEL); + lua_setglobal(L, "PANEL"); + lua_pushinteger(L, ATSPI_ROLE_PASSWORD_TEXT); + lua_setglobal(L, "PASSWORD_TEXT"); + lua_pushinteger(L, ATSPI_ROLE_POPUP_MENU); + lua_setglobal(L, "POPUP_MENU"); + lua_pushinteger(L, ATSPI_ROLE_PROGRESS_BAR); + lua_setglobal(L, "PROGRESS_BAR"); + lua_pushinteger(L, ATSPI_ROLE_PUSH_BUTTON); + lua_setglobal(L, "PUSH_BUTTON"); + lua_pushinteger(L, ATSPI_ROLE_RADIO_BUTTON); + lua_setglobal(L, "RADIO_BUTTON"); + lua_pushinteger(L, ATSPI_ROLE_RADIO_MENU_ITEM); + lua_setglobal(L, "RADIO_MENU_ITEM"); + lua_pushinteger(L, ATSPI_ROLE_ROOT_PANE); + lua_setglobal(L, "ROOT_PANE"); + lua_pushinteger(L, ATSPI_ROLE_ROW_HEADER); + lua_setglobal(L, "ROW_HEADER"); + lua_pushinteger(L, ATSPI_ROLE_SCROLL_BAR); + lua_setglobal(L, "SCROLL_BAR"); + lua_pushinteger(L, ATSPI_ROLE_SCROLL_PANE); + lua_setglobal(L, "SCROLL_PANE"); + lua_pushinteger(L, ATSPI_ROLE_SEPARATOR); + lua_setglobal(L, "SEPARATOR"); + lua_pushinteger(L, ATSPI_ROLE_SLIDER); + lua_setglobal(L, "SLIDER"); + lua_pushinteger(L, ATSPI_ROLE_SPIN_BUTTON); + lua_setglobal(L, "SPIN_BUTTON"); + lua_pushinteger(L, ATSPI_ROLE_SPLIT_PANE); + lua_setglobal(L, "SPLIT_PANE"); + lua_pushinteger(L, ATSPI_ROLE_STATUS_BAR); + lua_setglobal(L, "STATUS_BAR"); + lua_pushinteger(L, ATSPI_ROLE_TABLE); + lua_setglobal(L, "TABLE"); + lua_pushinteger(L, ATSPI_ROLE_TABLE_CELL); + lua_setglobal(L, "TABLE_CELL"); + lua_pushinteger(L, ATSPI_ROLE_TABLE_COLUMN_HEADER); + lua_setglobal(L, "TABLE_COLUMN_HEADER"); + lua_pushinteger(L, ATSPI_ROLE_TABLE_ROW_HEADER); + lua_setglobal(L, "TABLE_ROW_HEADER"); + lua_pushinteger(L, ATSPI_ROLE_TEAROFF_MENU_ITEM); + lua_setglobal(L, "TEAROFF_MENU_ITEM"); + lua_pushinteger(L, ATSPI_ROLE_TERMINAL); + lua_setglobal(L, "TERMINAL"); + lua_pushinteger(L, ATSPI_ROLE_TEXT); + lua_setglobal(L, "TEXT"); + lua_pushinteger(L, ATSPI_ROLE_TOGGLE_BUTTON); + lua_setglobal(L, "TOGGLE_BUTTON"); + lua_pushinteger(L, ATSPI_ROLE_TOOL_BAR); + lua_setglobal(L, "TOOL_BAR"); + lua_pushinteger(L, ATSPI_ROLE_TOOL_TIP); + lua_setglobal(L, "TOOL_TIP"); + lua_pushinteger(L, ATSPI_ROLE_TREE); + lua_setglobal(L, "TREE"); + lua_pushinteger(L, ATSPI_ROLE_TREE_TABLE); + lua_setglobal(L, "TREE_TABLE"); + lua_pushinteger(L, ATSPI_ROLE_UNKNOWN); + lua_setglobal(L, "UNKNOWN"); + lua_pushinteger(L, ATSPI_ROLE_VIEWPORT); + lua_setglobal(L, "VIEWPORT"); + lua_pushinteger(L, ATSPI_ROLE_WINDOW); + lua_setglobal(L, "WINDOW"); + lua_pushinteger(L, ATSPI_ROLE_EXTENDED); + lua_setglobal(L, "EXTENDED"); + lua_pushinteger(L, ATSPI_ROLE_HEADER); + lua_setglobal(L, "HEADER"); + lua_pushinteger(L, ATSPI_ROLE_FOOTER); + lua_setglobal(L, "FOOTER"); + lua_pushinteger(L, ATSPI_ROLE_PARAGRAPH); + lua_setglobal(L, "PARAGRAPH"); + lua_pushinteger(L, ATSPI_ROLE_RULER); + lua_setglobal(L, "RULER"); + lua_pushinteger(L, ATSPI_ROLE_APPLICATION); + lua_setglobal(L, "APPLICATION"); + lua_pushinteger(L, ATSPI_ROLE_AUTOCOMPLETE); + lua_setglobal(L, "AUTOCOMPLETE"); + lua_pushinteger(L, ATSPI_ROLE_EDITBAR); + lua_setglobal(L, "EDITBAR"); + lua_pushinteger(L, ATSPI_ROLE_EMBEDDED); + lua_setglobal(L, "EMBEDDED"); + lua_pushinteger(L, ATSPI_ROLE_ENTRY); + lua_setglobal(L, "ENTRY"); + lua_pushinteger(L, ATSPI_ROLE_CHART); + lua_setglobal(L, "CHART"); + lua_pushinteger(L, ATSPI_ROLE_CAPTION); + lua_setglobal(L, "CAPTION"); + lua_pushinteger(L, ATSPI_ROLE_DOCUMENT_FRAME); + lua_setglobal(L, "DOCUMENT_FRAME"); + lua_pushinteger(L, ATSPI_ROLE_HEADING); + lua_setglobal(L, "HEADING"); + lua_pushinteger(L, ATSPI_ROLE_PAGE); + lua_setglobal(L, "PAGE"); + lua_pushinteger(L, ATSPI_ROLE_SECTION); + lua_setglobal(L, "SECTION"); + lua_pushinteger(L, ATSPI_ROLE_REDUNDANT_OBJECT); + lua_setglobal(L, "REDUNDANT_OBJECT"); + lua_pushinteger(L, ATSPI_ROLE_FORM); + lua_setglobal(L, "FORM"); + lua_pushinteger(L, ATSPI_ROLE_LINK); + lua_setglobal(L, "LINK"); + lua_pushinteger(L, ATSPI_ROLE_INPUT_METHOD_WINDOW); + lua_setglobal(L, "INPUT_METHOD_WINDOW"); + lua_pushinteger(L, ATSPI_ROLE_TABLE_ROW); + lua_setglobal(L, "TABLE_ROW"); + lua_pushinteger(L, ATSPI_ROLE_TREE_ITEM); + lua_setglobal(L, "TREE_ITEM"); + lua_pushinteger(L, ATSPI_ROLE_DOCUMENT_SPREADSHEET); + lua_setglobal(L, "DOCUMENT_SPREADSHEET"); + lua_pushinteger(L, ATSPI_ROLE_DOCUMENT_PRESENTATION); + lua_setglobal(L, "DOCUMENT_PRESENTATION"); + lua_pushinteger(L, ATSPI_ROLE_DOCUMENT_TEXT); + lua_setglobal(L, "DOCUMENT_TEXT"); + lua_pushinteger(L, ATSPI_ROLE_DOCUMENT_WEB); + lua_setglobal(L, "DOCUMENT_WEB"); + lua_pushinteger(L, ATSPI_ROLE_DOCUMENT_EMAIL); + lua_setglobal(L, "DOCUMENT_EMAIL"); + lua_pushinteger(L, ATSPI_ROLE_COMMENT); + lua_setglobal(L, "COMMENT"); + lua_pushinteger(L, ATSPI_ROLE_LIST_BOX); + lua_setglobal(L, "LIST_BOX"); + lua_pushinteger(L, ATSPI_ROLE_GROUPING); + lua_setglobal(L, "GROUPING"); + lua_pushinteger(L, ATSPI_ROLE_IMAGE_MAP); + lua_setglobal(L, "IMAGE_MAP"); + lua_pushinteger(L, ATSPI_ROLE_NOTIFICATION); + lua_setglobal(L, "NOTIFICATION"); + lua_pushinteger(L, ATSPI_ROLE_INFO_BAR); + lua_setglobal(L, "INFO_BAR"); + lua_pushinteger(L, ATSPI_ROLE_LEVEL_BAR); + lua_setglobal(L, "LEVEL_BAR"); + lua_pushinteger(L, ATSPI_ROLE_TITLE_BAR); + lua_setglobal(L, "TITLE_BAR"); + lua_pushinteger(L, ATSPI_ROLE_BLOCK_QUOTE); + lua_setglobal(L, "BLOCK_QUOTE"); + lua_pushinteger(L, ATSPI_ROLE_AUDIO); + lua_setglobal(L, "AUDIO"); + lua_pushinteger(L, ATSPI_ROLE_VIDEO); + lua_setglobal(L, "VIDEO"); + lua_pushinteger(L, ATSPI_ROLE_DEFINITION); + lua_setglobal(L, "DEFINITION"); + lua_pushinteger(L, ATSPI_ROLE_ARTICLE); + lua_setglobal(L, "ARTICLE"); + lua_pushinteger(L, ATSPI_ROLE_LANDMARK); + lua_setglobal(L, "LANDMARK"); + lua_pushinteger(L, ATSPI_ROLE_LOG); + lua_setglobal(L, "LOG"); + lua_pushinteger(L, ATSPI_ROLE_MARQUEE); + lua_setglobal(L, "MARQUEE"); + lua_pushinteger(L, ATSPI_ROLE_MATH); + lua_setglobal(L, "MATH"); + lua_pushinteger(L, ATSPI_ROLE_RATING); + lua_setglobal(L, "RATING"); + lua_pushinteger(L, ATSPI_ROLE_TIMER); + lua_setglobal(L, "TIMER"); + lua_pushinteger(L, ATSPI_ROLE_STATIC); + lua_setglobal(L, "STATIC"); + lua_pushinteger(L, ATSPI_ROLE_MATH_FRACTION); + lua_setglobal(L, "MATH_FRACTION"); + lua_pushinteger(L, ATSPI_ROLE_MATH_ROOT); + lua_setglobal(L, "MATH_ROOT"); + lua_pushinteger(L, ATSPI_ROLE_SUBSCRIPT); + lua_setglobal(L, "SUBSCRIPT"); + lua_pushinteger(L, ATSPI_ROLE_SUPERSCRIPT); + lua_setglobal(L, "SUPERSCRIPT"); + lua_pushinteger(L, ATSPI_ROLE_LAST_DEFINED); + lua_setglobal(L, "LAST_DEFINED"); + + // relations enums + lua_pushinteger(L, ATSPI_RELATION_NULL); + lua_setglobal(L, "RELATION_NULL"); + lua_pushinteger(L, ATSPI_RELATION_LABEL_FOR); + lua_setglobal(L, "RELATION_LABEL_FOR"); + lua_pushinteger(L, ATSPI_RELATION_LABELLED_BY); + lua_setglobal(L, "RELATION_LABELLED_BY"); + lua_pushinteger(L, ATSPI_RELATION_CONTROLLER_FOR); + lua_setglobal(L, "RELATION_CONTROLLER_FOR"); + lua_pushinteger(L, ATSPI_RELATION_CONTROLLED_BY); + lua_setglobal(L, "RELATION_CONTROLLED_BY"); + lua_pushinteger(L, ATSPI_RELATION_MEMBER_OF); + lua_setglobal(L, "RELATION_MEMBER_OF"); + lua_pushinteger(L, ATSPI_RELATION_TOOLTIP_FOR); + lua_setglobal(L, "RELATION_TOOLTIP_FOR"); + lua_pushinteger(L, ATSPI_RELATION_NODE_CHILD_OF); + lua_setglobal(L, "RELATION_NODE_CHILD_OF"); + lua_pushinteger(L, ATSPI_RELATION_NODE_PARENT_OF); + lua_setglobal(L, "RELATION_NODE_PARENT_OF"); + lua_pushinteger(L, ATSPI_RELATION_EXTENDED); + lua_setglobal(L, "RELATION_EXTENDED"); + lua_pushinteger(L, ATSPI_RELATION_FLOWS_TO); + lua_setglobal(L, "RELATION_FLOWS_TO"); + lua_pushinteger(L, ATSPI_RELATION_FLOWS_FROM); + lua_setglobal(L, "RELATION_FLOWS_FROM"); + lua_pushinteger(L, ATSPI_RELATION_SUBWINDOW_OF); + lua_setglobal(L, "RELATION_SUBWINDOW_OF"); + lua_pushinteger(L, ATSPI_RELATION_EMBEDS); + lua_setglobal(L, "RELATION_EMBEDS"); + lua_pushinteger(L, ATSPI_RELATION_EMBEDDED_BY); + lua_setglobal(L, "RELATION_EMBEDDED_BY"); + lua_pushinteger(L, ATSPI_RELATION_POPUP_FOR); + lua_setglobal(L, "RELATION_POPUP_FOR"); + lua_pushinteger(L, ATSPI_RELATION_PARENT_WINDOW_OF); + lua_setglobal(L, "RELATION_PARENT_WINDOW_OF"); + lua_pushinteger(L, ATSPI_RELATION_DESCRIPTION_FOR); + lua_setglobal(L, "RELATION_DESCRIPTION_FOR"); + lua_pushinteger(L, ATSPI_RELATION_DESCRIBED_BY); + lua_setglobal(L, "RELATION_DESCRIBED_BY"); + lua_pushinteger(L, ATSPI_RELATION_LAST_DEFINED); + lua_setglobal(L, "RELATION_LAST_DEFINED"); + + // state enums + lua_pushinteger(L, ATSPI_STATE_INVALID); + lua_setglobal(L, "INVALID"); + lua_pushinteger(L, ATSPI_STATE_ACTIVE); + lua_setglobal(L, "ACTIVE"); + lua_pushinteger(L, ATSPI_STATE_ARMED); + lua_setglobal(L, "ARMED"); + lua_pushinteger(L, ATSPI_STATE_BUSY); + lua_setglobal(L, "BUSY"); + lua_pushinteger(L, ATSPI_STATE_CHECKED); + lua_setglobal(L, "CHECKED"); + lua_pushinteger(L, ATSPI_STATE_COLLAPSED); + lua_setglobal(L, "COLLAPSED"); + lua_pushinteger(L, ATSPI_STATE_DEFUNCT); + lua_setglobal(L, "DEFUNCT"); + lua_pushinteger(L, ATSPI_STATE_EDITABLE); + lua_setglobal(L, "EDITABLE"); + lua_pushinteger(L, ATSPI_STATE_ENABLED); + lua_setglobal(L, "ENABLED"); + lua_pushinteger(L, ATSPI_STATE_EXPANDABLE); + lua_setglobal(L, "EXPANDABLE"); + lua_pushinteger(L, ATSPI_STATE_EXPANDED); + lua_setglobal(L, "EXPANDED"); + lua_pushinteger(L, ATSPI_STATE_FOCUSABLE); + lua_setglobal(L, "FOCUSABLE"); + lua_pushinteger(L, ATSPI_STATE_FOCUSED); + lua_setglobal(L, "FOCUSED"); + lua_pushinteger(L, ATSPI_STATE_HAS_TOOLTIP); + lua_setglobal(L, "HAS_TOOLTIP"); + lua_pushinteger(L, ATSPI_STATE_HORIZONTAL); + lua_setglobal(L, "HORIZONTAL"); + lua_pushinteger(L, ATSPI_STATE_ICONIFIED); + lua_setglobal(L, "ICONIFIED"); + lua_pushinteger(L, ATSPI_STATE_MODAL); + lua_setglobal(L, "MODAL"); + lua_pushinteger(L, ATSPI_STATE_MULTI_LINE); + lua_setglobal(L, "MULTI_LINE"); + lua_pushinteger(L, ATSPI_STATE_MULTISELECTABLE); + lua_setglobal(L, "MULTISELECTABLE"); + lua_pushinteger(L, ATSPI_STATE_OPAQUE); + lua_setglobal(L, "OPAQUE"); + lua_pushinteger(L, ATSPI_STATE_PRESSED); + lua_setglobal(L, "PRESSED"); + lua_pushinteger(L, ATSPI_STATE_RESIZABLE); + lua_setglobal(L, "RESIZABLE"); + lua_pushinteger(L, ATSPI_STATE_SELECTABLE); + lua_setglobal(L, "SELECTABLE"); + lua_pushinteger(L, ATSPI_STATE_SELECTED); + lua_setglobal(L, "SELECTED"); + lua_pushinteger(L, ATSPI_STATE_SENSITIVE); + lua_setglobal(L, "SENSITIVE"); + lua_pushinteger(L, ATSPI_STATE_SHOWING); + lua_setglobal(L, "SHOWING"); + lua_pushinteger(L, ATSPI_STATE_SINGLE_LINE); + lua_setglobal(L, "SINGLE_LINE"); + lua_pushinteger(L, ATSPI_STATE_STALE); + lua_setglobal(L, "STALE"); + lua_pushinteger(L, ATSPI_STATE_TRANSIENT); + lua_setglobal(L, "TRANSIENT"); + lua_pushinteger(L, ATSPI_STATE_VERTICAL); + lua_setglobal(L, "VERTICAL"); + lua_pushinteger(L, ATSPI_STATE_VISIBLE); + lua_setglobal(L, "VISIBLE"); + lua_pushinteger(L, ATSPI_STATE_MANAGES_DESCENDANTS); + lua_setglobal(L, "MANAGES_DESCENDANTS"); + lua_pushinteger(L, ATSPI_STATE_INDETERMINATE); + lua_setglobal(L, "INDETERMINATE"); + lua_pushinteger(L, ATSPI_STATE_REQUIRED); + lua_setglobal(L, "REQUIRED"); + lua_pushinteger(L, ATSPI_STATE_TRUNCATED); + lua_setglobal(L, "TRUNCATED"); + lua_pushinteger(L, ATSPI_STATE_ANIMATED); + lua_setglobal(L, "ANIMATED"); + lua_pushinteger(L, ATSPI_STATE_INVALID_ENTRY); + lua_setglobal(L, "INVALID_ENTRY"); + lua_pushinteger(L, ATSPI_STATE_SUPPORTS_AUTOCOMPLETION); + lua_setglobal(L, "SUPPORTS_AUTOCOMPLETION"); + lua_pushinteger(L, ATSPI_STATE_SELECTABLE_TEXT); + lua_setglobal(L, "SELECTABLE_TEXT"); + lua_pushinteger(L, ATSPI_STATE_IS_DEFAULT); + lua_setglobal(L, "IS_DEFAULT"); + lua_pushinteger(L, ATSPI_STATE_VISITED); + lua_setglobal(L, "VISITED"); + lua_pushinteger(L, ATSPI_STATE_HIGHLIGHTED); + lua_setglobal(L, "HIGHLIGHTED"); + lua_pushinteger(L, ATSPI_STATE_LAST_DEFINED); + lua_setglobal(L, "LAST_DEFINED"); +} + +static void _register_class(lua_State *L, const char *class_name, const luaL_Reg *funcs) +{ + lua_newtable(L); + int methodtable = lua_gettop(L); + luaL_newmetatable(L, class_name); + int metatable = lua_gettop(L); + + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + lua_pushliteral(L, "__index"); + lua_pushvalue(L, methodtable); + lua_settable(L, metatable); + + luaI_openlib(L, 0, _meta_methods, 0); + + lua_pop(L, 1); + + luaI_openlib(L, 0, funcs, 0); + lua_pop(L, 1); +} + +static int _extensions_register(lua_State *L) +{ + _register_class(L, ACCESSIBLE_CLASS_NAME, _accessible_methods); + _register_class(L, VALUE_CLASS_NAME, _value_methods); + _register_class(L, SELECTION_CLASS_NAME, _selection_methods); + + _register_role_enums(L); + + lua_register(L, "desktop", l_get_root); + lua_register(L, "T", l_get_translation); + + return 0; +} + +int lua_engine_init(const char *script) +{ + L = luaL_newstate(); + + luaL_openlibs(L); + + DEBUG("Initializing lua engine with script file: %s", script); + + if (_extensions_register(L)) + { + ERROR("Failed to load screen-reader lua extensions"); + lua_close(L); + return -1; + } + if (luaL_loadfile(L, script)) + { + ERROR("Script loading failed: %s\n", lua_tostring(L, -1)); + lua_close(L); + return -1; + } + if (lua_pcall(L, 0, 0, 0)) + { + ERROR("Failed to init lua script: %s", lua_tostring(L, -1)); + lua_close(L); + return -1; + } + DEBUG("Lua engine successfully inited."); + return 0; +} + +void lua_engine_shutdown(void) +{ + lua_close(L); +} + +char *lua_engine_describe_object(AtspiAccessible *obj) +{ + const char *ret = NULL; + + // get 'describeObject' function and push arguments on stack + lua_getglobal(L, "describeObject"); + + _push_class_obj(L, obj, ACCESSIBLE_CLASS_NAME); + + // launch function + if (lua_pcall(L, 1, 1, 0)) + { + ERROR("Failed to run function 'describeObject': %s", lua_tostring(L, -1)); + goto end; + } + // get result from lua stack + if (!lua_isstring(L, -1)) + { + ERROR("Function 'describeObject' do not returned string value."); + goto end; + } + ret = lua_tostring(L, -1); + +end: + // unref all AtspiAccessible references + lua_gc(L, LUA_GCCOLLECT, 1); + lua_pop(L, 1); + return ret ? strdup(ret) : NULL; +} diff --git a/src/navigator.c b/src/navigator.c index 1dcc68a..52d8891 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -38,6 +38,7 @@ #include "screen_reader_gestures.h" #include "dbus_gesture_adapter.h" #include "elm_access_adapter.h" +#include "lua_engine.h" #define QUICKPANEL_DOWN TRUE #define QUICKPANEL_UP FALSE @@ -88,6 +89,16 @@ static struct { } s_auto_review = { .focused_object = NULL,.auto_review_on = false}; +static bool _widget_has_state(AtspiAccessible * obj, AtspiStateType type) +{ + Eina_Bool ret = EINA_FALSE; + AtspiStateSet *st = atspi_accessible_get_state_set(obj); + if (atspi_state_set_contains(st, type)) + ret = EINA_TRUE; + g_object_unref(st); + return ret; +} + char *state_to_char(AtspiStateType state) { switch (state) { @@ -261,553 +272,9 @@ static void display_info_about_object(AtspiAccessible * obj, bool display_parent g_free(description); } -char *generate_description_for_subtrees(AtspiAccessible * obj) -{ - DEBUG("START"); - - if (!obj) - return strdup(""); - return strdup(""); - /* - AtspiRole role; - int child_count; - int i; - char *name = NULL; - char *below = NULL; - char ret[TTS_MAX_TEXT_SIZE] = "\0"; - AtspiAccessible *child = NULL; - - int child_count = atspi_accessible_get_child_count(obj, NULL); - - role = atspi_accessible_get_role(obj, NULL); - - // Do not generate that for popups - if (role == ATSPI_ROLE_POPUP_MENU || role == ATSPI_ROLE_DIALOG) - return strdup(""); - - child_count = atspi_accessible_get_child_count(obj, NULL); - - DEBUG("There is %d children inside this object", child_count); - if (!child_count) - return strdup(""); - - for (i=0; i < child_count; i++) - { - child = atspi_accessible_get_child_at_index(obj, i, NULL); - name = atspi_accessible_get_name(child, NULL); - DEBUG("%d child name:%s", i, name); - if (name && strncmp(name, "\0", 1)) - { - strncat(ret, name, sizeof(ret) - strlen(ret) - 1); - } - strncat(ret, " ", sizeof(ret) - strlen(ret) - 1); - below = generate_description_for_subtrees(child); - DEBUG("%s from below", below); - if (strncmp(below, "\0", 1)) - { - strncat(ret, below, sizeof(ret) - strlen(ret) - 1); - } - - g_object_unref(child); - free(below); - free(name); - } - return strdup(ret); - */ -} - -static int _check_list_children_count(AtspiAccessible * obj) -{ - int list_count = 0; - int i; - AtspiAccessible *child = NULL; - - if (!obj) - return 0; - - if (atspi_accessible_get_role(obj, NULL) == ATSPI_ROLE_LIST) { - int children_count = atspi_accessible_get_child_count(obj, NULL); - - for (i = 0; i < children_count; i++) { - child = atspi_accessible_get_child_at_index(obj, i, NULL); - if (atspi_accessible_get_role(child, NULL) == ATSPI_ROLE_LIST_ITEM) - list_count++; - g_object_unref(child); - } - } - - return list_count; -} - -static int _find_popup_list_children_count(AtspiAccessible * obj) -{ - int list_items_count = 0; - int children_count = atspi_accessible_get_child_count(obj, NULL); - int i; - AtspiAccessible *child = NULL; - - list_items_count = _check_list_children_count(obj); - if (list_items_count > 0) - return list_items_count; - - for (i = 0; i < children_count; i++) { - child = atspi_accessible_get_child_at_index(obj, i, NULL); - list_items_count = _find_popup_list_children_count(child); - if (list_items_count > 0) - return list_items_count; - g_object_unref(child); - } - - return 0; -} - -static bool _widget_has_state(AtspiAccessible * obj, AtspiStateType type) -{ - Eina_Bool ret = EINA_FALSE; - AtspiStateSet *st = atspi_accessible_get_state_set(obj); - if (atspi_state_set_contains(st, type)) - ret = EINA_TRUE; - g_object_unref(st); - return ret; -} - -int get_accuracy(double val, int max_accuracy) -{ - char val_str[HOVERSEL_TRAIT_SIZE] = ""; - int position; - int accuracy; - - snprintf(val_str, HOVERSEL_TRAIT_SIZE, "%.*f", max_accuracy, val); - accuracy = max_accuracy; - position = strlen(val_str) - 1; - while ( position > 0 && val_str[position] == '0' ) { - --position; - --accuracy; - } - return accuracy; -} - -void add_slider_description(char *dest, uint dest_size, AtspiAccessible *obj) -{ - gchar *role_name; - AtspiValue *value_iface; - double val; - double min_val; - double max_val; - char trait[HOVERSEL_TRAIT_SIZE] = ""; - int accuracy; - - role_name = atspi_accessible_get_localized_role_name(obj, NULL); - if (role_name) { - strncat(dest, role_name, dest_size - strlen(dest) - 1); - g_free(role_name); - } - - value_iface = atspi_accessible_get_value_iface(obj); - if (!value_iface) { - return; - } - - accuracy = get_accuracy( atspi_value_get_minimum_increment(value_iface, NULL), 3 ); - val = atspi_value_get_current_value(value_iface, NULL); - max_val = atspi_value_get_maximum_value(value_iface, NULL); - min_val = atspi_value_get_minimum_value(value_iface, NULL); - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_SLIDER_VALUE"), accuracy, min_val, accuracy, max_val, accuracy, val); - strncat(dest, trait, dest_size - strlen(dest) - 1); - - if (_widget_has_state(obj, ATSPI_STATE_ENABLED)) { - strncat(dest, _("IDS_TRAIT_SLIDER_SWIPE_COMMUNICATE"), dest_size - strlen(dest) - 1); - } - g_object_unref(value_iface); -} - -char *generate_trait(AtspiAccessible * obj) -{ - if (!obj) - return strdup(""); - - AtspiRole role = atspi_accessible_get_role(obj, NULL); - AtspiStateSet *state_set = atspi_accessible_get_state_set(obj); - char ret[TTS_MAX_TEXT_SIZE] = "\0"; - switch (role) { - case ATSPI_ROLE_ENTRY: { - gchar *role_name = atspi_accessible_get_localized_role_name(obj, NULL); - if (role_name) { - strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1); - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - if (atspi_state_set_contains(state_set, ATSPI_STATE_FOCUSED)) - strncat(ret, _("IDS_TRAIT_TEXT_EDIT_FOCUSED"), sizeof(ret) - strlen(ret) - 1); - else - strncat(ret, _("IDS_TRAIT_TEXT_EDIT"), sizeof(ret) - strlen(ret) - 1); - g_free(role_name); - } - break; - } - case ATSPI_ROLE_MENU_ITEM: { - AtspiAccessible *parent = atspi_accessible_get_parent(obj, NULL); - int children_count = atspi_accessible_get_child_count(parent, NULL); - int index = atspi_accessible_get_index_in_parent(obj, NULL); - char tab_index[MENU_ITEM_TAB_INDEX_SIZE]; - snprintf(tab_index, MENU_ITEM_TAB_INDEX_SIZE, _("IDS_TRAIT_MENU_ITEM_TAB_INDEX"), index + 1, children_count); - strncat(ret, tab_index, sizeof(ret) - strlen(ret) - 1); - g_object_unref(parent); - break; - } - case ATSPI_ROLE_POPUP_MENU: { - int children_count = atspi_accessible_get_child_count(obj, NULL); - char trait[HOVERSEL_TRAIT_SIZE]; - - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_CTX_POPUP")); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_SHOWING")); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - strncat(ret, " ", sizeof(ret) - strlen(ret) - 1); - - snprintf(trait, HOVERSEL_TRAIT_SIZE, "%d", children_count); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - strncat(ret, " ", sizeof(ret) - strlen(ret) - 1); - - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_ITEMS")); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_POPUP_CLOSE")); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - break; - } - case ATSPI_ROLE_DIALOG: { - int children_count = _find_popup_list_children_count(obj); - char trait[HOVERSEL_TRAIT_SIZE]; - - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_POPUP")); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - - if (children_count > 0) { - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_SHOWING")); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - strncat(ret, " ", sizeof(ret) - strlen(ret) - 1); - - snprintf(trait, HOVERSEL_TRAIT_SIZE, "%d", children_count); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - strncat(ret, " ", sizeof(ret) - strlen(ret) - 1); - - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_ITEMS")); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - } - - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_POPUP_CLOSE")); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - break; - } - case ATSPI_ROLE_GLASS_PANE: { - AtspiAccessible *parent = atspi_accessible_get_parent(obj, NULL); - int children_count = atspi_accessible_get_child_count(parent, NULL); - char trait[HOVERSEL_TRAIT_SIZE]; - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_PD_HOVERSEL"), children_count); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - g_object_unref(parent); - break; - } - case ATSPI_ROLE_LIST_ITEM: { - AtspiAccessible *parent = atspi_accessible_get_parent(obj, NULL); - AtspiRole parent_role = atspi_accessible_get_role(parent, NULL); - - if(parent_role == ATSPI_ROLE_TREE_TABLE) { - - AtspiStateSet *state_set = atspi_accessible_get_state_set(obj); - gboolean is_selected = atspi_state_set_contains(state_set, ATSPI_STATE_SELECTED); - g_object_unref(state_set); - - if(is_selected) { - strncat(ret, _("IDS_TRAIT_ITEM_SELECTED"), sizeof(ret) - strlen(ret) - 1); - } - - AtspiStateSet *parent_state_set = atspi_accessible_get_state_set(parent); - bool is_parent_multiselectable = atspi_state_set_contains(parent_state_set, ATSPI_STATE_MULTISELECTABLE); - - g_object_unref(parent_state_set); - g_object_unref(parent); - - if(is_parent_multiselectable) { - - char buf[200]; - - AtspiSelection *parent_selection = atspi_accessible_get_selection(parent); - int selected_children_count = atspi_selection_get_n_selected_children(parent_selection, NULL); - - if(is_selected) { - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - } - - snprintf(buf, 200, _("IDS_TRAIT_ITEM_SELECTED_COUNT"), selected_children_count); - strncat(ret, buf, sizeof(ret) - strlen(ret) - 1); - - g_object_unref(parent_selection); - } - - } else if (atspi_state_set_contains(state_set, ATSPI_STATE_EXPANDABLE)) { - if (atspi_state_set_contains(state_set, ATSPI_STATE_EXPANDED)) { - strncat(ret, _("IDS_TRAIT_GROUP_INDEX_EXPANDED"), sizeof(ret) - strlen(ret) - 1); - } else { - strncat(ret, _("IDS_TRAIT_GROUP_INDEX_COLLAPSED"), sizeof(ret) - strlen(ret) - 1); - } - } - g_object_unref(parent); - break; - } - case ATSPI_ROLE_CHECK_BOX: - case ATSPI_ROLE_RADIO_BUTTON: { - if (atspi_state_set_contains(state_set, ATSPI_STATE_CHECKED)) { - strncat(ret, _("IDS_TRAIT_CHECK_BOX_SELECTED"), sizeof(ret) - strlen(ret) - 1); - } else { - strncat(ret, _("IDS_TRAIT_CHECK_BOX_NOT_SELECTED"), sizeof(ret) - strlen(ret) - 1); - } - - if (role == ATSPI_ROLE_RADIO_BUTTON) { - /* Say role name ("radio button"), but only if it's not a color chooser */ - AtspiAccessible *parent; - AtspiRole parent_role; - parent = atspi_accessible_get_parent(obj, NULL); - parent_role = atspi_accessible_get_role(parent, NULL); - if (parent_role != ATSPI_ROLE_COLOR_CHOOSER) { - gchar *role_name; - role_name = atspi_accessible_get_localized_role_name(obj, NULL); - if (role_name) { - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1); - g_free(role_name); - } - } - g_object_unref(parent); - } - break; - } - case ATSPI_ROLE_PUSH_BUTTON: { - strncat(ret, _("IDS_TRAIT_PUSH_BUTTON"), sizeof(ret) - strlen(ret) - 1); - break; - } - case ATSPI_ROLE_PROGRESS_BAR: { - AtspiValue *value = atspi_accessible_get_value_iface(obj); - if (value) { - double val = atspi_value_get_current_value(value, NULL); - char trait[HOVERSEL_TRAIT_SIZE]; - if (val > 0) { - snprintf(trait, HOVERSEL_TRAIT_SIZE, _("IDS_TRAIT_PD_PROGRESSBAR_PERCENT"), val * 100); - strncat(ret, trait, sizeof(ret) - strlen(ret) - 1); - } else { - strncat(ret, _("IDS_TRAIT_PD_PROGRESSBAR"), sizeof(ret) - strlen(ret) - 1); - } - g_object_unref(value); - } - break; - } - case ATSPI_ROLE_TOGGLE_BUTTON: { - strncat(ret, _("IDS_TRAIT_TOGGLE_BUTTON"), sizeof(ret) - strlen(ret) - 1); - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - if (atspi_state_set_contains(state_set, ATSPI_STATE_CHECKED)) { - strncat(ret, _("IDS_TRAIT_TOGGLE_BUTTON_ON"), sizeof(ret) - strlen(ret) - 1); - } else { - strncat(ret, _("IDS_TRAIT_TOGGLE_BUTTON_OFF"), sizeof(ret) - strlen(ret) - 1); - } - break; - } - case ATSPI_ROLE_SLIDER: { - add_slider_description(ret, sizeof(ret), obj); - break; - } - case ATSPI_ROLE_HEADING: - case ATSPI_ROLE_GROUPING: { - break; - } - default: { - gchar *role_name = atspi_accessible_get_localized_role_name(obj, NULL); - if (role_name) { - strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1); - g_free(role_name); - } - } - } - - if (state_set) - g_object_unref(state_set); - - return strdup(ret); -} - -char *generate_text_for_relation_objects(AtspiAccessible * obj, AtspiRelationType search, char *(*text_generate_cb)(AtspiAccessible *obj)) -{ - GError *err = NULL; - GArray *relations; - AtspiRelation *relation; - AtspiRelationType type; - Eina_Strbuf *buf; - int i, j; - char *ret = NULL; - - if (!obj || !text_generate_cb) return NULL; - - relations = atspi_accessible_get_relation_set(obj, &err); - if (err || !relations) - { - if (err) g_error_free(err); - return NULL; - } - - buf = eina_strbuf_new(); - - for (i = 0; i < relations->len; i++) - { - relation = g_array_index(relations, AtspiRelation *, i); - type = atspi_relation_get_relation_type(relation); - if (type == search) - { - for (j = 0; j < atspi_relation_get_n_targets(relation); j++) - { - AtspiAccessible *target = atspi_relation_get_target(relation, j); - char *text = text_generate_cb(target); - if (j == 0) - eina_strbuf_append_printf(buf, "%s", text); - else - eina_strbuf_append_printf(buf, ", %s", text); - g_object_unref(target); - free(text); - } - } - g_object_unref(relation); - } - g_array_free(relations, TRUE); - ret = eina_strbuf_string_steal(buf); - eina_strbuf_free(buf); - - return ret; -} - -static char *generate_description_from_relation_object(AtspiAccessible *obj) -{ - GError *err = NULL; - char *ret = generate_trait(obj); - char *desc = atspi_accessible_get_description(obj, &err); - - if (err) - { - g_error_free(err); - g_free(desc); - return ret; - } - - if (desc) { - if (desc[0] != '\0') { - char *tmp = ret; - if (asprintf(&ret, "%s, %s", desc, ret) < 0) - ERROR("asprintf failed."); - free(tmp); - } - g_free(desc); - } - - - return ret; -} - -static char *generate_name_from_relation_object(AtspiAccessible *obj) -{ - GError *err = NULL; - char *name = atspi_accessible_get_name(obj, &err); - - if(err) - { - g_error_free(err); - g_free(name); - return NULL; - } - - return name; -} - static char *generate_what_to_read(AtspiAccessible * obj) { - char *name; - char *names = NULL; - char *description; - char *role_name; - char *other; - char *text = NULL; - char ret[TTS_MAX_TEXT_SIZE] = "\0"; - char *description_from_relation; - char *name_from_relation; - - description = atspi_accessible_get_description(obj, NULL); - name = atspi_accessible_get_name(obj, NULL); - role_name = generate_trait(obj); - other = generate_description_for_subtrees(obj); - description_from_relation = generate_text_for_relation_objects(obj, ATSPI_RELATION_DESCRIBED_BY, generate_description_from_relation_object); - name_from_relation = generate_text_for_relation_objects(obj, ATSPI_RELATION_LABELLED_BY, generate_name_from_relation_object); - AtspiText *iface_text = atspi_accessible_get_text_iface(obj); - if (iface_text) { - text = atspi_text_get_text(iface_text, 0, atspi_text_get_character_count(iface_text, NULL), NULL); - g_object_unref(iface_text); - } - - DEBUG("->->->->->-> WIDGET GAINED HIGHLIGHT: %s <-<-<-<-<-<-<-", name); - DEBUG("->->->->->-> FROM SUBTREE HAS NAME: %s <-<-<-<-<-<-<-", other); - - display_info_about_object(obj, false); - - if (name && strncmp(name, "\0", 1)) - names = strdup(name); - else if (other && strncmp(other, "\0", 1)) - names = strdup(other); - - if (text) { - strncat(ret, text, sizeof(ret) - strlen(ret) - 1); - } - - DEBUG("Text:%s", text); - - if (names && strlen(names) > 0) { - if (strlen(ret) > 0) - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - strncat(ret, names, sizeof(ret) - strlen(ret) - 1); - } - - if (name_from_relation && strlen(name_from_relation) > 0) { - if(strlen(ret) > 0) - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - strncat(ret, name_from_relation, sizeof(ret) - strlen(ret) - 1); - } - - if (role_name && strlen(role_name) > 0) { - if (strlen(ret) > 0) - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1); - } - - if (description && strlen(description) > 0) { - if (strlen(ret) > 0) - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - strncat(ret, description, sizeof(ret) - strlen(ret) - 1); - } - - if (description_from_relation && (description_from_relation[0] != '\n')) { - if (strlen(ret) > 0) - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - strncat(ret, description_from_relation, sizeof(ret) - strlen(ret) - 1); - } - - free(text); - free(name); - free(names); - free(name_from_relation); - free(description); - free(role_name); - free(other); - free(description_from_relation); - - return strdup(ret); + return lua_engine_describe_object(obj); } static void _current_highlight_object_set(AtspiAccessible * obj) @@ -2260,7 +1727,9 @@ void navigator_init(void) set_utterance_cb(_on_utterance); screen_reader_gestures_tracker_register(on_gesture_detected, NULL); - // register on active_window + //FIXME add some config to get script path + if (lua_engine_init(SCRIPTDIR "/mobile.lua")) + ERROR("Failed to init lua engine."); dbus_gesture_adapter_init(); app_tracker_init(); app_tracker_new_obj_highlighted_callback_register(_new_highlighted_obj_changed); @@ -2289,6 +1758,7 @@ void navigator_shutdown(void) flat_navi_context_free(context); context = NULL; } + lua_engine_shutdown(); dbus_gesture_adapter_shutdown(); app_tracker_shutdown(); window_tracker_shutdown(); diff --git a/src/screen_reader.c b/src/screen_reader.c index e465e1b..e6a6ff0 100644 --- a/src/screen_reader.c +++ b/src/screen_reader.c @@ -42,6 +42,7 @@ Service_Data service_data = { //Actions to do when tts state is 'ready' .update_language_list = false, + .lua_script_path = SCRIPTDIR "/mobile.lua", .text_to_say_info = NULL }; @@ -77,6 +78,10 @@ int screen_reader_terminate_service(void *data) Service_Data *service_data = data; +#ifdef SCREEN_READER_TV + spi_shutdown(service_data); +#endif + tts_stop(service_data->tts); tts_unprepare(service_data->tts); tts_destroy(service_data->tts); diff --git a/src/screen_reader_spi.c b/src/screen_reader_spi.c index 10645de..197e27e 100644 --- a/src/screen_reader_spi.c +++ b/src/screen_reader_spi.c @@ -20,6 +20,7 @@ #include "screen_reader_spi.h" #include "screen_reader_tts.h" #include "logger.h" +#include "lua_engine.h" #ifdef RUN_IPC_TEST_SUIT #include "test_suite/test_suite.h" #endif @@ -29,11 +30,6 @@ /** @brief Service_Data used as screen reader internal data struct*/ static Service_Data *service_data; -typedef struct { - char *key; - char *val; -} Attr; - /** * @brief Debug function. Print current toolkit version/event * type/event source/event detail1/event detail2 @@ -54,105 +50,12 @@ static void display_info(const AtspiEvent * event) DEBUG("--------------------------------------------------------"); } -Eina_Bool double_click_timer_cb(void *data) -{ - Service_Data *sd = data; - sd->clicked_widget = NULL; - - return EINA_FALSE; -} - -bool allow_recursive_name(AtspiAccessible * obj) -{ - AtspiRole r = atspi_accessible_get_role(obj, NULL); - if (r == ATSPI_ROLE_FILLER) - return true; - return false; -} - -char *generate_description_for_subtree(AtspiAccessible * obj) -{ - DEBUG("START"); - if (!allow_recursive_name(obj)) - return strdup(""); - - if (!obj) - return strdup(""); - int child_count = atspi_accessible_get_child_count(obj, NULL); - - DEBUG("There is %d children inside this filler", child_count); - if (!child_count) - return strdup(""); - - int i; - char *name = NULL; - char *below = NULL; - char ret[256] = "\0"; - AtspiAccessible *child = NULL; - for (i = 0; i < child_count; i++) { - child = atspi_accessible_get_child_at_index(obj, i, NULL); - name = atspi_accessible_get_name(child, NULL); - DEBUG("%d child name:%s", i, name); - if (name && strncmp(name, "\0", 1)) { - strncat(ret, name, sizeof(ret) - strlen(ret) - 1); - } - strncat(ret, " ", sizeof(ret) - strlen(ret) - 1); - below = generate_description_for_subtree(child); - if (strncmp(below, "\0", 1)) { - strncat(ret, below, sizeof(ret) - strlen(ret) - 1); - } - g_object_unref(child); - free(below); - free(name); - } - return strdup(ret); -} - static char *spi_on_state_changed_get_text(AtspiEvent * event, void *user_data) { Service_Data *sd = (Service_Data *) user_data; - char *name; - char *names = NULL; - char *description; - char *role_name; - char *other; - char ret[256] = "\0"; sd->currently_focused = event->source; - description = atspi_accessible_get_description(sd->currently_focused, NULL); - name = atspi_accessible_get_name(sd->currently_focused, NULL); - role_name = atspi_accessible_get_localized_role_name(sd->currently_focused, NULL); - other = generate_description_for_subtree(sd->currently_focused); - - DEBUG("->->->->->-> WIDGET GAINED HIGHLIGHT: %s <-<-<-<-<-<-<-", name); - DEBUG("->->->->->-> FROM SUBTREE HAS NAME: %s <-<-<-<-<-<-<-", other); - - if (name && strncmp(name, "\0", 1)) - names = strdup(name); - else if (other && strncmp(other, "\0", 1)) - names = strdup(other); - - if (names) { - strncat(ret, names, sizeof(ret) - strlen(ret) - 1); - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - } - - if (role_name) - strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1); - - if (description) { - if (strncmp(description, "\0", 1)) - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - strncat(ret, description, sizeof(ret) - strlen(ret) - 1); - } - - free(name); - free(names); - free(description); - free(role_name); - free(other); - - return strdup(ret); + return lua_engine_describe_object(sd->currently_focused); } static char *spi_on_caret_move_get_text(AtspiEvent * event, void *user_data) @@ -292,6 +195,10 @@ void spi_init(Service_Data * sd) DEBUG("--------------------- SPI_init START ---------------------"); service_data = sd; + DEBUG(">>> Init lua engine<<<"); + if (lua_engine_init(sd->lua_script_path)) + ERROR("Failed to init lua engine."); + DEBUG(">>> Creating listeners <<<"); sd->spi_listener = atspi_event_listener_new(spi_event_listener_cb, service_data, NULL); @@ -327,3 +234,8 @@ void spi_init(Service_Data * sd) DEBUG("---------------------- SPI_init END ----------------------\n\n"); } + +void spi_shutdown(Service_Data * sd) +{ + lua_engine_shutdown(); +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 75034d8..dc59d11 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,6 +21,7 @@ pkg_check_modules(tests REQUIRED check vconf elementary + lua ) FOREACH(flag ${tests_CFLAGS}) @@ -35,6 +36,7 @@ SET(TESTED_SRCS ${CMAKE_SOURCE_DIR}/src/screen_reader.c ${CMAKE_SOURCE_DIR}/src/screen_reader_vconf.c ${CMAKE_SOURCE_DIR}/src/screen_reader_spi.c ${CMAKE_SOURCE_DIR}/src/screen_reader_tts.c + ${CMAKE_SOURCE_DIR}/src/lua_engine.c ${CMAKE_SOURCE_DIR}/src/flat_navi.c) ADD_DEFINITIONS(-DSCREEN_READER_FLAT_NAVI_TEST_DUMMY_IMPLEMENTATION) diff --git a/tests/atspi/atspi.c b/tests/atspi/atspi.c index 096a51f..2623840 100644 --- a/tests/atspi/atspi.c +++ b/tests/atspi/atspi.c @@ -517,3 +517,29 @@ int atspi_exit(void) { return 1; } + +AtspiAccessible* atspi_get_desktop (gint i) +{ + return NULL; +} + +gdouble atspi_value_get_minimum_increment (AtspiValue *obj, GError **error) +{ + return 0.0; +} + +gint +atspi_selection_get_n_selected_children (AtspiSelection *obj, GError **error) +{ + return 0; +} + +gboolean atspi_selection_is_child_selected (AtspiSelection *obj, gint child_index, GError **error) +{ + return FALSE; +} + +AtspiSelection * atspi_accessible_get_selection_iface (AtspiAccessible *obj) +{ + return NULL; +} diff --git a/tests/atspi/atspi.h b/tests/atspi/atspi.h index e03f548..bfe1f62 100644 --- a/tests/atspi/atspi.h +++ b/tests/atspi/atspi.h @@ -51,6 +51,7 @@ typedef struct _AtspiRect AtspiRect; typedef struct _AtspiEditableText AtspiEditableText; typedef struct _AtspiRelation AtspiRelation; typedef struct _AtspiAction AtspiAction; +typedef struct _AtspiSelection AtspiSelection; typedef struct _AtspiAccessibleClass AtspiAccessibleClass; typedef struct _AtspiActionClass AtspiActionClass; @@ -80,111 +81,128 @@ typedef enum typedef enum { - ATSPI_ROLE_INVALID, - ATSPI_ROLE_ACCELERATOR_LABEL, - ATSPI_ROLE_ALERT, - ATSPI_ROLE_ANIMATION, - ATSPI_ROLE_ARROW, - ATSPI_ROLE_CALENDAR, - ATSPI_ROLE_CANVAS, - ATSPI_ROLE_CHECK_BOX, - ATSPI_ROLE_CHECK_MENU_ITEM, - ATSPI_ROLE_COLOR_CHOOSER, - ATSPI_ROLE_COLUMN_HEADER, - ATSPI_ROLE_COMBO_BOX, - ATSPI_ROLE_DATE_EDITOR, - ATSPI_ROLE_DESKTOP_ICON, - ATSPI_ROLE_DESKTOP_FRAME, - ATSPI_ROLE_DIAL, - ATSPI_ROLE_DIALOG, - ATSPI_ROLE_DIRECTORY_PANE, - ATSPI_ROLE_DRAWING_AREA, - ATSPI_ROLE_FILE_CHOOSER, - ATSPI_ROLE_FILLER, - ATSPI_ROLE_FOCUS_TRAVERSABLE, - ATSPI_ROLE_FONT_CHOOSER, - ATSPI_ROLE_FRAME, - ATSPI_ROLE_GLASS_PANE, - ATSPI_ROLE_HTML_CONTAINER, - ATSPI_ROLE_ICON, - ATSPI_ROLE_IMAGE, - ATSPI_ROLE_INTERNAL_FRAME, - ATSPI_ROLE_LABEL, - ATSPI_ROLE_LAYERED_PANE, - ATSPI_ROLE_LIST, - ATSPI_ROLE_LIST_ITEM, - ATSPI_ROLE_MENU, - ATSPI_ROLE_MENU_BAR, - ATSPI_ROLE_MENU_ITEM, - ATSPI_ROLE_OPTION_PANE, - ATSPI_ROLE_PAGE_TAB, - ATSPI_ROLE_PAGE_TAB_LIST, - ATSPI_ROLE_PANEL, - ATSPI_ROLE_PASSWORD_TEXT, - ATSPI_ROLE_POPUP_MENU, - ATSPI_ROLE_PROGRESS_BAR, - ATSPI_ROLE_PUSH_BUTTON, - ATSPI_ROLE_RADIO_BUTTON, - ATSPI_ROLE_RADIO_MENU_ITEM, - ATSPI_ROLE_ROOT_PANE, - ATSPI_ROLE_ROW_HEADER, - ATSPI_ROLE_SCROLL_BAR, - ATSPI_ROLE_SCROLL_PANE, - ATSPI_ROLE_SEPARATOR, - ATSPI_ROLE_SLIDER, - ATSPI_ROLE_SPIN_BUTTON, - ATSPI_ROLE_SPLIT_PANE, - ATSPI_ROLE_STATUS_BAR, - ATSPI_ROLE_TABLE, - ATSPI_ROLE_TABLE_CELL, - ATSPI_ROLE_TABLE_COLUMN_HEADER, - ATSPI_ROLE_TABLE_ROW_HEADER, - ATSPI_ROLE_TEAROFF_MENU_ITEM, - ATSPI_ROLE_TERMINAL, - ATSPI_ROLE_TEXT, - ATSPI_ROLE_TOGGLE_BUTTON, - ATSPI_ROLE_TOOL_BAR, - ATSPI_ROLE_TOOL_TIP, - ATSPI_ROLE_TREE, - ATSPI_ROLE_TREE_TABLE, - ATSPI_ROLE_UNKNOWN, - ATSPI_ROLE_VIEWPORT, - ATSPI_ROLE_WINDOW, - ATSPI_ROLE_EXTENDED, - ATSPI_ROLE_HEADER, - ATSPI_ROLE_FOOTER, - ATSPI_ROLE_PARAGRAPH, - ATSPI_ROLE_RULER, - ATSPI_ROLE_APPLICATION, - ATSPI_ROLE_AUTOCOMPLETE, - ATSPI_ROLE_EDITBAR, - ATSPI_ROLE_EMBEDDED, - ATSPI_ROLE_ENTRY, - ATSPI_ROLE_CHART, - ATSPI_ROLE_CAPTION, - ATSPI_ROLE_DOCUMENT_FRAME, - ATSPI_ROLE_HEADING, - ATSPI_ROLE_PAGE, - ATSPI_ROLE_SECTION, - ATSPI_ROLE_REDUNDANT_OBJECT, - ATSPI_ROLE_FORM, - ATSPI_ROLE_LINK, - ATSPI_ROLE_INPUT_METHOD_WINDOW, - ATSPI_ROLE_TABLE_ROW, - ATSPI_ROLE_TREE_ITEM, - ATSPI_ROLE_DOCUMENT_SPREADSHEET, - ATSPI_ROLE_DOCUMENT_PRESENTATION, - ATSPI_ROLE_DOCUMENT_TEXT, - ATSPI_ROLE_DOCUMENT_WEB, - ATSPI_ROLE_DOCUMENT_EMAIL, - ATSPI_ROLE_COMMENT, - ATSPI_ROLE_LIST_BOX, - ATSPI_ROLE_GROUPING, - ATSPI_ROLE_IMAGE_MAP, - ATSPI_ROLE_NOTIFICATION, - ATSPI_ROLE_INFO_BAR, - ATSPI_ROLE_LEVEL_BAR, - ATSPI_ROLE_LAST_DEFINED, + ATSPI_ROLE_INVALID, + ATSPI_ROLE_ACCELERATOR_LABEL, + ATSPI_ROLE_ALERT, + ATSPI_ROLE_ANIMATION, + ATSPI_ROLE_ARROW, + ATSPI_ROLE_CALENDAR, + ATSPI_ROLE_CANVAS, + ATSPI_ROLE_CHECK_BOX, + ATSPI_ROLE_CHECK_MENU_ITEM, + ATSPI_ROLE_COLOR_CHOOSER, + ATSPI_ROLE_COLUMN_HEADER, + ATSPI_ROLE_COMBO_BOX, + ATSPI_ROLE_DATE_EDITOR, + ATSPI_ROLE_DESKTOP_ICON, + ATSPI_ROLE_DESKTOP_FRAME, + ATSPI_ROLE_DIAL, + ATSPI_ROLE_DIALOG, + ATSPI_ROLE_DIRECTORY_PANE, + ATSPI_ROLE_DRAWING_AREA, + ATSPI_ROLE_FILE_CHOOSER, + ATSPI_ROLE_FILLER, + ATSPI_ROLE_FOCUS_TRAVERSABLE, + ATSPI_ROLE_FONT_CHOOSER, + ATSPI_ROLE_FRAME, + ATSPI_ROLE_GLASS_PANE, + ATSPI_ROLE_HTML_CONTAINER, + ATSPI_ROLE_ICON, + ATSPI_ROLE_IMAGE, + ATSPI_ROLE_INTERNAL_FRAME, + ATSPI_ROLE_LABEL, + ATSPI_ROLE_LAYERED_PANE, + ATSPI_ROLE_LIST, + ATSPI_ROLE_LIST_ITEM, + ATSPI_ROLE_MENU, + ATSPI_ROLE_MENU_BAR, + ATSPI_ROLE_MENU_ITEM, + ATSPI_ROLE_OPTION_PANE, + ATSPI_ROLE_PAGE_TAB, + ATSPI_ROLE_PAGE_TAB_LIST, + ATSPI_ROLE_PANEL, + ATSPI_ROLE_PASSWORD_TEXT, + ATSPI_ROLE_POPUP_MENU, + ATSPI_ROLE_PROGRESS_BAR, + ATSPI_ROLE_PUSH_BUTTON, + ATSPI_ROLE_RADIO_BUTTON, + ATSPI_ROLE_RADIO_MENU_ITEM, + ATSPI_ROLE_ROOT_PANE, + ATSPI_ROLE_ROW_HEADER, + ATSPI_ROLE_SCROLL_BAR, + ATSPI_ROLE_SCROLL_PANE, + ATSPI_ROLE_SEPARATOR, + ATSPI_ROLE_SLIDER, + ATSPI_ROLE_SPIN_BUTTON, + ATSPI_ROLE_SPLIT_PANE, + ATSPI_ROLE_STATUS_BAR, + ATSPI_ROLE_TABLE, + ATSPI_ROLE_TABLE_CELL, + ATSPI_ROLE_TABLE_COLUMN_HEADER, + ATSPI_ROLE_TABLE_ROW_HEADER, + ATSPI_ROLE_TEAROFF_MENU_ITEM, + ATSPI_ROLE_TERMINAL, + ATSPI_ROLE_TEXT, + ATSPI_ROLE_TOGGLE_BUTTON, + ATSPI_ROLE_TOOL_BAR, + ATSPI_ROLE_TOOL_TIP, + ATSPI_ROLE_TREE, + ATSPI_ROLE_TREE_TABLE, + ATSPI_ROLE_UNKNOWN, + ATSPI_ROLE_VIEWPORT, + ATSPI_ROLE_WINDOW, + ATSPI_ROLE_EXTENDED, + ATSPI_ROLE_HEADER, + ATSPI_ROLE_FOOTER, + ATSPI_ROLE_PARAGRAPH, + ATSPI_ROLE_RULER, + ATSPI_ROLE_APPLICATION, + ATSPI_ROLE_AUTOCOMPLETE, + ATSPI_ROLE_EDITBAR, + ATSPI_ROLE_EMBEDDED, + ATSPI_ROLE_ENTRY, + ATSPI_ROLE_CHART, + ATSPI_ROLE_CAPTION, + ATSPI_ROLE_DOCUMENT_FRAME, + ATSPI_ROLE_HEADING, + ATSPI_ROLE_PAGE, + ATSPI_ROLE_SECTION, + ATSPI_ROLE_REDUNDANT_OBJECT, + ATSPI_ROLE_FORM, + ATSPI_ROLE_LINK, + ATSPI_ROLE_INPUT_METHOD_WINDOW, + ATSPI_ROLE_TABLE_ROW, + ATSPI_ROLE_TREE_ITEM, + ATSPI_ROLE_DOCUMENT_SPREADSHEET, + ATSPI_ROLE_DOCUMENT_PRESENTATION, + ATSPI_ROLE_DOCUMENT_TEXT, + ATSPI_ROLE_DOCUMENT_WEB, + ATSPI_ROLE_DOCUMENT_EMAIL, + ATSPI_ROLE_COMMENT, + ATSPI_ROLE_LIST_BOX, + ATSPI_ROLE_GROUPING, + ATSPI_ROLE_IMAGE_MAP, + ATSPI_ROLE_NOTIFICATION, + ATSPI_ROLE_INFO_BAR, + ATSPI_ROLE_LEVEL_BAR, + ATSPI_ROLE_TITLE_BAR, + ATSPI_ROLE_BLOCK_QUOTE, + ATSPI_ROLE_AUDIO, + ATSPI_ROLE_VIDEO, + ATSPI_ROLE_DEFINITION, + ATSPI_ROLE_ARTICLE, + ATSPI_ROLE_LANDMARK, + ATSPI_ROLE_LOG, + ATSPI_ROLE_MARQUEE, + ATSPI_ROLE_MATH, + ATSPI_ROLE_RATING, + ATSPI_ROLE_TIMER, + ATSPI_ROLE_STATIC, + ATSPI_ROLE_MATH_FRACTION, + ATSPI_ROLE_MATH_ROOT, + ATSPI_ROLE_SUBSCRIPT, + ATSPI_ROLE_SUPERSCRIPT, + ATSPI_ROLE_LAST_DEFINED, } AtspiRole; typedef enum @@ -375,6 +393,11 @@ struct _AtspiRelation GTypeInterface parent; }; +struct _AtspiSelection +{ + GTypeInterface parent; +}; + struct _AtspiRect { gint x; @@ -396,6 +419,7 @@ gchar * atspi_accessible_get_toolkit_name (AtspiAccessible *obj, GError **error) gchar * atspi_accessible_get_description (AtspiAccessible *obj, GError **error); AtspiText * atspi_accessible_get_text_iface (AtspiAccessible *obj); AtspiAction * atspi_accessible_get_action_iface (AtspiAccessible *obj); +AtspiSelection * atspi_accessible_get_selection_iface (AtspiAccessible *obj); gint atspi_text_get_character_count (AtspiText *obj, GError **error); gint atspi_text_get_caret_offset (AtspiText *obj, GError **error); gchar * atspi_text_get_text (AtspiText *obj, gint start_offset, gint end_offset, GError **error); @@ -447,5 +471,9 @@ gint atspi_action_get_n_actions (AtspiAction *obj, GError **error); gchar * atspi_action_get_action_name (AtspiAction *obj, gint i, GError **error); int atspi_exit(void); +AtspiAccessible* atspi_get_desktop (gint i); +gdouble atspi_value_get_minimum_increment (AtspiValue *obj, GError **error); +gint atspi_selection_get_n_selected_children (AtspiSelection *obj, GError **error); +gboolean atspi_selection_is_child_selected (AtspiSelection *obj, gint child_index, GError **error); #endif /*__ATSPI_H__*/ diff --git a/tests/smart_navi_suite.c b/tests/smart_navi_suite.c index b7b637a..98f362e 100644 --- a/tests/smart_navi_suite.c +++ b/tests/smart_navi_suite.c @@ -16,6 +16,7 @@ #include "screen_reader_spi.h" #include "flat_navi.h" +#include "lua_engine.h" #include #include #include @@ -65,14 +66,17 @@ void setup(void) data->update_language_list = false; data->text_to_say_info = NULL; + data->lua_script_path = "./res/scripts/mobile.lua"; + spi_init(data); } void teardown(void) { + Service_Data *data = get_pointer_to_service_data_struct(); + spi_shutdown(data); } -void setup_flat_navi() -{ +void setup_flat_navi() { setup(); root = atspi_create_accessible(); root->role = ATSPI_ROLE_APPLICATION; @@ -259,18 +263,7 @@ void teardown_flat_navi() teardown(); } -START_TEST(spi_init_null_parameter) -{ - spi_init(NULL); -} - -END_TEST START_TEST(spi_init_service_data_parameter) -{ - Service_Data *data = get_pointer_to_service_data_struct(); - spi_init(data); -} - -END_TEST START_TEST(spi_on_state_change_name) +START_TEST(spi_on_state_change_name) { Service_Data *sd = get_pointer_to_service_data_struct(); AtspiEvent event; @@ -514,7 +507,6 @@ END_TEST Suite * screen_reader_suite(void) { Suite *s; - TCase *tc_spi_screen_reader_init; TCase *tc_spi_screen_reader_on_state_changed; TCase *tc_spi_screen_reader_on_caret_move; TCase *tc_spi_screen_reader_on_access_value; @@ -522,25 +514,23 @@ Suite * screen_reader_suite(void) TCase *tc_spi_screen_reader_flat_navi2; s = suite_create("Screen reader"); - tc_spi_screen_reader_init = tcase_create("tc_spi_screen_reader_init"); tc_spi_screen_reader_on_state_changed = tcase_create("tc_spi_screen_reader_on_state_changed"); tc_spi_screen_reader_on_caret_move = tcase_create("tc_spi_screen_reader_on_caret_move"); tc_spi_screen_reader_on_access_value = tcase_create("tc_spi_screen_reader_on_access_value"); tc_spi_screen_reader_flat_navi = tcase_create("tc_scpi_screen_reader_flat_navi"); tc_spi_screen_reader_flat_navi2 = tcase_create("tc_scpi_screen_reader_flat_navi2"); - tcase_add_checked_fixture(tc_spi_screen_reader_init, setup, teardown); tcase_add_checked_fixture(tc_spi_screen_reader_on_state_changed, setup, teardown); tcase_add_checked_fixture(tc_spi_screen_reader_on_caret_move, setup, teardown); tcase_add_checked_fixture(tc_spi_screen_reader_on_access_value, setup, teardown); tcase_add_checked_fixture(tc_spi_screen_reader_flat_navi, setup_flat_navi2, teardown_flat_navi); tcase_add_checked_fixture(tc_spi_screen_reader_flat_navi2, setup_flat_navi3, teardown_flat_navi); - tcase_add_test(tc_spi_screen_reader_init, spi_init_null_parameter); - tcase_add_test(tc_spi_screen_reader_init, spi_init_service_data_parameter); +#if 1 tcase_add_test(tc_spi_screen_reader_on_state_changed, spi_on_state_change_name); tcase_add_test(tc_spi_screen_reader_on_state_changed, spi_on_state_change_description); tcase_add_test(tc_spi_screen_reader_on_state_changed, spi_on_state_change_role); +#endif tcase_add_test(tc_spi_screen_reader_on_caret_move, spi_on_caret_move); tcase_add_test(tc_spi_screen_reader_on_access_value, spi_on_value_changed); @@ -570,7 +560,6 @@ Suite * screen_reader_suite(void) tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_current_set_null_parameters); tcase_add_test(tc_spi_screen_reader_flat_navi, spi_flat_navi_context_current_set_valid_parameters); - suite_add_tcase(s, tc_spi_screen_reader_init); suite_add_tcase(s, tc_spi_screen_reader_on_state_changed); suite_add_tcase(s, tc_spi_screen_reader_on_caret_move); suite_add_tcase(s, tc_spi_screen_reader_on_access_value);