2 #include <Ecore_Evas.h>
4 #include <atspi/atspi.h>
5 #include <tone_player.h>
7 #include "screen_reader_tts.h"
8 #include "screen_reader_haptic.h"
9 #include "smart_notification.h"
11 #define RED "\x1B[31m"
12 #define RESET "\033[0m"
14 #define ITEMS_NOTIFICATION "Visible items from %d to %d"
16 static Eina_Bool status = EINA_FALSE;
18 static void _smart_notification_focus_chain_end(void);
19 static void _smart_notification_realized_items(int start_idx, int end_idx);
22 * @brief Smart Notifications event handler
24 * @param nt Notification event type
25 * @param start_index int first visible items index smart_notification_realized_items
26 * @param end_index int last visible items index used for smart_notification_realized_items
28 void smart_notification(Notification_Type nt, int start_index, int end_index)
36 case FOCUS_CHAIN_END_NOTIFICATION_EVENT:
37 _smart_notification_focus_chain_end();
39 case REALIZED_ITEMS_NOTIFICATION_EVENT:
40 _smart_notification_realized_items(start_index, end_index);
43 DEBUG("Gesture type %d not handled in switch", nt);
48 * @brief Used for getting first and last index of visible items
50 * @param scrollable_object AtspiAccessible object on which scroll was triggered
51 * @param start_index int first visible items index smart_notification_realized_items
52 * @param end_index int last visible items index used for smart_notification_realized_items
54 void get_realized_items_count(AtspiAccessible *scrollable_object, int *start_idx, int *end_idx)
58 AtspiAccessible *child_iter;
59 AtspiStateType state = ATSPI_STATE_SHOWING;
61 if(!scrollable_object)
63 DEBUG("No scrollable object");
67 count_child = atspi_accessible_get_child_count(scrollable_object, NULL);
69 for(jdx = 0; jdx < count_child; jdx++)
71 child_iter = atspi_accessible_get_child_at_index(scrollable_object, jdx, NULL);
72 if (!child_iter) continue;
74 AtspiStateSet* state_set = atspi_accessible_get_state_set(child_iter);
76 gboolean is_visible = atspi_state_set_contains(state_set, state);
80 DEBUG("Item with index %d is visible", jdx);
83 DEBUG("Item with index %d is NOT visible", jdx);
85 *end_idx = *start_idx + 8;
89 * @brief Scroll-start/Scroll-end event callback
91 * @param event AtspiEvent
92 * @param user_data UNUSED
96 _scroll_event_cb(AtspiEvent *event, gpointer user_data)
101 int start_index, end_index;
105 gchar *role_name = atspi_accessible_get_role_name(event->source, NULL);
106 fprintf(stderr, "Event: %s: %d, obj: %p: role: %s\n",
107 event->type, event->detail1, event->source,
111 if (!strcmp(event->type, "object:scroll-start"))
113 DEBUG("Scrolling started");
114 tts_speak("Scrolling started", EINA_TRUE);
116 else if (!strcmp(event->type, "object:scroll-end"))
118 DEBUG("Scrolling finished");
119 tts_speak("Scrolling finished", EINA_FALSE);
120 get_realized_items_count((AtspiAccessible *)event->source, &start_index, &end_index);
121 _smart_notification_realized_items(start_index, end_index);
126 * @brief Initializer for smart notifications
130 void smart_notification_init(void)
132 DEBUG("Smart Notification init!");
134 AtspiEventListener *listener;
136 listener = atspi_event_listener_new(_scroll_event_cb, NULL, NULL);
137 atspi_event_listener_register(listener, "object:scroll-start", NULL);
138 atspi_event_listener_register(listener, "object:scroll-end", NULL);
140 haptic_module_init();
146 * @brief Smart notifications shutdown
149 void smart_notification_shutdown(void)
155 * @brief Smart notifications focus chain event handler
158 static void _smart_notification_focus_chain_end(void)
163 DEBUG(RED"Smart notification - FOCUS CHAIN END"RESET);
166 tone_player_start(TONE_TYPE_SUP_CONFIRM, SOUND_TYPE_MEDIA, 200, NULL);
170 * @brief Smart notifications realized items event handler
173 static void _smart_notification_realized_items(int start_idx, int end_idx)
178 if(start_idx == end_idx)
181 DEBUG(RED"Smart notification - Visible items notification"RESET);
185 snprintf(buf, sizeof(buf), ITEMS_NOTIFICATION, start_idx, end_idx);
187 tts_speak(strdup(buf), EINA_FALSE);