2 * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include "screen_reader_spi.h"
21 #include "screen_reader_tts.h"
23 #include "lua_engine.h"
24 #ifdef RUN_IPC_TEST_SUIT
25 #include "test_suite/test_suite.h"
28 #define EPS 0.000000001
30 /** @brief Service_Data used as screen reader internal data struct*/
31 static Service_Data *service_data;
34 * @brief Debug function. Print current toolkit version/event
35 * type/event source/event detail1/event detail2
37 * @param AtspiEvent instance
40 static void display_info(const AtspiEvent * event)
42 AtspiAccessible *source = event->source;
43 gchar *name = atspi_accessible_get_name(source, NULL);
44 gchar *role = atspi_accessible_get_localized_role_name(source, NULL);
45 gchar *toolkit = atspi_accessible_get_toolkit_name(source, NULL);
47 DEBUG("--------------------------------------------------------");
48 DEBUG("Toolkit: %s; Event_type: %s; (%d, %d)", toolkit, event->type, event->detail1, event->detail2);
49 DEBUG("Name: %s; Role: %s", name, role);
50 DEBUG("--------------------------------------------------------");
53 static char *spi_on_state_changed_get_text(AtspiEvent * event, void *user_data)
55 Service_Data *sd = (Service_Data *) user_data;
56 sd->currently_focused = event->source;
58 return lua_engine_describe_object(sd->currently_focused);
61 static char *spi_on_caret_move_get_text(AtspiEvent * event, void *user_data)
63 Service_Data *sd = (Service_Data *) user_data;
64 sd->currently_focused = event->source;
67 AtspiText *text_interface = atspi_accessible_get_text_iface(sd->currently_focused);
69 DEBUG("->->->->->-> WIDGET CARET MOVED: %s <-<-<-<-<-<-<-", atspi_accessible_get_name(sd->currently_focused, NULL));
71 int char_count = (int)atspi_text_get_character_count(text_interface, NULL);
72 int caret_pos = atspi_text_get_caret_offset(text_interface, NULL);
74 DEBUG("MIN POSITION REACHED");
75 if (asprintf(&return_text, "%s %s", (char *)atspi_text_get_text(text_interface, caret_pos, caret_pos + 1, NULL), _("IDS_REACHED_MIN_POS")) < 0) {
79 } else if (char_count == caret_pos) {
80 DEBUG("MAX POSITION REACHED");
81 if (asprintf(&return_text, "%s %s", (char *)atspi_text_get_text(text_interface, caret_pos, caret_pos + 1, NULL), _("IDS_REACHED_MAX_POS")) < 0) {
86 if (asprintf(&return_text, "%s", (char *)atspi_text_get_text(text_interface, caret_pos, caret_pos + 1, NULL)) < 0) {
98 static char *spi_on_value_changed_get_text(AtspiEvent * event, void *user_data)
100 Service_Data *sd = (Service_Data *) user_data;
101 char *text_to_read = NULL;
103 sd->currently_focused = event->source;
105 AtspiValue *value_interface = atspi_accessible_get_value_iface(sd->currently_focused);
106 if (value_interface) {
107 DEBUG("->->->->->-> WIDGET VALUE CHANGED: %s <-<-<-<-<-<-<-", atspi_accessible_get_name(sd->currently_focused, NULL));
109 double current_temp_value = (double)atspi_value_get_current_value(value_interface, NULL);
110 if (abs(current_temp_value - atspi_value_get_maximum_value(value_interface, NULL)) < EPS) {
111 DEBUG("MAX VALUE REACHED");
112 if (asprintf(&text_to_read, "%.2f %s", current_temp_value, _("IDS_REACHED_MAX_VAL")) < 0) {
116 } else if (abs(current_temp_value - atspi_value_get_minimum_value(value_interface, NULL)) < EPS) {
117 DEBUG("MIN VALUE REACHED");
118 if (asprintf(&text_to_read, "%.2f %s", current_temp_value, _("IDS_REACHED_MIN_VAL")) < 0) {
123 if (asprintf(&text_to_read, "%.2f", current_temp_value) < 0) {
133 char *spi_event_get_text_to_read(AtspiEvent * event, void *user_data)
136 Service_Data *sd = (Service_Data *) user_data;
139 DEBUG("TRACK SIGNAL:%s", sd->tracking_signal_name);
140 DEBUG("WENT EVENT:%s", event->type);
142 if (!sd->tracking_signal_name) {
143 ERROR("Invalid tracking signal name");
147 if (!strncmp(event->type, sd->tracking_signal_name, strlen(event->type)) && event->detail1 == 1) {
148 text_to_read = spi_on_state_changed_get_text(event, user_data);
149 } else if (!strncmp(event->type, CARET_MOVED_SIG, strlen(event->type))) {
150 text_to_read = spi_on_caret_move_get_text(event, user_data);
151 } else if (!strncmp(event->type, VALUE_CHANGED_SIG, strlen(event->type))) {
152 text_to_read = spi_on_value_changed_get_text(event, user_data);
154 ERROR("Unknown event type");
161 void spi_event_listener_cb(AtspiEvent * event, void *user_data)
167 ERROR("Invalid parameter");
171 char *text_to_read = spi_event_get_text_to_read(event, user_data);
173 ERROR("Can not prepare text to read");
176 DEBUG("SPEAK: %s", text_to_read);
177 tts_speak(text_to_read, EINA_TRUE);
184 * @brief Initializer for screen-reader atspi listeners
186 * @param user_data screen-reader internal data
189 void spi_init(Service_Data * sd)
192 ERROR("Invalid parameter");
195 DEBUG("--------------------- SPI_init START ---------------------");
198 DEBUG(">>> Init lua engine<<<");
199 if (lua_engine_init(sd->lua_script_path))
200 ERROR("Failed to init lua engine.");
202 DEBUG(">>> Creating listeners <<<");
204 sd->spi_listener = atspi_event_listener_new(spi_event_listener_cb, service_data, NULL);
205 if (sd->spi_listener == NULL) {
206 DEBUG("FAILED TO CREATE spi state changed listener");
208 // ---------------------------------------------------------------------------------------------------
210 DEBUG("TRACKING SIGNAL:%s", sd->tracking_signal_name);
212 gboolean ret1 = atspi_event_listener_register(sd->spi_listener, sd->tracking_signal_name, NULL);
214 DEBUG("FAILED TO REGISTER spi focus/highlight listener");
216 GError *error = NULL;
217 gboolean ret2 = atspi_event_listener_register(sd->spi_listener, CARET_MOVED_SIG, &error);
219 DEBUG("FAILED TO REGISTER spi caret moved listener: %s", error ? error->message : "no error message");
221 g_clear_error(&error);
224 gboolean ret3 = atspi_event_listener_register(sd->spi_listener, VALUE_CHANGED_SIG, &error);
226 DEBUG("FAILED TO REGISTER spi value changed listener: %s", error ? error->message : "no error message");
228 g_clear_error(&error);
231 if (ret1 == true && ret2 == true && ret3 == true) {
232 DEBUG("spi listener REGISTERED");
235 DEBUG("---------------------- SPI_init END ----------------------\n\n");
238 void spi_shutdown(Service_Data * sd)
240 lua_engine_shutdown();