From 9ce455463a4a30cc42d648b84bf64c567508c909 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Mon, 5 Oct 2015 15:59:56 +0900 Subject: [PATCH 01/16] Fix prevent issue: CID 481761(FORWARD_NULL) Change-Id: I703f57d60841b43ea7205ffe13c328abc6cbf2f0 --- src/navigator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/navigator.c b/src/navigator.c index fee62b7..e2ed195 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -697,10 +697,11 @@ static char *generate_what_to_read(AtspiAccessible * obj) strncat(ret, names, sizeof(ret) - strlen(ret) - 1); } - if (name_from_relation && strlen(name_from_relation) > 0) + 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) -- 2.7.4 From 924d734b9f3352be910ac260e2844fb79551ba77 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Mon, 5 Oct 2015 17:00:22 +0900 Subject: [PATCH 02/16] Fix prevent issues: CID453825,453827,453828,479697,481760 Change-Id: I1379a3be531d98b3d71877884d01e21b4c0a3a26 --- src/flat_navi.c | 26 +++++++++++++++++--------- src/navigator.c | 47 ++++++++++++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/flat_navi.c b/src/flat_navi.c index 8811798..72aac40 100644 --- a/src/flat_navi.c +++ b/src/flat_navi.c @@ -233,17 +233,23 @@ static Eina_Bool _accept_object(AtspiAccessible * obj) name = atspi_accessible_get_name(obj, NULL); ret = EINA_FALSE; - if (strncmp(name, "\0", 1)) { - DEBUG("Has name:[%s]", name); - ret = EINA_TRUE; + if (name) { + if (strncmp(name, "\0", 1)) { + DEBUG("Has name:[%s]", name); + ret = EINA_TRUE; + } + g_free(name); } - g_free(name); - desc = atspi_accessible_get_description(obj, NULL); - if (!ret && strncmp(desc, "\0", 1)) { - DEBUG("Has description:[%s]", desc); - ret = EINA_TRUE; + if (!ret) { + desc = atspi_accessible_get_description(obj, NULL); + if (desc) { + if (strncmp(desc, "\0", 1)) { + DEBUG("Has description:[%s]", desc); + ret = EINA_TRUE; + } + g_free(desc); + } } - g_free(desc); if (!ret) { action = atspi_accessible_get_action_iface(obj); if (action) { @@ -386,6 +392,8 @@ AtspiAccessible *_get_child(AtspiAccessible * obj, int i) static Eina_Bool _has_next_sibling(AtspiAccessible * obj, int next_sibling_idx_modifier) { Eina_Bool ret = EINA_FALSE; + if (!obj) return ret; + int idx = atspi_accessible_get_index_in_parent(obj, NULL); if (idx >= 0) { AtspiAccessible *parent = atspi_accessible_get_parent(obj, NULL); diff --git a/src/navigator.c b/src/navigator.c index e2ed195..7cb8488 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -368,13 +368,15 @@ char *generate_trait(AtspiAccessible * obj) switch (role) { case ATSPI_ROLE_ENTRY: { gchar *role_name = atspi_accessible_get_localized_role_name(obj, NULL); - 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); + 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: { @@ -510,9 +512,11 @@ char *generate_trait(AtspiAccessible * obj) if (parent_role != ATSPI_ROLE_COLOR_CHOOSER) { gchar *role_name; role_name = atspi_accessible_get_localized_role_name(obj, NULL); - strncat(ret, ", ", sizeof(ret) - strlen(ret) - 1); - strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1); - g_free(role_name); + 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); } @@ -553,8 +557,10 @@ char *generate_trait(AtspiAccessible * obj) } default: { gchar *role_name = atspi_accessible_get_localized_role_name(obj, NULL); - strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1); - g_free(role_name); + if (role_name) { + strncat(ret, role_name, sizeof(ret) - strlen(ret) - 1); + g_free(role_name); + } } } @@ -624,15 +630,18 @@ static char *generate_description_from_relation_object(AtspiAccessible *obj) g_free(desc); return ret; } - if (desc[0] != '\0') - { - char *tmp = ret; - if (asprintf(&ret, "%s, %s", desc, ret) < 0) - ERROR("asprintf failed."); - free(tmp); + + 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); } - g_free(desc); + return ret; } -- 2.7.4 From 8849dbb92a8aba49765d4662d8660ac9418d244c Mon Sep 17 00:00:00 2001 From: Bartlomiej Uliasz Date: Thu, 24 Sep 2015 12:00:39 +0200 Subject: [PATCH 03/16] navigator: fix wrong text read when a slider is selected. Fix of text read when slider is selected. [UIFWAC-26] Change-Id: I987e8b958decfd4699f5b670d524fa720fa231a8 Signed-off-by: Bartlomiej Uliasz --- res/po/en_US.po | 7 ++++++ src/navigator.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/res/po/en_US.po b/res/po/en_US.po index 8a1ec3d..04325e4 100644 --- a/res/po/en_US.po +++ b/res/po/en_US.po @@ -1,4 +1,10 @@ +msgid "IDS_TRAIT_SLIDER_SWIPE_COMMUNICATE" +msgstr "flick up and down to adjust the position. " + +msgid "IDS_TRAIT_SLIDER_VALUE" +msgstr " from %.*f to %.*f, current value %.*f, " + msgid "IDS_SCROLLING_FINISHED" msgstr "Scrolling finished" @@ -217,3 +223,4 @@ msgstr "selected" msgid "IDS_TRAIT_ITEM_SELECTED_COUNT" msgstr "%d selected in total" + diff --git a/src/navigator.c b/src/navigator.c index 7cb8488..43abbfd 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -357,6 +357,64 @@ static int _find_popup_list_children_count(AtspiAccessible * obj) 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); + 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) @@ -551,6 +609,10 @@ char *generate_trait(AtspiAccessible * obj) } break; } + case ATSPI_ROLE_SLIDER: { + add_slider_description(ret, sizeof(ret), obj); + break; + } case ATSPI_ROLE_HEADING: case ATSPI_ROLE_GROUPING: { break; @@ -1158,16 +1220,6 @@ static void _value_dec(void) ERROR("No value interface supported!\n"); } -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; -} - static void _activate_widget(void) { //activate the widget -- 2.7.4 From e1f0b0b5c31a5e025194aba352beaa24683d5e26 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 6 Oct 2015 10:54:14 +0900 Subject: [PATCH 04/16] Fix prevent: CID482391 - Dereference null return value Change-Id: I274c8cfaa6f0e4f167a51215397b1ceb55839a8a --- src/navigator.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/navigator.c b/src/navigator.c index 43abbfd..655047d 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -394,8 +394,10 @@ void add_slider_description(char *dest, uint dest_size, AtspiAccessible *obj) int accuracy; role_name = atspi_accessible_get_localized_role_name(obj, NULL); - strncat(dest, role_name, dest_size - strlen(dest) - 1); - g_free(role_name); + 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) { -- 2.7.4 From 82a398c536bc503fb854efb6bc40e7f7266de2d0 Mon Sep 17 00:00:00 2001 From: Lukasz Stanislawski Date: Tue, 6 Oct 2015 10:57:17 +0200 Subject: [PATCH 05/16] navigator: properly set app_tracker root. If window had modal descendant navigator still put window as root object of app_tracker. This result in flat_navi was given wrong top object. [UIFWAC-43] Change-Id: Ib169845173d07234ee083837794c1c32179bae3d --- src/navigator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/navigator.c b/src/navigator.c index 655047d..b286cb3 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -2218,9 +2218,9 @@ static void on_window_activate(void *data, AtspiAccessible * window) if (window) { DEBUG("Window name: %s", atspi_accessible_get_name(window, NULL)); - app_tracker_callback_register(window, _view_content_changed, NULL); // TODO: modal descendant of window should be used (if exists) otherwise window AtspiAccessible *modal_descendant = _get_modal_descendant(window); + app_tracker_callback_register(modal_descendant ? modal_descendant : window, _view_content_changed, NULL); _view_content_changed(modal_descendant ? modal_descendant : window, NULL); g_object_unref(modal_descendant); } else { -- 2.7.4 From 9391737d566c72f6a864e7b98c2c6b9777a91921 Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Wed, 30 Sep 2015 12:02:37 +0200 Subject: [PATCH 06/16] Added usage of service_app_main instead of appcore_efl_main Change-Id: I2a200b4a8bf367cad07128b218f3b6e0d8b4badf --- CMakeLists.txt | 1 + org.tizen.screen-reader.xml | 4 ++-- packaging/org.tizen.screen-reader.spec | 1 + src/main.c | 42 +++++++++++++++++++++------------- src/screen_reader_vconf.c | 3 ++- tests/CMakeLists.txt | 1 + 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 650c47c..20a7467 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ pkg_check_modules(pkgs REQUIRED capi-network-bluetooth notification capi-network-wifi + capi-appfw-service-application ${TAPI_REQUIRED_PKG} ) diff --git a/org.tizen.screen-reader.xml b/org.tizen.screen-reader.xml index f13fa26..10932c6 100755 --- a/org.tizen.screen-reader.xml +++ b/org.tizen.screen-reader.xml @@ -2,7 +2,7 @@ SMART NAVIGATOR - + /usr/apps/org.tizen.screen-reader/res/icons/screen-reader.png @@ -10,6 +10,6 @@ - + diff --git a/packaging/org.tizen.screen-reader.spec b/packaging/org.tizen.screen-reader.spec index 396b8f9..77e376c 100755 --- a/packaging/org.tizen.screen-reader.spec +++ b/packaging/org.tizen.screen-reader.spec @@ -28,6 +28,7 @@ BuildRequires: pkgconfig(check) BuildRequires: pkgconfig(capi-network-bluetooth) BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(capi-network-wifi) +BuildRequires: pkgconfig(capi-appfw-service-application) %if "%{?tizen_profile_name}" != "tv" BuildRequires: pkgconfig(tapi) %endif diff --git a/src/main.c b/src/main.c index 613d0d2..2b20ab7 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include "navigator.h" #include "window_tracker.h" #include "logger.h" @@ -209,21 +211,27 @@ void set_signal_handler() } } -static int app_create(void *data) +static bool app_create(void *data) { - elm_init(0, NULL); + if (vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, 1)) + ERROR("Can't set value of %s vconf key to 1", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS); + DEBUG("atspi_init"); atspi_init(); - + DEBUG("logger_init"); + DEBUG("screen_reader_create_service"); screen_reader_create_service(data); #ifndef SCREEN_READER_TV + DEBUG("screen_reader_gestures_init"); screen_reader_gestures_init(); + DEBUG("navigator_init"); navigator_init(); #endif + DEBUG("screen_reader_switch_enabled_set"); screen_reader_switch_enabled_set(EINA_TRUE); - return 0; + return true; } -static int app_terminate(void *data) +static void app_terminate(void *data) { DEBUG("screen reader terminating"); #ifndef SCREEN_READER_TV @@ -237,11 +245,15 @@ static int app_terminate(void *data) DEBUG("clear ScreenReaderEnabled property"); screen_reader_switch_enabled_set(EINA_FALSE); DEBUG("screen reader terminated"); - + if (vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, 0)) + ERROR("Can't set value of %s vconf key to 0", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS); DEBUG("libatspi terminated"); atspi_exit(); +} - return 0; +static void app_control(app_control_h app_control, void *data) +{ + return; } int main(int argc, char **argv) @@ -249,14 +261,12 @@ int main(int argc, char **argv) set_signal_handler(); unsetenv("ELM_ATSPI_MODE"); - struct appcore_ops ops = { - .create = app_create, - .terminate = app_terminate, - .pause = NULL, - .resume = NULL, - .reset = NULL - }; - ops.data = get_pointer_to_service_data_struct(); - return appcore_efl_main("screen-reader", &argc, &argv, &ops); + service_app_lifecycle_callback_s event_callback; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.app_control = app_control; + + return service_app_main(argc, argv, &event_callback, get_pointer_to_service_data_struct()); } diff --git a/src/screen_reader_vconf.c b/src/screen_reader_vconf.c index f6ae5c1..b2daef2 100644 --- a/src/screen_reader_vconf.c +++ b/src/screen_reader_vconf.c @@ -16,6 +16,7 @@ #include #include +#include #include "screen_reader_vconf.h" #include "screen_reader_spi.h" #include "logger.h" @@ -42,7 +43,7 @@ void app_termination_cb(keynode_t * node, void *user_data) service_data->run_service = node->value.i; if (service_data->run_service == 0) { - elm_exit(); + service_app_exit(); } DEBUG("END"); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 75034d8..881fdb5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,6 +21,7 @@ pkg_check_modules(tests REQUIRED check vconf elementary + capi-appfw-service-application ) FOREACH(flag ${tests_CFLAGS}) -- 2.7.4 From 8424257e0dab8ad2811a8d12d3f890d16f8b05c8 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Wed, 7 Oct 2015 21:53:49 +0900 Subject: [PATCH 07/16] Fix prevent issue: CID482427, CID482428 Change-Id: I39a28cf5b862dea335f3816151191ee8f76978e2 --- src/navigator.c | 2 +- src/smart_notification.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/navigator.c b/src/navigator.c index b286cb3..c965cd8 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -1164,7 +1164,7 @@ static void _read_value(AtspiValue * value) char buf[256] = "\0"; snprintf(buf, sizeof(buf), "%d percent", proc); DEBUG("has value %s", buf); - tts_speak(strdup(buf), EINA_TRUE); + tts_speak(buf, EINA_TRUE); } static void _value_inc(void) diff --git a/src/smart_notification.c b/src/smart_notification.c index f48078c..e519797 100644 --- a/src/smart_notification.c +++ b/src/smart_notification.c @@ -188,5 +188,5 @@ static void _smart_notification_realized_items(int start_idx, int end_idx) snprintf(buf, sizeof(buf), _("IDS_REACHED_ITEMS_NOTIFICATION"), start_idx, end_idx); - tts_speak(strdup(buf), EINA_FALSE); + tts_speak(buf, EINA_FALSE); } -- 2.7.4 From e9e8078a13a443f3b38b72e01fd61234ccd8b46d Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Wed, 7 Oct 2015 23:59:21 +0900 Subject: [PATCH 08/16] Revert "Added usage of service_app_main instead of appcore_efl_main" This reverts commit 9391737d566c72f6a864e7b98c2c6b9777a91921. Change-Id: Ib4069bf26793bc1dd6ab17db5effeaf30b8c9b9d --- CMakeLists.txt | 1 - org.tizen.screen-reader.xml | 4 ++-- packaging/org.tizen.screen-reader.spec | 1 - src/main.c | 42 +++++++++++++--------------------- src/screen_reader_vconf.c | 3 +-- tests/CMakeLists.txt | 1 - 6 files changed, 19 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20a7467..650c47c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,6 @@ pkg_check_modules(pkgs REQUIRED capi-network-bluetooth notification capi-network-wifi - capi-appfw-service-application ${TAPI_REQUIRED_PKG} ) diff --git a/org.tizen.screen-reader.xml b/org.tizen.screen-reader.xml index 10932c6..f13fa26 100755 --- a/org.tizen.screen-reader.xml +++ b/org.tizen.screen-reader.xml @@ -2,7 +2,7 @@ SMART NAVIGATOR - + /usr/apps/org.tizen.screen-reader/res/icons/screen-reader.png @@ -10,6 +10,6 @@ - + diff --git a/packaging/org.tizen.screen-reader.spec b/packaging/org.tizen.screen-reader.spec index 77e376c..396b8f9 100755 --- a/packaging/org.tizen.screen-reader.spec +++ b/packaging/org.tizen.screen-reader.spec @@ -28,7 +28,6 @@ BuildRequires: pkgconfig(check) BuildRequires: pkgconfig(capi-network-bluetooth) BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(capi-network-wifi) -BuildRequires: pkgconfig(capi-appfw-service-application) %if "%{?tizen_profile_name}" != "tv" BuildRequires: pkgconfig(tapi) %endif diff --git a/src/main.c b/src/main.c index 2b20ab7..613d0d2 100644 --- a/src/main.c +++ b/src/main.c @@ -21,8 +21,6 @@ #include #include #include -#include -#include #include "navigator.h" #include "window_tracker.h" #include "logger.h" @@ -211,27 +209,21 @@ void set_signal_handler() } } -static bool app_create(void *data) +static int app_create(void *data) { - if (vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, 1)) - ERROR("Can't set value of %s vconf key to 1", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS); - DEBUG("atspi_init"); + elm_init(0, NULL); atspi_init(); - DEBUG("logger_init"); - DEBUG("screen_reader_create_service"); + screen_reader_create_service(data); #ifndef SCREEN_READER_TV - DEBUG("screen_reader_gestures_init"); screen_reader_gestures_init(); - DEBUG("navigator_init"); navigator_init(); #endif - DEBUG("screen_reader_switch_enabled_set"); screen_reader_switch_enabled_set(EINA_TRUE); - return true; + return 0; } -static void app_terminate(void *data) +static int app_terminate(void *data) { DEBUG("screen reader terminating"); #ifndef SCREEN_READER_TV @@ -245,15 +237,11 @@ static void app_terminate(void *data) DEBUG("clear ScreenReaderEnabled property"); screen_reader_switch_enabled_set(EINA_FALSE); DEBUG("screen reader terminated"); - if (vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, 0)) - ERROR("Can't set value of %s vconf key to 0", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS); + DEBUG("libatspi terminated"); atspi_exit(); -} -static void app_control(app_control_h app_control, void *data) -{ - return; + return 0; } int main(int argc, char **argv) @@ -261,12 +249,14 @@ int main(int argc, char **argv) set_signal_handler(); unsetenv("ELM_ATSPI_MODE"); + struct appcore_ops ops = { + .create = app_create, + .terminate = app_terminate, + .pause = NULL, + .resume = NULL, + .reset = NULL + }; + ops.data = get_pointer_to_service_data_struct(); - service_app_lifecycle_callback_s event_callback; - - event_callback.create = app_create; - event_callback.terminate = app_terminate; - event_callback.app_control = app_control; - - return service_app_main(argc, argv, &event_callback, get_pointer_to_service_data_struct()); + return appcore_efl_main("screen-reader", &argc, &argv, &ops); } diff --git a/src/screen_reader_vconf.c b/src/screen_reader_vconf.c index b2daef2..f6ae5c1 100644 --- a/src/screen_reader_vconf.c +++ b/src/screen_reader_vconf.c @@ -16,7 +16,6 @@ #include #include -#include #include "screen_reader_vconf.h" #include "screen_reader_spi.h" #include "logger.h" @@ -43,7 +42,7 @@ void app_termination_cb(keynode_t * node, void *user_data) service_data->run_service = node->value.i; if (service_data->run_service == 0) { - service_app_exit(); + elm_exit(); } DEBUG("END"); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 881fdb5..75034d8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,7 +21,6 @@ pkg_check_modules(tests REQUIRED check vconf elementary - capi-appfw-service-application ) FOREACH(flag ${tests_CFLAGS}) -- 2.7.4 From f87c073b69bfb2997b4ae83ba588c954213d6a63 Mon Sep 17 00:00:00 2001 From: Lukasz Oleksak Date: Thu, 8 Oct 2015 10:55:26 +0200 Subject: [PATCH 09/16] flat_navi: fixes asymetry between forward and backward dfs traversing Change-Id: I65e4216a15ab1842f62ef6a3a587986943afab64 Signed-off-by: Lukasz Oleksak --- src/flat_navi.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/flat_navi.c b/src/flat_navi.c index 72aac40..a7f299f 100644 --- a/src/flat_navi.c +++ b/src/flat_navi.c @@ -436,12 +436,19 @@ AtspiAccessible *_directional_depth_first_search(AtspiAccessible * root, AtspiAc g_object_unref(next_related_in_direction); } + Eina_Bool all_children_visited = (start && start != root && next_sibling_idx_modifier < 0)?EINA_TRUE:EINA_FALSE; + while (node) { AtspiAccessible *prev_related_in_direction = (next_sibling_idx_modifier > 0) ? _get_object_in_relation(node, ATSPI_RELATION_FLOWS_FROM) : _get_object_in_relation(node, ATSPI_RELATION_FLOWS_TO); - if (node != start && (relation_mode || !prev_related_in_direction) && stop_condition(node)) { + int cc = atspi_accessible_get_child_count(node, NULL); + // do not accept: + // 1. start node + // 2. internal nodes of flow relation chains + // 3. parent before children in backward traversing + if (node != start && (relation_mode || !prev_related_in_direction) && !(cc > 0 && next_sibling_idx_modifier < 0 && !all_children_visited) && stop_condition(node)) { g_object_unref(prev_related_in_direction); return node; } @@ -466,16 +473,19 @@ AtspiAccessible *_directional_depth_first_search(AtspiAccessible * root, AtspiAc g_object_unref(prev_related_in_direction); g_object_unref(next_related_in_direction); relation_mode = EINA_FALSE; - int cc = atspi_accessible_get_child_count(node, NULL); + ss = atspi_accessible_get_state_set(node); - if (cc > 0 && atspi_state_set_contains(ss, ATSPI_STATE_SHOWING)) // walk down + if (cc > 0 && !all_children_visited && atspi_state_set_contains(ss, ATSPI_STATE_SHOWING)) // walk down { int idx = next_sibling_idx_modifier > 0 ? 0 : cc - 1; g_object_unref(node); node = atspi_accessible_get_child_at_index(node, idx, NULL); DEBUG("DFS DOWN"); } else { + all_children_visited = EINA_TRUE; + DEBUG("ALL CHILD VISITED (TRUE)"); + Eina_Bool up_node_found = EINA_FALSE; while (!_has_next_sibling(node, next_sibling_idx_modifier) || node == root) // no next sibling { DEBUG("DFS NO SIBLING"); @@ -488,11 +498,20 @@ AtspiAccessible *_directional_depth_first_search(AtspiAccessible * root, AtspiAc g_object_unref(node); node = atspi_accessible_get_parent(node, NULL); // walk up... DEBUG("DFS UP"); + // in backward traversing stop the walk up on parent + if (next_sibling_idx_modifier < 0) { + up_node_found = EINA_TRUE; + break; + } + } + if (!up_node_found) { + int idx = atspi_accessible_get_index_in_parent(node, NULL); + g_object_unref(node); + node = atspi_accessible_get_child_at_index(atspi_accessible_get_parent(node, NULL), idx + next_sibling_idx_modifier, NULL); //... and next + all_children_visited = EINA_FALSE; + DEBUG("RESET ALL CHILD VISITED (FALSE) FOR NEW SIBLING"); + DEBUG("DFS NEXT %d", idx + next_sibling_idx_modifier); } - int idx = atspi_accessible_get_index_in_parent(node, NULL); - g_object_unref(node); - node = atspi_accessible_get_child_at_index(atspi_accessible_get_parent(node, NULL), idx + next_sibling_idx_modifier, NULL); //... and next - DEBUG("DFS NEXT %d", idx + next_sibling_idx_modifier); } g_object_unref(ss); } -- 2.7.4 From b16ed7196408ed653740158c9d43734ecf271e49 Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Thu, 8 Oct 2015 12:36:22 +0200 Subject: [PATCH 10/16] Fixed compilation warnings (unused variables, implicit declaration) Change-Id: Iab1baced700e5a2d1706591bc30b1a180c48cfbe --- src/keyboard_tracker.c | 2 +- src/screen_reader_switch.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/keyboard_tracker.c b/src/keyboard_tracker.c index 70f62d9..c0d3c4e 100644 --- a/src/keyboard_tracker.c +++ b/src/keyboard_tracker.c @@ -20,7 +20,7 @@ #include #include "keyboard_tracker.h" #include "logger.h" - +#include "screen_reader_tts.h" static AtspiDeviceListener *listener; static Keyboard_Tracker_Cb user_cb; static void *user_data; diff --git a/src/screen_reader_switch.c b/src/screen_reader_switch.c index 651d49f..b6b18c1 100644 --- a/src/screen_reader_switch.c +++ b/src/screen_reader_switch.c @@ -69,8 +69,8 @@ Eina_Bool screen_reader_switch_enabled_set(Eina_Bool value) Eldbus_Connection *conn; Eldbus_Object *dobj; Eldbus_Proxy *proxy; - Eldbus_Message *req, *reply; - const char *errname = NULL, *errmsg = NULL; + Eldbus_Message *req; + Eina_Bool ret = EINA_FALSE; Eldbus_Message_Iter *iter; -- 2.7.4 From cfc71295c3783a77d5a432447656304e41d29f55 Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Fri, 9 Oct 2015 14:51:50 +0200 Subject: [PATCH 11/16] Added setting vconf key when SR created and terminated. Change-Id: I20600cead27c1de070e33075f16cc9b8c194c6da --- src/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 613d0d2..b1b91a8 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "navigator.h" #include "window_tracker.h" #include "logger.h" @@ -211,6 +212,8 @@ void set_signal_handler() static int app_create(void *data) { + if (vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, 1)) + ERROR("Can't set value of %s vconf key to 1", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS); elm_init(0, NULL); atspi_init(); @@ -240,7 +243,8 @@ static int app_terminate(void *data) DEBUG("libatspi terminated"); atspi_exit(); - + if (vconf_set_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, 0)) + ERROR("Can't set value of %s vconf key to 1", VCONFKEY_SETAPPL_ACCESSIBILITY_TTS); return 0; } -- 2.7.4 From 9970b7bfab0900ad5a37511408d676c02cd8fd44 Mon Sep 17 00:00:00 2001 From: Shinwoo Kim Date: Tue, 4 Aug 2015 21:42:30 +0900 Subject: [PATCH 12/16] Remove tizen 2.4 keyword, and follow tizen 3.0 general definition Change-Id: I822e9507822ec4940e3176f15db9ad5b38a893f4 --- CMakeLists.txt | 2 +- org.tizen.screen-reader.xml | 3 +-- packaging/org.tizen.screen-reader.spec | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 650c47c..f9188a6 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,7 +55,7 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} ${SLP_LD_PATH_FLAGS} ${SLP INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) INSTALL(DIRECTORY ${RESOURCE_DIR}/icons DESTINATION res) # Install Manifest File -INSTALL(FILES org.tizen.screen-reader.xml DESTINATION /opt/share/packages) +INSTALL(FILES org.tizen.screen-reader.xml DESTINATION /usr/share/packages) ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/res/po) ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/tests) diff --git a/org.tizen.screen-reader.xml b/org.tizen.screen-reader.xml index f13fa26..99284a4 100755 --- a/org.tizen.screen-reader.xml +++ b/org.tizen.screen-reader.xml @@ -1,5 +1,5 @@ - + SMART NAVIGATOR @@ -9,7 +9,6 @@ - diff --git a/packaging/org.tizen.screen-reader.spec b/packaging/org.tizen.screen-reader.spec index 396b8f9..96ee306 100755 --- a/packaging/org.tizen.screen-reader.spec +++ b/packaging/org.tizen.screen-reader.spec @@ -74,4 +74,4 @@ rm -rf %{buildroot} %{AppInstallPath}/bin/screen-reader %{AppInstallPath}/res/icons/screen-reader.png %{AppInstallPath}/res/locale/*/LC_MESSAGES/* -/opt/share/packages/%{name}.xml +/usr/share/packages/%{name}.xml -- 2.7.4 From 944348726ee91cc0fd38078640997ba21df9ac56 Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Tue, 20 Oct 2015 16:19:55 +0200 Subject: [PATCH 13/16] tizen_2.4 adapted for 3.0 TV Change-Id: I19bc03f45871ec5f87a9e14265b8a07df67193b0 --- CMakeLists.txt | 32 +++++++++++++++++++++-- org.tizen.screen-reader.manifest | 48 +++------------------------------- packaging/org.tizen.screen-reader.spec | 11 +++++--- src/main.c | 5 ++-- src/screen_reader_vconf.c | 8 +++--- 5 files changed, 48 insertions(+), 56 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f9188a6..739a1b8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,22 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) ENABLE_TESTING() # FIND ALL SOURCE IN A SOURCE DIRECTORY -AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src SRCS) +#AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src SRCS) + +SET(SRCS ${CMAKE_SOURCE_DIR}/src/app_tracker.c + ${CMAKE_SOURCE_DIR}/src/flat_navi.c + ${CMAKE_SOURCE_DIR}/src/main.c + ${CMAKE_SOURCE_DIR}/src/pivot_chooser.c + ${CMAKE_SOURCE_DIR}/src/screen_reader.c + ${CMAKE_SOURCE_DIR}/src/screen_reader_haptic.c + ${CMAKE_SOURCE_DIR}/src/screen_reader_spi.c + ${CMAKE_SOURCE_DIR}/src/screen_reader_switch.c + ${CMAKE_SOURCE_DIR}/src/screen_reader_system.c + ${CMAKE_SOURCE_DIR}/src/screen_reader_tts.c + ${CMAKE_SOURCE_DIR}/src/screen_reader_vconf.c + ${CMAKE_SOURCE_DIR}/src/smart_notification.c +) + #INCLUDE FILE INCLUDE(CMakeLists.sub) @@ -12,11 +27,24 @@ SET(LOCALEDIR "/usr/apps/org.tizen.screen-reader/res/locale") IF("${SEC_FEATURE_TAPI_ENABLE}" STREQUAL "1") MESSAGE("SEC_FEATURE_TAPI_ENABLE: ${SEC_FEATURE_TAPI_ENABLE}") SET(TAPI_REQUIRED_PKG "tapi") + SET(SRCS ${SRCS} + ${CMAKE_SOURCE_DIR}/src/dbus_gesture_adapter.c + ${CMAKE_SOURCE_DIR}/src/elm_access_adapter.c + ${CMAKE_SOURCE_DIR}/src/screen_reader_gestures.c + ${CMAKE_SOURCE_DIR}/src/navigator.c + ${CMAKE_SOURCE_DIR}/src/keyboard_tracker.c + ${CMAKE_SOURCE_DIR}/src/window_tracker.c) ELSE() MESSAGE("SEC_FEATURE_TAPI_ENABLE: ${SEC_FEATURE_TAPI_ENABLE}") ADD_DEFINITIONS("-DSCREEN_READER_TV") ENDIF() +IF("${X11_ENABLED}" STREQUAL "1") + MESSSAGE("X11 is enabled") + SET(CONDITIONAL_PACKAGES ${CONDITIONAL_PACKAGES} "ecore-x") + ADD_DEFINITIONS("-DX11_ENABLED") +ENDIF() + INCLUDE(FindPkgConfig) pkg_check_modules(pkgs REQUIRED bundle @@ -26,7 +54,6 @@ pkg_check_modules(pkgs REQUIRED ecore atspi-2 gobject-2.0 - ecore-x dlog vconf tts @@ -36,6 +63,7 @@ pkg_check_modules(pkgs REQUIRED notification capi-network-wifi ${TAPI_REQUIRED_PKG} + ${CONDITIONAL_PACKAGES} ) FOREACH(flag ${pkgs_CFLAGS}) diff --git a/org.tizen.screen-reader.manifest b/org.tizen.screen-reader.manifest index cbe437f..9c82c66 100644 --- a/org.tizen.screen-reader.manifest +++ b/org.tizen.screen-reader.manifest @@ -1,47 +1,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/packaging/org.tizen.screen-reader.spec b/packaging/org.tizen.screen-reader.spec index 96ee306..d0bd43c 100755 --- a/packaging/org.tizen.screen-reader.spec +++ b/packaging/org.tizen.screen-reader.spec @@ -14,7 +14,9 @@ BuildRequires: at-spi2-core-devel BuildRequires: cmake BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(ecore) +%if %{with x} BuildRequires: pkgconfig(ecore-x) +%endif BuildRequires: pkgconfig(eina) BuildRequires: pkgconfig(eldbus) BuildRequires: pkgconfig(elementary) @@ -28,7 +30,7 @@ BuildRequires: pkgconfig(check) BuildRequires: pkgconfig(capi-network-bluetooth) BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(capi-network-wifi) -%if "%{?tizen_profile_name}" != "tv" +%if "%{?profile}" != "tv" BuildRequires: pkgconfig(tapi) %endif @@ -41,16 +43,19 @@ An utility library for developers of the menu screen. %build rm -rf CMakeFiles CMakeCache.txt -%if "%{?tizen_profile_name}" != "tv" +%if "%{profile}" != "tv" export SEC_FEATURE_TAPI_ENABLE="1" + export CFLAGS+=" -DELM_ACCESS_KEYBOARD" %else export SEC_FEATURE_TAPI_ENABLE="0" %endif -export CFLAGS+=" -DELM_ACCESS_KEYBOARD" cmake . -DCMAKE_INSTALL_PREFIX="%{AppInstallPath}" \ -DCMAKE_TARGET="%{Exec}" \ -DCMAKE_PACKAGE="%{name}" \ +%if %{with x} + -DX11_ENABLED=1 \ +%endif -DSEC_FEATURE_TAPI_ENABLE=${SEC_FEATURE_TAPI_ENABLE} make %{?jobs:-j%jobs} \ diff --git a/src/main.c b/src/main.c index b1b91a8..f6017f4 100644 --- a/src/main.c +++ b/src/main.c @@ -22,11 +22,12 @@ #include #include #include +#ifndef SCREEN_READER_TV #include "navigator.h" -#include "window_tracker.h" +#include "screen_reader_gestures.h" +#endif #include "logger.h" #include "screen_reader.h" -#include "screen_reader_gestures.h" #include "screen_reader_switch.h" #define MAX_STACK_FRAMES 64 diff --git a/src/screen_reader_vconf.c b/src/screen_reader_vconf.c index f6ae5c1..fbf7818 100644 --- a/src/screen_reader_vconf.c +++ b/src/screen_reader_vconf.c @@ -36,10 +36,10 @@ keylist_t *keys = NULL; void app_termination_cb(keynode_t * node, void *user_data) { DEBUG("START"); - DEBUG("Application terminate %d", !node->value.i); + DEBUG("Application terminate %d", !vconf_keynode_get_int(node)); Service_Data *service_data = user_data; - service_data->run_service = node->value.i; + service_data->run_service = vconf_keynode_get_int(node); if (service_data->run_service == 0) { elm_exit(); @@ -51,10 +51,10 @@ void app_termination_cb(keynode_t * node, void *user_data) void display_language_cb(keynode_t * node, void *user_data) { DEBUG("START"); - DEBUG("Trying to set LC_MESSAGES to: %s", node->value.s); + DEBUG("Trying to set LC_MESSAGES to: %s", vconf_keynode_get_str(node)); Service_Data *sd = user_data; - snprintf(sd->display_language, LANGUAGE_NAME_SIZE, "%s", node->value.s); + snprintf(sd->display_language, LANGUAGE_NAME_SIZE, "%s", vconf_keynode_get_str(node)); //to make gettext work setenv("LC_MESSAGES", sd->display_language, 1); -- 2.7.4 From b0032b59aeb941b658a0fa2ccc36263fd7cb2fe4 Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Tue, 27 Oct 2015 11:09:32 +0100 Subject: [PATCH 14/16] Changes that allow to compile SR on Tizen 3.0 Mobile. There are still many issues related to fact that Wayland differs a lot comparing to X11 and we used X11 a lot - especially for gesture recognition, scrolling. Change-Id: I24ea4d42006fe39359f484c9eddeffc8b7ac6572 --- CMakeLists.txt | 5 ++- include/elm_access_adapter.h | 13 +++++- include/screen_reader_gestures.h | 15 ++++++- packaging/org.tizen.screen-reader.spec | 6 ++- src/elm_access_adapter.c | 13 +++++- src/keyboard_tracker.c | 9 +++- src/navigator.c | 14 ++++-- src/screen_reader_gestures.c | 82 ++++++++++++++++++++++++++++------ src/window_tracker.c | 8 +++- 9 files changed, 140 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 739a1b8..8044755 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,9 +40,12 @@ ELSE() ENDIF() IF("${X11_ENABLED}" STREQUAL "1") - MESSSAGE("X11 is enabled") + MESSAGE(STATUS "X11 is enabled") SET(CONDITIONAL_PACKAGES ${CONDITIONAL_PACKAGES} "ecore-x") ADD_DEFINITIONS("-DX11_ENABLED") +ELSE() + MESSAGE(STATUS "X11 is disabled - using wayland") + SET(CONDITIONAL_PACKAGES ${CONDITIONAL_PACKAGES} "ecore-wayland") ENDIF() INCLUDE(FindPkgConfig) diff --git a/include/elm_access_adapter.h b/include/elm_access_adapter.h index 027108b..3c6b209 100644 --- a/include/elm_access_adapter.h +++ b/include/elm_access_adapter.h @@ -1,8 +1,11 @@ #ifndef ELM_ACCESS_KEYBOARD_ADAPTER_H_ #define ELM_ACCESS_KEYBOARD_ADAPTER_H_ -#include +#ifdef X11_ENABLED #include +#else +#include +#endif /** * @brief Send ecore x message with elm access read action @@ -12,7 +15,11 @@ * @param y y coordinate of gesture relative to X root window * */ +#ifdef X11_ENABLED void elm_access_adaptor_emit_read(Ecore_X_Window win, int x, int y); +#else +void elm_access_adaptor_emit_read(Ecore_Wl_Window *win, int x, int y); +#endif /** * @brief Send ecore x message with elm access activate action @@ -22,6 +29,10 @@ void elm_access_adaptor_emit_read(Ecore_X_Window win, int x, int y); * @param y y coordinate of gesture relative to X root window * */ +#ifdef X11_ENABLED void elm_access_adaptor_emit_activate(Ecore_X_Window win, int x, int y); +#else +void elm_access_adaptor_emit_activate(Ecore_Wl_Window *win, int x, int y); +#endif #endif diff --git a/include/screen_reader_gestures.h b/include/screen_reader_gestures.h index 0e5b1d4..3ac3114 100644 --- a/include/screen_reader_gestures.h +++ b/include/screen_reader_gestures.h @@ -2,8 +2,11 @@ #define SCREEN_READER_GESTURES_H_ #include +#ifdef X11_ENABLED #include - +#else +#include +#endif /** * @brief Accessibility gestures */ @@ -70,8 +73,11 @@ Eina_Bool screen_reader_gestures_init(void); * @brief Shutdown gesture navigation profile. */ void screen_reader_gestures_shutdown(void); - +#ifdef X11_ENABLED Eina_Bool screen_reader_gesture_x_grab_touch_devices(Ecore_X_Window win); +#else +Eina_Bool screen_reader_gesture_wl_grab_touch_devices(Ecore_Wl_Window win); +#endif typedef void (*GestureCB)(void *data, Gesture_Info *info); @@ -103,5 +109,10 @@ void end_scroll(int x, int y); * * @return Ecore_X_Window Object which represents top window on which gesture occure */ +#ifdef X11_ENABLED Ecore_X_Window top_window_get (int x, int y); +#else +Ecore_Wl_Window *top_window_get (int x, int y); +#endif + #endif diff --git a/packaging/org.tizen.screen-reader.spec b/packaging/org.tizen.screen-reader.spec index d0bd43c..9d10be4 100755 --- a/packaging/org.tizen.screen-reader.spec +++ b/packaging/org.tizen.screen-reader.spec @@ -1,6 +1,7 @@ %define AppInstallPath /usr/apps/%{name} %define Exec screen-reader - +%bcond_with x +%bcond_with wayland Name: org.tizen.screen-reader Summary: Screen Reader Assistive Technology @@ -17,6 +18,9 @@ BuildRequires: pkgconfig(ecore) %if %{with x} BuildRequires: pkgconfig(ecore-x) %endif +%if %{with wayland} +BuildRequires: pkgconfig(ecore-wayland) +%endif BuildRequires: pkgconfig(eina) BuildRequires: pkgconfig(eldbus) BuildRequires: pkgconfig(elementary) diff --git a/src/elm_access_adapter.c b/src/elm_access_adapter.c index fc46227..233e51a 100644 --- a/src/elm_access_adapter.c +++ b/src/elm_access_adapter.c @@ -17,6 +17,7 @@ #include "elm_access_adapter.h" #include "logger.h" +#ifdef X11_ENABLED static void _get_root_coords(Ecore_X_Window win, int *x, int *y) { Ecore_X_Window root = ecore_x_window_root_first_get(); @@ -37,7 +38,6 @@ static void _get_root_coords(Ecore_X_Window win, int *x, int *y) parent = ecore_x_window_parent_get(parent); } } - static void _send_ecore_x_client_msg(Ecore_X_Window win, int x, int y, Eina_Bool activate) { int x_win, y_win; @@ -63,3 +63,14 @@ void elm_access_adaptor_emit_read(Ecore_X_Window win, int x, int y) { _send_ecore_x_client_msg(win, x, y, EINA_FALSE); } +#else +void elm_access_adaptor_emit_activate(Ecore_Wl_Window *win, int x, int y) +{ + +} + +void elm_access_adaptor_emit_read(Ecore_Wl_Window *win, int x, int y) +{ + +} +#endif \ No newline at end of file diff --git a/src/keyboard_tracker.c b/src/keyboard_tracker.c index c0d3c4e..74befc9 100644 --- a/src/keyboard_tracker.c +++ b/src/keyboard_tracker.c @@ -17,13 +17,16 @@ #include #include #include +#ifdef X11_ENABLED #include +#endif #include "keyboard_tracker.h" #include "logger.h" #include "screen_reader_tts.h" static AtspiDeviceListener *listener; static Keyboard_Tracker_Cb user_cb; static void *user_data; +#ifdef X11_ENABLED static Ecore_Event_Handler *root_xwindow_property_changed_hld = NULL; static Ecore_Event_Handler *active_xwindow_property_changed_hld = NULL; @@ -134,7 +137,7 @@ void root_xwindow_property_tracker_unregister() root_xwindow_property_changed_hld = NULL; } } - +#endif static gboolean device_cb(const AtspiDeviceEvent * stroke, void *data) { Key k; @@ -159,8 +162,10 @@ void keyboard_tracker_init(void) { listener = atspi_device_listener_new(device_cb, NULL, NULL); atspi_register_keystroke_listener(listener, NULL, 0, ATSPI_KEY_PRESSED, ATSPI_KEYLISTENER_SYNCHRONOUS | ATSPI_KEYLISTENER_CANCONSUME, NULL); +#ifdef X11_ENABLED active_xwindow_property_tracker_register(); root_xwindow_property_tracker_register(); +#endif DEBUG("keyboard tracker init"); } @@ -173,7 +178,9 @@ void keyboard_tracker_register(Keyboard_Tracker_Cb cb, void *data) void keyboard_tracker_shutdown(void) { atspi_deregister_keystroke_listener(listener, NULL, 0, ATSPI_KEY_PRESSED, NULL); +#ifdef X11_ENABLED root_xwindow_property_tracker_unregister(); active_xwindow_property_tracker_unregister(); +#endif DEBUG("keyboard tracker shutdown"); } diff --git a/src/navigator.c b/src/navigator.c index c965cd8..1dcc68a 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -16,7 +16,11 @@ #define _GNU_SOURCE #include +#ifdef X11_ENABLED #include +#else +#include +#endif #include #include #include @@ -1348,6 +1352,7 @@ static void _activate_widget(void) static void _quickpanel_change_state(gboolean quickpanel_switch) { DEBUG("START"); +#ifdef X11_ENABLED Ecore_X_Window xwin = 0; if (quickpanel_switch) @@ -1366,6 +1371,7 @@ static void _quickpanel_change_state(gboolean quickpanel_switch) ecore_x_e_illume_quickpanel_state_send(ecore_x_e_illume_zone_get(xwin), state); ecore_main_loop_iterate(); +#endif } /** @@ -2018,7 +2024,9 @@ static void _start_stop_signal_send(void) static void on_gesture_detected(void *data, Gesture_Info * info) { +#ifdef X11_ENABLED Ecore_X_Window keyboard_win; +#endif _on_auto_review_stop(); if (info->type == ONE_FINGER_SINGLE_TAP && info->state == 3) { @@ -2039,7 +2047,7 @@ static void on_gesture_detected(void *data, Gesture_Info * info) if ((info->event_time - _last_hover_event_time) < ONGOING_HOVER_GESTURE_INTERPRETATION_INTERVAL && info->state == 1) return; _last_hover_event_time = info->state != 1 ? -1 : info->event_time; -#ifdef ELM_ACCESS_KEYBOARD +#if defined(ELM_ACCESS_KEYBOARD) && defined(X11_ENABLED) keyboard_win = top_window_get(info->x_end, info->y_end); if (keyboard_win && ecore_x_e_virtual_keyboard_get(keyboard_win)) { elm_access_adaptor_emit_read(keyboard_win, info->x_end, info->y_end); @@ -2075,7 +2083,7 @@ static void on_gesture_detected(void *data, Gesture_Info * info) _focus_next(); break; case ONE_FINGER_SINGLE_TAP: -#ifdef ELM_ACCESS_KEYBOARD +#if defined(ELM_ACCESS_KEYBOARD) && defined(X11_ENABLED) keyboard_win = top_window_get(info->x_end, info->y_end); if (keyboard_win && ecore_x_e_virtual_keyboard_get(keyboard_win)) { elm_access_adaptor_emit_read(keyboard_win, info->x_end, info->y_end); @@ -2086,7 +2094,7 @@ static void on_gesture_detected(void *data, Gesture_Info * info) _focus_widget(info); break; case ONE_FINGER_DOUBLE_TAP: -#ifdef ELM_ACCESS_KEYBOARD +#if defined(ELM_ACCESS_KEYBOARD) && defined(X11_ENABLED) keyboard_win = top_window_get(info->x_end, info->y_end); if (keyboard_win && ecore_x_e_virtual_keyboard_get(keyboard_win)) { elm_access_adaptor_emit_activate(keyboard_win, info->x_end, info->y_end); diff --git a/src/screen_reader_gestures.c b/src/screen_reader_gestures.c index c55d606..1a83297 100644 --- a/src/screen_reader_gestures.c +++ b/src/screen_reader_gestures.c @@ -19,11 +19,21 @@ #include #include +#ifdef X11_ENABLED #include +#else +#include +#endif static GestureCB _global_cb; static void *_global_data; -static Ecore_Window win; + +#ifdef X11_ENABLED +static Ecore_X_Window win; +#else +static Ecore_Wl_Window *win; +#endif + static Ecore_Event_Handler *property_changed_hld; struct _Gestures_Config { @@ -70,7 +80,11 @@ typedef enum { } gesture_type_e; struct _Cover { +#ifdef X11_ENABLED Ecore_X_Window win; /**< Input window covering given zone */ +#else + Ecore_Wl_Window *win; /**< Input window covering given zone */ +#endif unsigned int n_taps; /**< Number of fingers touching screen */ unsigned int event_time; @@ -115,8 +129,10 @@ struct _Cover { typedef struct _Cover Cover; Gestures_Config *_e_mod_config; +#ifdef X11_ENABLED static Ecore_X_Window scrolled_win; static int rx, ry; +#endif static Eina_List *handlers; static Cover *cov; static int win_angle; @@ -126,24 +142,25 @@ static unsigned int _win_angle_get(void); void __transform_coordinates(int *ax, int *ay) { - Ecore_X_Window root; int w; int h; int tmp; +#ifdef X11_ENABLED + ecore_x_window_geometry_get(ecore_x_window_root_first_get(), NULL, NULL, &w, &h); +#else + ecore_wl_screen_size_get(&w, &h); +#endif win_angle = _win_angle_get(); switch (win_angle) { case 90: - root = ecore_x_window_root_first_get(); - ecore_x_window_geometry_get(root, NULL, NULL, &w, &h); tmp = *ax; *ax = h - *ay; *ay = tmp; break; case 270: - root = ecore_x_window_root_first_get(); - ecore_x_window_geometry_get(root, NULL, NULL, &w, &h); + tmp = *ax; *ax = *ay; *ay = w - tmp; @@ -615,7 +632,7 @@ static void _hover_gesture_mouse_up(Ecore_Event_Mouse_Button * ev, Cover * cov) if (cov->n_taps == 0) cov->hover_gesture.state = GESTURE_NOT_STARTED; } - +#ifdef X11_ENABLED static void _get_root_coords(Ecore_X_Window win, int *x, int *y) { Ecore_X_Window root = ecore_x_window_root_first_get(); @@ -648,9 +665,17 @@ Ecore_X_Window top_window_get(int x, int y) } return 0; } +#else +Ecore_Wl_Window *top_window_get(int x, int y) +{ + return 0; +} +#endif + void start_scroll(int x, int y) { +#ifdef X11_ENABLED Ecore_X_Window wins[1] = { win }; Ecore_X_Window under = ecore_x_window_at_xy_with_skip_get(x, y, wins, sizeof(wins) / sizeof(wins[0])); _get_root_coords(under, &rx, &ry); @@ -658,25 +683,31 @@ void start_scroll(int x, int y) ecore_x_window_focus(under); ecore_x_mouse_down_send(under, x - rx, y - ry, 1); scrolled_win = under; +#endif } void continue_scroll(int x, int y) { +#ifdef X11_ENABLED ecore_x_mouse_move_send(scrolled_win, x - rx, y - ry); +#endif } void end_scroll(int x, int y) { - ecore_x_mouse_up_send(scrolled_win, x - rx, y - ry, 1); +#ifdef X11_ENABLED + ecore_x_mouse_up_send(scrolled_win, x - rx, y - ry, 1); ecore_x_mouse_out_send(scrolled_win, x - rx, y - ry); +#endif } static unsigned int _win_angle_get(void) { + int angle = 0; +#ifdef X11_ENABLED Ecore_X_Window root, first_root; int ret; int count; - int angle = 0; unsigned char *prop_data = NULL; first_root = ecore_x_window_root_first_get(); @@ -688,7 +719,9 @@ static unsigned int _win_angle_get(void) if (prop_data) free(prop_data); +#else +#endif return angle; } @@ -1025,25 +1058,34 @@ static Eina_Bool _gesture_input_win_create(void) int w, h; if (!win) { +#ifdef X11_ENABLED Ecore_Window root = ecore_x_window_root_first_get(); if (!root) return EINA_FALSE; ecore_x_window_geometry_get(root, NULL, NULL, &w, &h); win = ecore_x_window_input_new(root, 0, 0, w, h); +#else + ecore_wl_screen_size_get(&w, &h); + win = ecore_wl_window_new(NULL, 0, 0, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW); +#endif } if (!win) return EINA_FALSE; +#ifdef X11_ENABLED ecore_x_input_multi_select(win); ecore_x_window_show(win); ecore_x_window_raise(win); - +#else + ecore_wl_window_show(win); + ecore_wl_window_raise(win); +#endif // restet gestures memset(cov, 0x0, sizeof(Cover)); return EINA_TRUE; } - +#ifdef X11_ENABLED static Eina_Bool _win_property_changed(void *data, int type, void *event) { Ecore_X_Event_Window_Property *wp = event; @@ -1055,9 +1097,11 @@ static Eina_Bool _win_property_changed(void *data, int type, void *event) return EINA_TRUE; } +#endif static Eina_Bool _gestures_input_window_init(void) { +#ifdef X11_ENABLED Ecore_Window root = ecore_x_window_root_first_get(); if (!root) { ERROR("No root window found. Is Window manager running?"); @@ -1065,7 +1109,7 @@ static Eina_Bool _gestures_input_window_init(void) } ecore_x_event_mask_set(root, ECORE_X_EVENT_MASK_WINDOW_PROPERTY); property_changed_hld = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _win_property_changed, NULL); - +#endif return _gesture_input_win_create(); } @@ -1073,15 +1117,22 @@ static void _gestures_input_widnow_shutdown(void) { ecore_event_handler_del(property_changed_hld); if (win) +#ifdef X11_ENABLED ecore_x_window_free(win); +#else + ecore_wl_window_free(win); +#endif win = 0; } Eina_Bool screen_reader_gestures_init(void) { ecore_init(); +#ifdef X11_ENABLED ecore_x_init(NULL); - +#else + ecore_wl_init(NULL); +#endif cov = calloc(sizeof(Cover), 1); if (!_gestures_input_window_init()) { @@ -1112,8 +1163,11 @@ void screen_reader_gestures_shutdown(void) ecore_event_handler_del(hdlr); } _gestures_input_widnow_shutdown(); - +#ifdef X11_ENABLED ecore_x_shutdown(); +#else + ecore_wl_shutdown(); +#endif ecore_shutdown(); free(_e_mod_config); free(cov); diff --git a/src/window_tracker.c b/src/window_tracker.c index ebdb9be..4dbfc8b 100644 --- a/src/window_tracker.c +++ b/src/window_tracker.c @@ -17,8 +17,11 @@ #include #include "window_tracker.h" #include "logger.h" + +#ifdef X11_ENABLED #include #include +#endif static Window_Tracker_Cb user_cb; static void *user_data; @@ -49,8 +52,10 @@ static AtspiAccessible *_get_active_win(void) return NULL; } - Ecore_X_Window focus_window = ecore_x_window_focus_get(); unsigned int active_window_pid = 0; +#ifdef X11_ENABLED + Ecore_X_Window focus_window = ecore_x_window_focus_get(); + if (focus_window) { //invoking atspi_accessible_get_child_count for non active apps results in very long screen-reader startup //not active apps have low priority and dbus calls take a lot of time (a few hundred ms per call) @@ -60,6 +65,7 @@ static AtspiAccessible *_get_active_win(void) if (active_window_pid) DEBUG("First we will try filter apps by PID: %i", active_window_pid); } +#endif desktop_children_count = atspi_accessible_get_child_count(desktop, NULL); for (i = 0; i < desktop_children_count; i++) { AtspiAccessible *app = atspi_accessible_get_child_at_index(desktop, i, NULL); -- 2.7.4 From 55443e3c996b8960ecb390a508073ad97fcc445a Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Wed, 28 Oct 2015 17:59:28 +0100 Subject: [PATCH 15/16] Make the condition in flat_navi_context_current_at_x_y_set more readable Change-Id: I08ef56c290f13739927e238221494c18856a6dde --- src/flat_navi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/flat_navi.c b/src/flat_navi.c index a7f299f..20176a7 100644 --- a/src/flat_navi.c +++ b/src/flat_navi.c @@ -358,7 +358,11 @@ Eina_Bool flat_navi_context_current_at_x_y_set(FlatNaviContext * ctx, gint x_cor } if (youngest_ancestor_in_context && !_object_has_modal_state(youngest_ancestor_in_context)) { - if (youngest_ancestor_in_context == current_obj || flat_navi_context_current_set(ctx, youngest_ancestor_in_context)) { + + Eina_Bool update_target = youngest_ancestor_in_context == current_obj; + if (!update_target) + update_target = flat_navi_context_current_set(ctx, youngest_ancestor_in_context); + if (update_target) { DEBUG("Setting highlight to object %s with role %s", atspi_accessible_get_name(youngest_ancestor_in_context, NULL), atspi_accessible_get_role_name(youngest_ancestor_in_context, NULL)); *target = youngest_ancestor_in_context; ret = EINA_TRUE; -- 2.7.4 From 5f959737dd27e5dd374bcd6db77e0770d49379fc Mon Sep 17 00:00:00 2001 From: Lukasz Stanislawski Date: Thu, 24 Sep 2015 13:43:06 +0200 Subject: [PATCH 16/16] lua: add lua engine to process internal logic Change-Id: Idd194972e06d1c6764d9fde4178afb54eebfeafa --- CMakeLists.txt | 4 + include/lua_engine.h | 64 +++ include/screen_reader.h | 1 + include/screen_reader_spi.h | 1 + packaging/org.tizen.screen-reader.spec | 2 + res/po/en_US.po | 2 +- res/scripts/mobile.lua | 129 ++++++ src/lua_engine.c | 809 +++++++++++++++++++++++++++++++++ src/navigator.c | 562 +---------------------- src/screen_reader.c | 5 + src/screen_reader_spi.c | 110 +---- tests/CMakeLists.txt | 2 + tests/atspi/atspi.c | 26 ++ tests/atspi/atspi.h | 238 +++++----- tests/smart_navi_suite.c | 29 +- 15 files changed, 1213 insertions(+), 771 deletions(-) create mode 100644 include/lua_engine.h create mode 100644 res/scripts/mobile.lua create mode 100644 src/lua_engine.c 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); -- 2.7.4