[screen reader] Code refactoring: navigator 11/89111/2 tizen-refactored-v2
authorLukasz Wlazly <l.wlazly@partner.samsung.com>
Fri, 9 Sep 2016 07:52:52 +0000 (09:52 +0200)
committerm.detko <m.detko@samsung.com>
Thu, 22 Sep 2016 10:45:24 +0000 (12:45 +0200)
Change-Id: I309397981b0ab1054228cab78e423d48b2546ced

include/navigator.h
include/screen_reader.h
src/main.c
src/navigator.c

index f9b69250a053fec8f0737cee24965cccc228d91b..9ae6a1a6a7a872f6a34c01c2f5e0d780cd930119 100644 (file)
@@ -1,3 +1,6 @@
+#ifndef NAVIGATOR_H_
+#define NAVIGATOR_H_
+
 #include <atspi/atspi.h>
 #include "screen_reader.h"
 
@@ -6,5 +9,22 @@
 extern bool read_description;
 extern bool haptic;
 
-void navigator_init(void);
-void navigator_shutdown(void);
+
+/**
+ * @brief Creates environment for navigation
+ * @description Initializes D-Bus Gesture Adapter, App Tracker, Window Tracker,
+ *              registers callback functions for gesture detection and highlight changing
+ *
+ * @note Initializes notification system if SCREEN_READER_TV is undefined
+ *
+ * @see app_tracker_init(), window_tracker_init(), smart_notification_init(), system_notifications_init()
+ */
+Navigator_Data *navigator_init(Service_Data *sd);
+
+/**
+ * @brief Closes all subservices opened in initialization
+ *
+ */
+void navigator_shutdown(Service_Data *sd);
+
+#endif //NAVIGATOR_H_
index da6ecac59c3ef6292d0801e4a63e6be9fdb80b18..106bf098e4d95d58d2d7a5cf084e3ccf94a00592 100644 (file)
@@ -26,47 +26,50 @@ typedef struct
 
 typedef enum
 {
-   read_as_xml,
-   read_as_plain,
-   dont_read
+       read_as_xml,
+       read_as_plain,
+       dont_read
 } Wrong_Validation_Reacction;
 
+typedef struct _Navigator_Data Navigator_Data;
+
 typedef struct _Service_Data
 {
-   //Set by vconf
-   bool run_service;
-   char display_language[LANGUAGE_NAME_SIZE];
-   char *tracking_signal_name;
-
-   //Set by tts
-   tts_h tts;
-   Eina_List *available_languages;
-
-   char *text_to_say_info;
-   char *current_value;
-   char *current_char;
-
-   //Actions to do when tts state is 'ready'
-   int _dbus_txt_readed;
-   bool say_text;
-   bool update_language_list;
-
-   //Set by spi
-   AtspiEventListener *state_changed_listener;
-   AtspiEventListener *value_changed_listener;
-   AtspiEventListener *caret_moved_listener;
-   AtspiEventListener *spi_listener;
-
-   AtspiAccessible  *currently_focused;
-   AtspiAccessible  *mouse_down_widget;
-   AtspiAccessible  *clicked_widget;
-
-   //Set by dbus
-   Eldbus_Proxy *proxy;
-   char **last_tokens;
-   char *available_requests;
-   char **available_apps;
-
+       Navigator_Data *navigator_data;
+
+       //Set by vconf
+       bool run_service;
+       char display_language[LANGUAGE_NAME_SIZE];
+       char *tracking_signal_name;
+
+       //Set by tts
+       tts_h tts;
+       Eina_List *available_languages;
+
+       char *text_to_say_info;
+       char *current_value;
+       char *current_char;
+
+       //Actions to do when tts state is 'ready'
+       int _dbus_txt_readed;
+       bool say_text;
+       bool update_language_list;
+
+       //Set by spi
+       AtspiEventListener *state_changed_listener;
+       AtspiEventListener *value_changed_listener;
+       AtspiEventListener *caret_moved_listener;
+       AtspiEventListener *spi_listener;
+
+       AtspiAccessible  *currently_focused;
+       AtspiAccessible  *mouse_down_widget;
+       AtspiAccessible  *clicked_widget;
+
+       //Set by dbus
+       Eldbus_Proxy *proxy;
+       char **last_tokens;
+       char *available_requests;
+       char **available_apps;
 } Service_Data;
 
 Service_Data *get_pointer_to_service_data_struct();
index e856ce1aaa1a45e57eb0b785f568f2080cfbe585..c0bfd04065164b19af764abf75e57819303a8072 100644 (file)
@@ -216,6 +216,8 @@ void set_signal_handler()
 
 static int app_create(void *data)
 {
+       Service_Data *sd = get_pointer_to_service_data_struct();
+
        elm_init(0, NULL);
        atspi_init();
        screen_reader_create_service(data);
@@ -226,7 +228,12 @@ static int app_create(void *data)
        }
 #ifndef SCREEN_READER_TV
        //screen_reader_gestures_init();
-       navigator_init();
+       sd->navigator_data = navigator_init(sd);
+       if (sd->navigator_data == NULL) {
+               ERROR("Navigator not initialized");
+               return -1;
+       }
+
        keyboard_tracker_init();
 #endif
        screen_reader_switch_enabled_set(EINA_TRUE);
@@ -236,10 +243,12 @@ static int app_create(void *data)
 
 static int app_terminate(void *data)
 {
+       Service_Data *sd = get_pointer_to_service_data_struct();
+
        DEBUG("screen reader terminating");
 #ifndef SCREEN_READER_TV
        DEBUG("terminate navigator");
-       navigator_shutdown();
+       navigator_shutdown(sd);
        DEBUG("terminate gestures");
        //screen_reader_gestures_shutdown();
 #endif
index 14f433b3eb955ae093ad1142057b623122604e86..b7a869760040a0f41f3a464401cdaec235f2b009 100644 (file)
@@ -75,8 +75,9 @@ static void on_window_activate(void *data, AtspiAccessible * window);
 static void _highlight_on_slider(Eina_Bool is_slider);
 
 typedef struct {
-       int x, y;
-} last_focus_t;
+       int x;
+       int y;
+} point_t;
 
 /* The Highlight_Type will be used for access object working for embedded
 toolkit such as Dali does not support at-spi interface. This kind of work
@@ -89,27 +90,26 @@ typedef enum {
        HIGHLIGHT_PREV
 } Highlight_Type;
 
-static last_focus_t gesture_start_p = { -1, -1 };
-static last_focus_t last_focus = { -1, -1 };
-static last_focus_t last_pos = { -1, -1 };
+struct _Navigator_Data {
+       point_t gesture_start_p;
+       point_t last_focus;
+       point_t last_pos;
+       AtspiAccessible *current_obj;
+       AtspiComponent *current_comp;
+       AtspiAccessible *top_window;
+       bool prepared;
+       int counter;
+       int last_hover_event_time;
+       AtspiAccessible *focused_object;
+       bool auto_review_on;
+};
 
-static AtspiAccessible *current_obj;
-static AtspiComponent *current_comp = NULL;
-static AtspiAccessible *top_window;
 static FlatNaviContext *context;
-static bool prepared = false;
-static int counter = 0;
-int _last_hover_event_time = -1;
+
 extern bool read_description;
 extern bool haptic;
 extern bool sound_feedback;
 
-static struct {
-       AtspiAccessible *focused_object;
-       bool auto_review_on;
-} s_auto_review = {
-.focused_object = NULL,.auto_review_on = false};
-
 char *state_to_char(AtspiStateType state)
 {
        switch (state) {
@@ -1083,28 +1083,31 @@ static Eina_Bool _highlight_access_object(AtspiAccessible *obj, Highlight_Type h
        return _do_action(obj, expected_action);
 }
 
-static void _current_highlight_object_set(AtspiAccessible * obj, Highlight_Type h_type)
+static void _current_highlight_object_set(Navigator_Data *nd, AtspiAccessible * obj, Highlight_Type h_type)
 {
        DEBUG("START");
+
        GError *err = NULL;
        gchar *role_name = NULL;
        AtspiRole role = -1;
 
        if (!obj) {
                DEBUG("Clearing highlight object");
-               current_obj = NULL;
-               if (current_comp) {
-                       atspi_component_clear_highlight(current_comp, &err);
-                       g_object_unref(current_comp);
-                       current_comp = NULL;
+               nd->current_obj = NULL;
+               if (nd->current_comp) {
+                       atspi_component_clear_highlight(nd->current_comp, &err);
+                       g_object_unref(nd->current_comp);
+                       nd->current_comp = NULL;
                }
                return;
        }
-       if (current_obj == obj) {
+
+       if (nd->current_obj == obj) {
                DEBUG("Object already highlighted");
                DEBUG("Object name:%s", atspi_accessible_get_name(obj, NULL));
                return;
        }
+
        if (obj && ATSPI_IS_COMPONENT(obj)) {
                DEBUG("OBJ WITH COMPONENT");
                AtspiComponent *comp = atspi_accessible_get_component_iface(obj);
@@ -1116,8 +1119,8 @@ static void _current_highlight_object_set(AtspiAccessible * obj, Highlight_Type
                        g_free(role_name);
                        return;
                }
-               if (current_comp) {
-                       atspi_component_clear_highlight(current_comp, &err);
+               if (nd->current_comp) {
+                       atspi_component_clear_highlight(nd->current_comp, &err);
                }
 
                if (sound_feedback) {
@@ -1145,7 +1148,7 @@ static void _current_highlight_object_set(AtspiAccessible * obj, Highlight_Type
                        }
                        atspi_component_grab_highlight(comp, &err);
                }
-               current_comp = comp;
+               nd->current_comp = comp;
                GERROR_CHECK(err)
 
                Eina_Bool is_paused = tts_pause_get();
@@ -1153,8 +1156,8 @@ static void _current_highlight_object_set(AtspiAccessible * obj, Highlight_Type
                        tts_stop_set();
                        tts_pause_set(EINA_FALSE);
                }
-               g_clear_object(&current_obj);
-               current_obj = obj;
+               g_clear_object(&nd->current_obj);
+               nd->current_obj = obj;
                char *text_to_speak = NULL;
                text_to_speak = generate_what_to_read(obj);
                DEBUG("SPEAK:%s", text_to_speak);
@@ -1204,26 +1207,27 @@ void test_debug(AtspiAccessible * current_widget)
        g_object_unref(parent);
 }
 
-static void _focus_widget(Gesture_Info * info)
+static void _focus_widget(Navigator_Data *nd, Gesture_Info *info)
 {
        DEBUG("START");
 
-       if ((last_focus.x == info->x_beg) && (last_focus.y == info->y_beg))
+       if ((nd->last_focus.x == info->x_beg) && (nd->last_focus.y == info->y_beg))
                return;
 
        AtspiAccessible *obj = NULL;
        if (flat_navi_context_current_at_x_y_set(context, info->x_beg, info->y_beg, &obj)) {
-               last_focus.x = info->x_beg;
-               last_focus.y = info->y_beg;
-               _current_highlight_object_set(obj, HIGHLIGHT_POINT);
+               nd->last_focus.x = info->x_beg;
+               nd->last_focus.y = info->y_beg;
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_POINT);
        }
 
        DEBUG("END");
 }
 
-static void _focus_next(void)
+static void _focus_next(Navigator_Data *nd)
 {
        DEBUG("START");
+
        AtspiAccessible *obj;
        if (!context) {
                ERROR("No navigation context created");
@@ -1232,15 +1236,16 @@ static void _focus_next(void)
 
        obj = flat_navi_context_next(context);
        if (obj)
-               _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_FIRST);
        else
                DEBUG("Next widget not found. Abort");
        DEBUG("END");
 }
 
-static void _focus_next_visible(void)
+static void _focus_next_visible(Navigator_Data *nd)
 {
        DEBUG("START");
+
        AtspiAccessible *obj;
        AtspiStateSet *ss = NULL;
        Eina_Bool visible = EINA_FALSE;
@@ -1261,13 +1266,13 @@ static void _focus_next_visible(void)
        while (obj && !visible);
 
        if (obj)
-               _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_FIRST);
        else
                DEBUG("Next widget not found. Abort");
        DEBUG("END");
 }
 
-static void _focus_prev_visible(void)
+static void _focus_prev_visible(Navigator_Data *nd)
 {
        AtspiAccessible *obj;
        AtspiStateSet *ss = NULL;
@@ -1288,12 +1293,12 @@ static void _focus_prev_visible(void)
        while (obj && !visible);
 
        if (obj)
-               _current_highlight_object_set(obj, HIGHLIGHT_LAST);
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_LAST);
        else
                DEBUG("Previous widget not found. Abort");
 }
 
-static void _focus_prev(void)
+static void _focus_prev(Navigator_Data *nd)
 {
        AtspiAccessible *obj;
        if (!context) {
@@ -1303,26 +1308,26 @@ static void _focus_prev(void)
 
        obj = flat_navi_context_prev(context);
        if (obj)
-               _current_highlight_object_set(obj, HIGHLIGHT_LAST);
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_LAST);
        else
                DEBUG("Previous widget not found. Abort");
 }
 
-static void _caret_move_beg(void)
+static void _caret_move_beg(Navigator_Data *nd)
 {
        AtspiAccessible *current_widget = NULL;
        AtspiText *text_interface;
        gboolean ret;
        GError *err = NULL;
 
-       if (!current_obj)
+       if (!nd->current_obj)
                return;
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
                current_widget = relation;
        else
-               current_widget = current_obj;
+               current_widget = nd->current_obj;
 
        text_interface = atspi_accessible_get_text_iface(current_widget);
 
@@ -1336,8 +1341,8 @@ static void _caret_move_beg(void)
                        DEBUG("Caret position increment done");
                        gchar *text = atspi_text_get_text(text_interface, 0, 1, NULL);
                        DEBUG("SPEAK:%s", text);
-                       tts_speak_customized(text, EINA_TRUE, EINA_TRUE, current_obj);
-                       tts_speak_customized(_("IDS_TEXT_BEGIN"), EINA_FALSE, EINA_TRUE, current_obj);
+                       tts_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj);
+                       tts_speak_customized(_("IDS_TEXT_BEGIN"), EINA_FALSE, EINA_TRUE, nd->current_obj);
                        g_free(text);
                } else {
                        ERROR("Caret position increment error");
@@ -1347,21 +1352,21 @@ static void _caret_move_beg(void)
                ERROR("No text interface supported!");
 }
 
-static void _caret_move_end(void)
+static void _caret_move_end(Navigator_Data *nd)
 {
        AtspiAccessible *current_widget = NULL;
        AtspiText *text_interface;
        gboolean ret;
        GError *err = NULL;
 
-       if (!current_obj)
+       if (nd->current_obj == NULL)
                return;
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
                current_widget = relation;
        else
-               current_widget = current_obj;
+               current_widget = nd->current_obj;
 
        text_interface = atspi_accessible_get_text_iface(current_widget);
 
@@ -1374,14 +1379,14 @@ static void _caret_move_end(void)
                if (ret) {
                        DEBUG("Caret position increment done");
                        DEBUG("SPEAK:%s", _("IDS_TEXT_END"));
-                       tts_speak_customized(_("IDS_TEXT_END"), EINA_TRUE, EINA_TRUE, current_obj);
+                       tts_speak_customized(_("IDS_TEXT_END"), EINA_TRUE, EINA_TRUE, nd->current_obj);
                } else
                        ERROR("Caret position to end error");
                g_object_unref(text_interface);
        }
 }
 
-static void _caret_move_forward(void)
+static void _caret_move_forward(Navigator_Data *nd)
 {
        AtspiAccessible *current_widget = NULL;
        AtspiText *text_interface;
@@ -1390,14 +1395,14 @@ static void _caret_move_forward(void)
        int offset_pos;
        gchar *text;
        GError *err = NULL;
-       if (!current_obj)
+       if (nd->current_obj == NULL)
                return;
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
                current_widget = relation;
        else
-               current_widget = current_obj;
+               current_widget = nd->current_obj;
 
        text_interface = atspi_accessible_get_text_iface(current_widget);
 
@@ -1417,10 +1422,10 @@ static void _caret_move_forward(void)
                        DEBUG("Current caret offset:%d", current_offset);
                        if (offset_pos == atspi_text_get_character_count(text_interface, NULL)) {
                                DEBUG("SPEAK:%s", _("IDS_TEXT_END"));
-                               tts_speak_customized(_("IDS_TEXT_END"), EINA_FALSE, EINA_TRUE, current_obj);
+                               tts_speak_customized(_("IDS_TEXT_END"), EINA_FALSE, EINA_TRUE, nd->current_obj);
                        } else {
                                DEBUG("SPEAK:%s", text);
-                               tts_speak_customized(text, EINA_TRUE, EINA_TRUE, current_obj);
+                               tts_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj);
                        }
                        g_free(text);
                } else {
@@ -1433,7 +1438,7 @@ static void _caret_move_forward(void)
 
 }
 
-static void _caret_move_backward(void)
+static void _caret_move_backward(Navigator_Data *nd)
 {
        AtspiAccessible *current_widget = NULL;
        AtspiText *text_interface;
@@ -1443,14 +1448,14 @@ static void _caret_move_backward(void)
        GError *err = NULL;
        gboolean ret;
 
-       if (!current_obj)
+       if (nd->current_obj == NULL)
                return;
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
                current_widget = relation;
        else
-               current_widget = current_obj;
+               current_widget = nd->current_obj;
 
        GERROR_CHECK(err)
 
@@ -1470,11 +1475,11 @@ static void _caret_move_backward(void)
                        DEBUG("Caret position decrement done");
                        DEBUG("Current caret position:%d", offset_pos);
                        DEBUG("SPEAK:%s", text);
-                       tts_speak_customized(text, EINA_TRUE, EINA_TRUE, current_obj);
+                       tts_speak_customized(text, EINA_TRUE, EINA_TRUE, nd->current_obj);
                        g_free(text);
                        if (offset_pos == 0) {
                                DEBUG("SPEAK:%s", _("IDS_TEXT_BEGIN"));
-                               tts_speak_customized(_("IDS_TEXT_BEGIN"), EINA_FALSE, EINA_TRUE, current_obj);
+                               tts_speak_customized(_("IDS_TEXT_BEGIN"), EINA_FALSE, EINA_TRUE, nd->current_obj);
                        }
                } else {
                        ERROR("Caret position decrement error");
@@ -1485,19 +1490,19 @@ static void _caret_move_backward(void)
        return;
 }
 
-static void _value_inc(void)
+static void _value_inc(Navigator_Data *nd)
 {
        AtspiAccessible *current_widget = NULL;
        GError *err = NULL;
 
-       if (!current_obj)
+       if (nd->current_obj == NULL)
                return;
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
                current_widget = relation;
        else
-               current_widget = current_obj;
+               current_widget = nd->current_obj;
 
        AtspiValue *value_interface = atspi_accessible_get_value_iface(current_widget);
 
@@ -1519,19 +1524,19 @@ static void _value_inc(void)
        ERROR("No value interface supported!\n");
 }
 
-static void _value_dec(void)
+static void _value_dec(Navigator_Data *nd)
 {
        AtspiAccessible *current_widget = NULL;
        GError *err = NULL;
 
-       if (!current_obj)
+       if (nd->current_obj == NULL)
                return;
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
                current_widget = relation;
        else
-               current_widget = current_obj;
+               current_widget = nd->current_obj;
 
        AtspiValue *value_interface = atspi_accessible_get_value_iface(current_widget);
 
@@ -1553,7 +1558,7 @@ static void _value_dec(void)
        ERROR("No value interface supported!\n");
 }
 
-static void _activate_widget(void)
+static void _activate_widget(Navigator_Data *nd)
 {
        //activate the widget
        //only if activate mean click
@@ -1575,19 +1580,19 @@ static void _activate_widget(void)
        Eina_Bool activate_found = EINA_FALSE;
        AtspiRole role = ATSPI_ROLE_INVALID;
 
-       if (!current_obj)
+       if (nd->current_obj == NULL)
                return;
 
-       if (!_widget_has_state(current_obj, ATSPI_STATE_ENABLED)) {
+       if (!_widget_has_state(nd->current_obj, ATSPI_STATE_ENABLED)) {
                DEBUG("Widget is disabled so cannot be activated");
                return;
        }
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
                current_widget = relation;
        else
-               current_widget = current_obj;
+               current_widget = nd->current_obj;
 
        role = atspi_accessible_get_role(current_widget, NULL);
        if (role == ATSPI_ROLE_SLIDER) {
@@ -1720,13 +1725,13 @@ _find_scrollable_ancestor_at_xy(int x, int y)
    AtspiRect *rect;
    GError *err = NULL;
 
-   if (!top_window || !ATSPI_IS_COMPONENT(top_window))
+   if (!nd->top_window || !ATSPI_IS_COMPONENT(nd->top_window))
      {
         DEBUG("No active window detected or no AtspiComponent interface available");
         return NULL;
      }
 
-   rect = atspi_component_get_extents(ATSPI_COMPONENT(top_window), ATSPI_COORD_TYPE_SCREEN, &err);
+   rect = atspi_component_get_extents(ATSPI_COMPONENT(nd->top_window), ATSPI_COORD_TYPE_SCREEN, &err);
    GERROR_CHECK(err)
    if (!rect)
      {
@@ -1743,7 +1748,7 @@ _find_scrollable_ancestor_at_xy(int x, int y)
         return NULL;
      }
 
-   ret = atspi_component_get_accessible_at_point(ATSPI_COMPONENT(top_window), x, y, ATSPI_COORD_TYPE_SCREEN, &err);
+   ret = atspi_component_get_accessible_at_point(ATSPI_COMPONENT(nd->top_window), x, y, ATSPI_COORD_TYPE_SCREEN, &err);
    GERROR_CHECK(err)
    if (!ret)
      {
@@ -1753,7 +1758,7 @@ _find_scrollable_ancestor_at_xy(int x, int y)
 gchar *name;
 gchar *role;
    // find accessible object with Scrollable interface
-   while (ret && (ret != top_window))
+   while (ret && (ret != nd->top_window))
      {
        name = atspi_accessible_get_name(ret, &err);
        GERROR_CHECK(err)
@@ -1844,14 +1849,25 @@ static void _widget_scroll_end(Gesture_Info *gi)
 }
 */
 
-static void _widget_scroll(Gesture_Info * gi)
+static void _widget_scroll(Navigator_Data *nd, Gesture_Info *gi)
 {
        DEBUG("Recognized gesture state: %d", gi->state);
        int x_diff, y_diff;
+
+       if (nd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
+       if (gi == NULL) {
+               ERROR("NULL gesture");
+               return;
+       }
+
        if (gi->state == 0) {
-               DEBUG("save coordinates %d %d", gesture_start_p.x, gesture_start_p.y);
-               gesture_start_p.x = gi->x_beg;
-               gesture_start_p.y = gi->y_beg;
+               DEBUG("save coordinates %d %d", nd->gesture_start_p.x, nd->gesture_start_p.y);
+               nd->gesture_start_p.x = gi->x_beg;
+               nd->gesture_start_p.y = gi->y_beg;
        }
 
        if (gi->state != 2) {
@@ -1861,48 +1877,48 @@ static void _widget_scroll(Gesture_Info * gi)
 
        AtspiAccessible *obj = NULL;
        obj = flat_navi_context_current_get(context);
-       if (!obj) {
+       if (obj == NULL) {
                ERROR("No context");
                return;
        }
 
        AtspiStateSet *ss = atspi_accessible_get_state_set(obj);
-       if (!ss) {
+       if (ss == NULL) {
                ERROR("no stetes");
                return;
        }
 
        if (!atspi_state_set_contains(ss, ATSPI_STATE_SHOWING)) {
                DEBUG("current context do not have visible state, swith to next/prev %d %d", gi->x_end,gi->y_end);
-               x_diff = (gi->x_end - gesture_start_p.x);
-               y_diff = (gi->y_end - gesture_start_p.y);
+               x_diff = (gi->x_end - nd->gesture_start_p.x);
+               y_diff = (gi->y_end - nd->gesture_start_p.y);
                DEBUG("%d %d", y_diff, x_diff);
                if (abs(y_diff) >= abs(x_diff)) {
                        if (y_diff > 0) {
                                DEBUG("PREVIOUS");
-                               _focus_prev_visible();
+                               _focus_prev_visible(nd);
                        }
                        else {
                                DEBUG("NEXT");
-                               _focus_next_visible();
+                               _focus_next_visible(nd);
                        }
                }
                else {
                        if (x_diff > 0) {
                                DEBUG("PREVIOUS");
-                               _focus_prev_visible();
+                               _focus_prev_visible(nd);
                        }
                        else {
                                DEBUG("NEXT");
-                               _focus_next_visible();
+                               _focus_next_visible(nd);
                        }
                }
        }
        else {
                DEBUG("Read Highlighted object");
                char *text_to_speak = NULL;
-               text_to_speak = generate_what_to_read(current_obj);
-               tts_speak_customized(text_to_speak, EINA_TRUE, EINA_TRUE, current_obj);
+               text_to_speak = generate_what_to_read(nd->current_obj);
+               tts_speak_customized(text_to_speak, EINA_TRUE, EINA_TRUE, nd->current_obj);
        }
 
        DEBUG("end");
@@ -1942,27 +1958,32 @@ static void _set_pause(void)
        DEBUG("END");
 }
 
-void auto_review_highlight_set(void)
+void auto_review_highlight_set(Navigator_Data *nd)
 {
+       if (nd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
        AtspiAccessible *obj = flat_navi_context_next(context);
 
        DEBUG("START");
 
        if (!obj) {
                DEBUG("obj == NULL");
-               s_auto_review.auto_review_on = false;
+               nd->auto_review_on = false;
                return;
        } else if (obj == flat_navi_context_last_get(context)) {
                DEBUG("obj == flat_navi_context_last_get()");
-               s_auto_review.auto_review_on = false;
+               nd->auto_review_on = false;
        }
 
-       _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
+       _current_highlight_object_set(nd, obj, HIGHLIGHT_FIRST);
 
        DEBUG("END");
 }
 
-void auto_review_highlight_top(void)
+void auto_review_highlight_top(Navigator_Data *nd)
 {
        DEBUG("START");
        char *text_to_speak = NULL;
@@ -1970,7 +1991,7 @@ void auto_review_highlight_top(void)
        AtspiAccessible *first = flat_navi_context_first(context);
 
        if (first != obj) {
-               _current_highlight_object_set(first, HIGHLIGHT_FIRST);
+               _current_highlight_object_set(nd, first, HIGHLIGHT_FIRST);
        } else {
                text_to_speak = generate_what_to_read(obj);
                DEBUG("Text to speak: %s", text_to_speak);
@@ -1981,47 +2002,55 @@ void auto_review_highlight_top(void)
        DEBUG("END");
 }
 
-static void _on_auto_review_stop(void)
+static void _on_auto_review_stop(Navigator_Data *nd)
 {
        DEBUG("START");
-       s_auto_review.auto_review_on = false;
+       nd->auto_review_on = false;
        DEBUG("END");
 }
 
-static void _on_utterance(void)
+static void _on_utterance()
 {
        DEBUG("START");
-       DEBUG("s_auto_review.auto_review_on == %d", s_auto_review.auto_review_on);
 
-       if (s_auto_review.auto_review_on) {
-               auto_review_highlight_set();
+       Service_Data *sd = get_pointer_to_service_data_struct();
+
+       if (sd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
+       DEBUG("sd->navigator_data->auto_review_on == %d", sd->navigator_data->auto_review_on);
+
+       if (sd->navigator_data->auto_review_on) {
+               auto_review_highlight_set(sd->navigator_data);
        }
        DEBUG("END");
 }
 
-static void _review_from_current(void)
+static void _review_from_current(Navigator_Data *nd)
 {
        DEBUG("START");
 
-       s_auto_review.focused_object = flat_navi_context_current_get(context);
-       s_auto_review.auto_review_on = true;
-       auto_review_highlight_set();
+       nd->focused_object = flat_navi_context_current_get(context);
+       nd->auto_review_on = true;
+       auto_review_highlight_set(nd);
 
        DEBUG("END");
 }
 
-static void _review_from_top()
+static void _review_from_top(Navigator_Data *nd)
 {
        DEBUG("START");
 
-       s_auto_review.focused_object = flat_navi_context_current_get(context);
-       s_auto_review.auto_review_on = true;
-       auto_review_highlight_top();
+       nd->focused_object = flat_navi_context_current_get(context);
+       nd->auto_review_on = true;
+       auto_review_highlight_top(nd);
 
        DEBUG("END");
 }
 
-static void _direct_scroll_back(void)
+static void _direct_scroll_back(Navigator_Data *nd)
 {
        DEBUG("ONE_FINGER_FLICK_LEFT_RETURN");
        if (!context) {
@@ -2074,13 +2103,13 @@ static void _direct_scroll_back(void)
                if (flat_navi_context_current_set(context, obj)) {
                        DEBUG("current obj set");
                }
-               _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_FIRST);
        }
        g_object_unref(parent);
        g_object_unref(current);
 }
 
-static void _direct_scroll_forward(void)
+static void _direct_scroll_forward(Navigator_Data *nd)
 {
        DEBUG("ONE_FINGER_FLICK_RIGHT_RETURN");
 
@@ -2134,13 +2163,13 @@ static void _direct_scroll_forward(void)
                if (flat_navi_context_current_set(context, obj)) {
                        DEBUG("current obj set");
                }
-               _current_highlight_object_set(obj, HIGHLIGHT_LAST);
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_LAST);
        }
        g_object_unref(parent);
        g_object_unref(current);
 }
 
-static void _direct_scroll_to_first(void)
+static void _direct_scroll_to_first(Navigator_Data *nd)
 {
        DEBUG("ONE_FINGER_FLICK_UP_RETURN");
        if (!context) {
@@ -2149,13 +2178,13 @@ static void _direct_scroll_to_first(void)
        }
        AtspiAccessible *obj = flat_navi_context_first(context);
        if (obj)
-               _current_highlight_object_set(obj, HIGHLIGHT_FIRST);
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_FIRST);
        else
                DEBUG("First widget not found. Abort");
        DEBUG("END");
 }
 
-static void _direct_scroll_to_last(void)
+static void _direct_scroll_to_last(Navigator_Data *nd)
 {
        DEBUG("ONE_FINGER_FLICK_DOWN_RETURN");
        if (!context) {
@@ -2164,25 +2193,25 @@ static void _direct_scroll_to_last(void)
        }
        AtspiAccessible *obj = flat_navi_context_last(context);
        if (obj)
-               _current_highlight_object_set(obj, HIGHLIGHT_LAST);
+               _current_highlight_object_set(nd, obj, HIGHLIGHT_LAST);
        else
                DEBUG("Last widget not found. Abort");
        DEBUG("END");
 }
 
-static Eina_Bool _has_value(void)
+static Eina_Bool _has_value(Navigator_Data *nd)
 {
        DEBUG("START");
        AtspiAccessible *obj = NULL;
 
-       if (!current_obj)
+       if (nd->current_obj == NULL)
                return EINA_FALSE;
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
                obj = relation;
        else
-               obj = current_obj;
+               obj = nd->current_obj;
 
        if (!obj)
                return EINA_FALSE;
@@ -2200,13 +2229,13 @@ static Eina_Bool _has_value(void)
        return EINA_FALSE;
 }
 
-static Eina_Bool _is_enabled(void)
+static Eina_Bool _is_enabled(Navigator_Data *nd)
 {
-       if (!current_obj) {
+       if (nd->current_obj == NULL) {
                return EINA_FALSE;
        }
 
-       AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+       AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
        if(relation)
        {
                Eina_Bool ret = _widget_has_state(relation, ATSPI_STATE_ENABLED);
@@ -2215,7 +2244,7 @@ static Eina_Bool _is_enabled(void)
        }
        else
        {
-               return _widget_has_state(current_obj, ATSPI_STATE_ENABLED);
+               return _widget_has_state(nd->current_obj, ATSPI_STATE_ENABLED);
        }
 }
 
@@ -2324,10 +2353,20 @@ void end_scroll(int x, int y)
 #endif
 }
 
-static void _move_slider(Gesture_Info * gi)
+static void _move_slider(Navigator_Data *nd, Gesture_Info *gi)
 {
        DEBUG("ONE FINGER DOUBLE TAP AND HOLD");
 
+       if (nd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
+       if (gi == NULL) {
+               ERROR("NULL gesture");
+               return;
+       }
+
        if (!context) {
                ERROR("No navigation context created");
                return;
@@ -2336,11 +2375,11 @@ static void _move_slider(Gesture_Info * gi)
        AtspiAccessible *obj = NULL;
        AtspiComponent *comp = NULL;
        AtspiRect *rect = NULL;
-       obj = current_obj;
+       obj = nd->current_obj;
 
        if (!obj) {
                DEBUG("no object");
-               prepared = false;
+               nd->prepared = false;
                return;
        }
 
@@ -2350,7 +2389,7 @@ static void _move_slider(Gesture_Info * gi)
 
        if (!_is_slider(obj)) {
                DEBUG("Object is not a slider");
-               prepared = false;
+               nd->prepared = false;
                if(relation)
                        g_object_unref(relation);
                return;
@@ -2358,7 +2397,7 @@ static void _move_slider(Gesture_Info * gi)
 
        if (!_widget_has_state(obj, ATSPI_STATE_ENABLED)) {
                DEBUG("Slider is disabled");
-               prepared = false;
+               nd->prepared = false;
                if(relation)
                        g_object_unref(relation);
                return;
@@ -2368,7 +2407,7 @@ static void _move_slider(Gesture_Info * gi)
                comp = atspi_accessible_get_component_iface(obj);
                if (!comp) {
                        ERROR("that slider do not have component interface");
-                       prepared = false;
+                       nd->prepared = false;
                        if(relation)
                                g_object_unref(relation);
                        return;
@@ -2382,28 +2421,28 @@ static void _move_slider(Gesture_Info * gi)
        }
 
        if (gi->state == 1) {
-               counter++;
-               DEBUG("SCROLLING but not meet counter:%d", counter);
-                       if (counter >= GESTURE_LIMIT) {
-                       counter = 0;
+               nd->counter++;
+               DEBUG("SCROLLING but not meet counter:%d", nd->counter);
+                       if (nd->counter >= GESTURE_LIMIT) {
+                       nd->counter = 0;
                        DEBUG("Scroll on point %d %d", gi->x_end, gi->y_end);
-                       if (last_pos.x != -1) {
-                               if (last_pos.x > gi->x_end)
-                                       _value_dec();
+                       if (nd->last_pos.x != -1) {
+                               if (nd->last_pos.x > gi->x_end)
+                                       _value_dec(nd);
                                else
-                                       _value_inc();
+                                       _value_inc(nd);
                        }
-                       last_pos.x = gi->x_end;
-                       last_pos.y = gi->y_end;
+                       nd->last_pos.x = gi->x_end;
+                       nd->last_pos.y = gi->y_end;
                }
        }
 
        if (gi->state == 2) {
                DEBUG("state == 2");
-               prepared = false;
+               nd->prepared = false;
                _highlight_on_slider(EINA_FALSE);
-               last_pos.x = -1;
-               last_pos.y = -1;
+               nd->last_pos.x = -1;
+               nd->last_pos.y = -1;
        }
 
        if(relation)
@@ -2499,6 +2538,13 @@ static Eina_Bool _check_access_object_internal(Highlight_Type h_type)
 
 static void on_gesture_detected(void *data, const Eldbus_Message *msg)
 {
+       Navigator_Data *nd = (Navigator_Data *)data;
+
+       if (nd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
 #ifdef X11_ENABLED
        Ecore_X_Window keyboard_win;
 #else
@@ -2522,16 +2568,16 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
        DEBUG("Incoming gesture name is %s : %d %d %d %d %d", _gesture_enum_to_string(info->type),
              info->x_beg, info->y_beg, info->x_end, info->y_end, info->state);
 
-       _on_auto_review_stop();
+       _on_auto_review_stop(nd);
 
        if (info->type == ONE_FINGER_SINGLE_TAP && info->state == 3) {
                DEBUG("One finger single tap aborted");
-               prepared = true;
+               nd->prepared = true;
 
                if (sound_feedback)
                        smart_notification(LONG_PRESS_NOTIFICATION_EVENT, 0, 0);
 
-               AtspiAccessible *relation = flat_navi_get_object_in_relation(current_obj, ATSPI_RELATION_CONTROLLER_FOR);
+               AtspiAccessible *relation = flat_navi_get_object_in_relation(nd->current_obj, ATSPI_RELATION_CONTROLLER_FOR);
                if(relation)
                {
                        if (_is_slider(relation))
@@ -2541,25 +2587,25 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
                }
                else
                {
-                       if (_is_slider(current_obj))
+                       if (_is_slider(nd->current_obj))
                                _highlight_on_slider(EINA_TRUE);
-                       _send_highlighted_object_info(current_obj);
+                       _send_highlighted_object_info(nd->current_obj);
                }
        }
 
        switch (info->type) {
        case ONE_FINGER_HOVER:
-               if (prepared) {
+               if (nd->prepared) {
                        DEBUG("Prepare to move slider");
-                       _move_slider(info);
+                       _move_slider(nd, info);
                } else {
-                       if (_last_hover_event_time < 0)
-                               _last_hover_event_time = info->event_time;
-               //info->event_time and _last_hover_event_time contain timestamp in ms.
+                       if (nd->last_hover_event_time < 0)
+                               nd->last_hover_event_time = info->event_time;
+               //info->event_time and last_hover_event_time contain timestamp in ms.
                //RETURN so we do not handle all incoming event
-                       if ((info->event_time - _last_hover_event_time) < ONGOING_HOVER_GESTURE_INTERPRETATION_INTERVAL && info->state == 1)
+                       if ((info->event_time - nd->last_hover_event_time) < ONGOING_HOVER_GESTURE_INTERPRETATION_INTERVAL && info->state == 1)
                                return;
-                       _last_hover_event_time = info->state != 1 ? -1 : info->event_time;
+                       nd->last_hover_event_time = info->state != 1 ? -1 : info->event_time;
 #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)) {
@@ -2574,41 +2620,41 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
                                        break;
                                }
 #endif
-                       _focus_widget(info);
+                       _focus_widget(nd, info);
                }
                break;
        case TWO_FINGERS_HOVER:
-               _widget_scroll(info);
+               _widget_scroll(nd, info);
                break;
        case ONE_FINGER_FLICK_LEFT:
                if (_check_access_object_internal(HIGHLIGHT_PREV)) break;
-               _focus_prev();
+               _focus_prev(nd);
                if (_is_index_item())
-                       _activate_widget();
+                       _activate_widget(nd);
 
                break;
        case ONE_FINGER_FLICK_RIGHT:
                if (_check_access_object_internal(HIGHLIGHT_NEXT)) break;
-               _focus_next();
+               _focus_next(nd);
                if (_is_index_item())
-                       _activate_widget();
+                       _activate_widget(nd);
 
                break;
        case ONE_FINGER_FLICK_UP:
                if (_is_active_entry())
-                       _caret_move_backward();
-               else if (_has_value() && _is_enabled())
-                       _value_inc();
+                       _caret_move_backward(nd);
+               else if (_has_value(nd) && _is_enabled(nd))
+                       _value_inc(nd);
                else
-                       _focus_prev();
+                       _focus_prev(nd);
                break;
        case ONE_FINGER_FLICK_DOWN:
                if (_is_active_entry())
-                       _caret_move_forward();
-               else if (_has_value() && _is_enabled())
-                       _value_dec();
+                       _caret_move_forward(nd);
+               else if (_has_value(nd) && _is_enabled(nd))
+                       _value_dec(nd);
                else
-                       _focus_next();
+                       _focus_next(nd);
                break;
        case ONE_FINGER_SINGLE_TAP:
 #if defined(ELM_ACCESS_KEYBOARD) && defined(X11_ENABLED)
@@ -2625,8 +2671,8 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
                                break;
                        }
 #endif
-               if (!prepared)
-                       _focus_widget(info);
+               if (!nd->prepared)
+                       _focus_widget(nd, info);
                break;
        case ONE_FINGER_DOUBLE_TAP:
 #if defined(ELM_ACCESS_KEYBOARD) && defined(X11_ENABLED)
@@ -2643,7 +2689,7 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
                                break;
                        }
 #endif
-               _activate_widget();
+               _activate_widget(nd);
                break;
        case TWO_FINGERS_SINGLE_TAP:
                _set_pause();
@@ -2657,10 +2703,10 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
 #endif
                break;
        case THREE_FINGERS_SINGLE_TAP:
-               _review_from_top();
+               _review_from_top(nd);
                break;
        case THREE_FINGERS_DOUBLE_TAP:
-               _review_from_current();
+               _review_from_current(nd);
                break;
        case THREE_FINGERS_FLICK_DOWN:
                _quickpanel_change_state(QUICKPANEL_DOWN);
@@ -2669,22 +2715,22 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
                _quickpanel_change_state(QUICKPANEL_UP);
                break;
        case ONE_FINGER_FLICK_LEFT_RETURN:
-               _direct_scroll_back();
+               _direct_scroll_back(nd);
                break;
        case ONE_FINGER_FLICK_RIGHT_RETURN:
-               _direct_scroll_forward();
+               _direct_scroll_forward(nd);
                break;
        case ONE_FINGER_FLICK_UP_RETURN:
                if (_is_active_entry())
-                       _caret_move_beg();
+                       _caret_move_beg(nd);
                else
-                       _direct_scroll_to_first();
+                       _direct_scroll_to_first(nd);
                break;
        case ONE_FINGER_FLICK_DOWN_RETURN:
                if (_is_active_entry())
-                       _caret_move_end();
+                       _caret_move_end(nd);
                else
-                       _direct_scroll_to_last();
+                       _direct_scroll_to_last(nd);
                break;
        default:
                DEBUG("Gesture type %d not handled in switch", info->type);
@@ -2696,6 +2742,13 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
 
 static void _view_content_changed(AtspiAccessible * root, void *user_data)
 {
+       Navigator_Data *nd = (Navigator_Data *)user_data;
+
+       if (nd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
        AtspiRole role = -1;
 
        if (flat_navi_is_valid(context, root))
@@ -2713,7 +2766,7 @@ static void _view_content_changed(AtspiAccessible * root, void *user_data)
                if(role == ATSPI_ROLE_PAGE_TAB ||       //add more roles...
                        role == ATSPI_ROLE_PAGE_TAB_LIST)
                {
-                       _current_highlight_object_set(flat_navi_context_current_get(context), HIGHLIGHT_FIRST);
+                       _current_highlight_object_set(nd, flat_navi_context_current_get(context), HIGHLIGHT_FIRST);
                }
                else
                {
@@ -2728,7 +2781,7 @@ static void _view_content_changed(AtspiAccessible * root, void *user_data)
                break;
        case ATSPI_ROLE_POPUP_MENU:
        case ATSPI_ROLE_DIALOG :
-               _current_highlight_object_set(flat_navi_context_current_get(context), HIGHLIGHT_FIRST);
+               _current_highlight_object_set(nd, flat_navi_context_current_get(context), HIGHLIGHT_FIRST);
                break;
        default :
                break;
@@ -2740,10 +2793,12 @@ static void _view_content_changed(AtspiAccessible * root, void *user_data)
 static void _new_highlighted_obj_changed(AtspiAccessible * new_highlighted_obj, void *user_data)
 {
        DEBUG("context: %p, current: %p, new_highlighted_obj: %p", context, flat_navi_context_current_get(context), new_highlighted_obj);
+       Service_Data *service_data = get_pointer_to_service_data_struct();
+       Navigator_Data *nd = service_data->navigator_data;
        if (context && flat_navi_context_current_get(context) != new_highlighted_obj) {
                flat_navi_context_current_set(context, g_object_ref(new_highlighted_obj));
-               current_obj = new_highlighted_obj;
-               current_comp = atspi_accessible_get_component_iface(new_highlighted_obj);
+               nd->current_obj = new_highlighted_obj;
+               nd->current_comp = atspi_accessible_get_component_iface(new_highlighted_obj);
        }
 }
 
@@ -2798,16 +2853,23 @@ static void on_window_activate(void *data, AtspiAccessible * window)
 {
        DEBUG("START");
 
-       if (top_window)
-               app_tracker_callback_unregister(top_window, _view_content_changed, NULL);
+       Navigator_Data *nd = (Navigator_Data *)data;
+
+       if (nd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
+       if (nd->top_window)
+               app_tracker_callback_unregister(nd->top_window, _view_content_changed, nd);
 
        if (window) {
                DEBUG("Window name: %s", atspi_accessible_get_name(window, 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);
-               top_window = modal_descendant ? modal_descendant : window;
+               app_tracker_callback_register(modal_descendant ? modal_descendant : window, _view_content_changed, nd);
+               _view_content_changed(modal_descendant ? modal_descendant : window, nd);
+               nd->top_window = modal_descendant ? modal_descendant : window;
                g_object_unref(modal_descendant);
        } else {
                flat_navi_context_free(context);
@@ -2839,40 +2901,74 @@ void navigator_gestures_tracker_register(GestureCB gesture_cb, void *data)
        return;
 }
 
-void navigator_init(void)
+Navigator_Data *navigator_init(Service_Data *sd)
 {
        DEBUG("START");
 
+       if (sd == NULL) {
+               ERROR("NULL context");
+               return NULL;
+       }
+
+       Navigator_Data *nd = calloc(1, sizeof(Navigator_Data));
+
+       if (nd == NULL) {
+               ERROR("calloc(1,%d) failed", sizeof(Navigator_Data));
+               return NULL;
+       }
+
+       nd->gesture_start_p = (point_t) { .x = -1, .y = -1};
+       nd->last_focus = (point_t) { .x = -1, .y = -1};
+       nd->last_pos = (point_t) { .x = -1, .y = -1};
+       nd->last_hover_event_time = -1;
+       nd->focused_object = NULL;
+       nd->auto_review_on = false;
+
        set_utterance_cb(_on_utterance);
 
-       navigator_gestures_tracker_register(on_gesture_detected, NULL);
+       navigator_gestures_tracker_register(on_gesture_detected, nd);
        // register on active_window
        dbus_gesture_adapter_init();
        app_tracker_init();
        app_tracker_new_obj_highlighted_callback_register(_new_highlighted_obj_changed);
        window_tracker_init();
-       window_tracker_register(on_window_activate, NULL);
+       window_tracker_register(on_window_activate, nd);
        window_tracker_active_window_request();
        smart_notification_init();
 #ifndef SCREEN_READER_TV
        system_notifications_init();
 #endif
+
+       return nd;
 }
 
-void navigator_shutdown(void)
+void navigator_shutdown(Service_Data *sd)
 {
+       if (sd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
+       if (sd->navigator_data == NULL) {
+               ERROR("NULL navigator context");
+               return;
+       }
+
        GError *err = NULL;
-       if (current_obj) {
-               AtspiComponent *comp = atspi_accessible_get_component_iface(current_obj);
+
+       if (sd->navigator_data->current_obj != NULL) {
+               AtspiComponent *comp = atspi_accessible_get_component_iface(sd->navigator_data->current_obj);
                if (comp) {
                        atspi_component_clear_highlight(comp, &err);
                        GERROR_CHECK(err);
                }
        }
+
        if (context) {
                flat_navi_context_free(context);
                context = NULL;
        }
+
        dbus_gesture_adapter_shutdown();
        app_tracker_shutdown();
        window_tracker_shutdown();
@@ -2880,4 +2976,6 @@ void navigator_shutdown(void)
 #ifndef SCREEN_READER_TV
        system_notifications_shutdown();
 #endif
+
+       free(sd->navigator_data);
 }