Multilanguage support
[profile/tv/apps/native/screen-reader.git] / src / smart_notification.c
1 #include <Ecore.h>
2 #include <Ecore_Evas.h>
3 #include <Evas.h>
4 #include <atspi/atspi.h>
5 #include <tone_player.h>
6 #include "logger.h"
7 #include "screen_reader_tts.h"
8 #include "screen_reader_haptic.h"
9 #include "smart_notification.h"
10
11 #define RED  "\x1B[31m"
12 #define RESET "\033[0m"
13
14 static Eina_Bool status = EINA_FALSE;
15
16 static void _smart_notification_focus_chain_end(void);
17 static void _smart_notification_realized_items(int start_idx, int end_idx);
18
19 /**
20  * @brief Smart Notifications event handler
21  *
22  * @param nt Notification event type
23  * @param start_index int first visible items index smart_notification_realized_items
24  * @param end_index int last visible items index used for smart_notification_realized_items
25  */
26 void smart_notification(Notification_Type nt, int start_index, int end_index)
27 {
28    DEBUG("START");
29    if(!status)
30       return;
31
32    switch(nt)
33       {
34       case FOCUS_CHAIN_END_NOTIFICATION_EVENT:
35          _smart_notification_focus_chain_end();
36          break;
37       case REALIZED_ITEMS_NOTIFICATION_EVENT:
38          _smart_notification_realized_items(start_index, end_index);
39          break;
40       default:
41          DEBUG("Gesture type %d not handled in switch", nt);
42       }
43 }
44
45 /**
46  * @brief Used for getting first and last index of visible items
47  *
48  * @param scrollable_object AtspiAccessible object on which scroll was triggered
49  * @param start_index int first visible items index smart_notification_realized_items
50  * @param end_index int last visible items index used for smart_notification_realized_items
51  */
52 void get_realized_items_count(AtspiAccessible *scrollable_object, int *start_idx, int *end_idx)
53 {
54    DEBUG("START");
55    int count_child, jdx;
56    AtspiAccessible *child_iter;
57    AtspiStateType state =  ATSPI_STATE_SHOWING;
58
59    if(!scrollable_object)
60       {
61          DEBUG("No scrollable object");
62          return;
63       }
64
65    count_child = atspi_accessible_get_child_count(scrollable_object, NULL);
66
67    for(jdx = 0; jdx < count_child; jdx++)
68       {
69          child_iter = atspi_accessible_get_child_at_index(scrollable_object, jdx, NULL);
70          if (!child_iter) continue;
71
72          AtspiStateSet* state_set = atspi_accessible_get_state_set(child_iter);
73
74          gboolean is_visible = atspi_state_set_contains(state_set, state);
75          if(is_visible)
76             {
77                *start_idx = jdx;
78                DEBUG("Item with index %d is visible", jdx);
79             }
80          else
81             DEBUG("Item with index %d is NOT visible", jdx);
82       }
83    *end_idx = *start_idx + 8;
84 }
85
86 /**
87  * @brief Scroll-start/Scroll-end event callback
88  *
89  * @param event AtspiEvent
90  * @param user_data UNUSED
91  */
92
93 static void
94 _scroll_event_cb(AtspiEvent *event, gpointer user_data)
95 {
96    if(!status)
97       return;
98
99    int start_index, end_index;
100    start_index = 0;
101    end_index = 0;
102
103    gchar *role_name = atspi_accessible_get_role_name(event->source, NULL);
104    fprintf(stderr, "Event: %s: %d, obj: %p: role: %s\n",
105            event->type, event->detail1, event->source,
106            role_name);
107    g_free(role_name);
108
109    if (!strcmp(event->type, "object:scroll-start"))
110       {
111          DEBUG("Scrolling started");
112          tts_speak("Scrolling started", EINA_TRUE);
113       }
114    else if (!strcmp(event->type, "object:scroll-end"))
115       {
116          DEBUG("Scrolling finished");
117          tts_speak("Scrolling finished", EINA_FALSE);
118          get_realized_items_count((AtspiAccessible *)event->source, &start_index, &end_index);
119          _smart_notification_realized_items(start_index, end_index);
120       }
121 }
122
123 /**
124  * @brief Initializer for smart notifications
125  *
126  *
127  */
128 void smart_notification_init(void)
129 {
130    DEBUG("Smart Notification init!");
131
132    AtspiEventListener *listener;
133
134    listener = atspi_event_listener_new(_scroll_event_cb, NULL, NULL);
135    atspi_event_listener_register(listener, "object:scroll-start", NULL);
136    atspi_event_listener_register(listener, "object:scroll-end", NULL);
137
138    haptic_module_init();
139
140    status = EINA_TRUE;
141 }
142
143 /**
144  * @brief Smart notifications shutdown
145  *
146  */
147 void smart_notification_shutdown(void)
148 {
149    status = EINA_FALSE;
150 }
151
152 /**
153  * @brief Smart notifications focus chain event handler
154  *
155  */
156 static void _smart_notification_focus_chain_end(void)
157 {
158    if(!status)
159       return;
160
161    DEBUG(RED"Smart notification - FOCUS CHAIN END"RESET);
162
163    tone_player_stop(0);
164    tone_player_start(TONE_TYPE_SUP_CONFIRM, SOUND_TYPE_MEDIA, 200, NULL);
165 }
166
167 /**
168  * @brief Smart notifications realized items event handler
169  *
170  */
171 static void _smart_notification_realized_items(int start_idx, int end_idx)
172 {
173    if(!status)
174       return;
175
176    if(start_idx == end_idx)
177       return;
178
179    DEBUG(RED"Smart notification - Visible items notification"RESET);
180
181    char buf[256];
182
183    snprintf(buf, sizeof(buf), _("IDS_REACHED_ITEMS_NOTIFICATION"), start_idx, end_idx);
184
185    tts_speak(strdup(buf), EINA_FALSE);
186 }