[screen reader] Code refactoring: flat navi v0.2 54/89154/2
authorLukasz Wlazly <l.wlazly@partner.samsung.com>
Thu, 8 Sep 2016 09:55:20 +0000 (11:55 +0200)
committerm.detko <m.detko@samsung.com>
Thu, 22 Sep 2016 12:30:10 +0000 (14:30 +0200)
Change-Id: Id4d756ac03ebfda3d3889df95f5d792ccc67f30e

include/app_tracker.h
include/flat_navi.h
include/navigator.h
include/screen_reader.h
include/screen_reader_tts.h
src/app_tracker.c
src/flat_navi.c
src/main.c
src/navigator.c
tests/smart_navi_suite.c

index 655a892596859f1afc0f69b4f5ea7c3d54c2d7ee..2c1f246af82261113396ae3e95ad74bbe82ca2ed 100644 (file)
@@ -25,7 +25,7 @@ typedef void (*AppTrackerEventCB)(AtspiAccessible *root, void *user_data);
  * @param user_data pointer passed to cb function.
  */
 void app_tracker_callback_register(AtspiAccessible *app, AppTrackerEventCB cb, void *user_data);
-void app_tracker_new_obj_highlighted_callback_register(AppTrackerEventCB cb);
+void app_tracker_new_obj_highlighted_callback_register(AppTrackerEventCB cb, void *user_data);
 
 /**
  * @brief Unregister listener on given event type.
index ae9af32391a0f428e6c76c9e46aa1ea47ccd0cca..179a321c7dc570c119f65104e44ff8c18d7cb818 100644 (file)
@@ -4,19 +4,25 @@
 #include <atspi/atspi.h>
 #include <Eina.h>
 #include <stdbool.h>
+#include "screen_reader.h"
 
-typedef struct _FlatNaviContext FlatNaviContext;
+struct _Flat_Navi_Context {
+       AtspiAccessible *root;
+       AtspiAccessible *current;
+       AtspiAccessible *first;
+       AtspiAccessible *last;
+};
 
 /**
- * @brief Creates new FlatNaviContext.
+ * @brief Creates new Flat_Navi_Context.
  *
- * FlatNaviContext organizes UI elements in a way that is similar to
- * reading orded (from left to right) and allow it traversing.
+ * Flat_Navi_Context organizes UI elements in a way that is similar to
+ * reading orded (from left to right) and allows linear traversing of these elements.
  *
- * @param root AtspiAccessible root object on which descendants FlatNaviContext
- * will be builded.
+ * @param root AtspiAccessible root object on which descendants Flat_Navi_Context
+ * will be built.
  *
- * @return New FlatNaviContext. Should be free with flat_navi_context_free.
+ * @return New Flat_Navi_Context. Should be freed with flat_navi_context_free().
  *
  * @note Context will use positions obtain from object_cache. It is up
  * to developer to guarantee that cache is up-to-date.
@@ -26,91 +32,94 @@ typedef struct _FlatNaviContext FlatNaviContext;
  * @note default current element is first object in first line.
  *
  */
-FlatNaviContext *flat_navi_context_create(AtspiAccessible *root);
+Flat_Navi_Context *flat_navi_context_create(AtspiAccessible *root);
 
 /**
- * @brief Frees FlatNaviContext
- * @param ctx FlatNaviContext
+ * @brief Frees Flat_Navi_Context
+ *
+ * @param ctx Flat_Navi_Context
+ *
+ * @note This function does not free members of _Flat_Navi_Context struct,
+ *       they should be freed manually
  */
-void flat_navi_context_free(FlatNaviContext *ctx);
+void flat_navi_context_free(Flat_Navi_Context *ctx);
 
 /**
  * Returns the  root of given context
  * @param ctx Flat navi context
  * @return
  */
-AtspiAccessible *flat_navi_context_root_get(FlatNaviContext *ctx);
+AtspiAccessible *flat_navi_context_root_get(Flat_Navi_Context *ctx);
 
 /**
  * Advances to next element in natural reading order and returns
  * new current element.
  *
- * @param ctx FlatNaviContext
+ * @param ctx Flat_Navi_Context
  *
  * @return AtspiAccessible* pointer to current object
  *
  * @note If current element is last in line function returns NULL
  */
-AtspiAccessible *flat_navi_context_next(FlatNaviContext *ctx);
+AtspiAccessible *flat_navi_context_next(Flat_Navi_Context *ctx);
 
 /**
  * Advances to previous element in natural reading order and returns
  * new current element.
  *
- * @param ctx FlatNaviContext
+ * @param ctx Flat_Navi_Context
  *
  * @return AtspiAccessible* pointer to current object
  *
  * @note If current element is first in line function returns NULL
  */
-AtspiAccessible *flat_navi_context_prev(FlatNaviContext *ctx);
+AtspiAccessible *flat_navi_context_prev(Flat_Navi_Context *ctx);
 
 /**
  * Advances to last element in current line.
  *
- * @param ctx FlatNaviContext
+ * @param ctx Flat_Navi_Context
  *
  * @return AtspiAccessible* pointer to current object
  */
-AtspiAccessible *flat_navi_context_last(FlatNaviContext *ctx);
+AtspiAccessible *flat_navi_context_last(Flat_Navi_Context *ctx);
 
 /**
  * Advances to first element in current line.
  *
- * @param ctx FlatNaviContext
+ * @param ctx Flat_Navi_Context
  *
  * @return AtspiAccessible* pointer to current object
  */
-AtspiAccessible *flat_navi_context_first(FlatNaviContext *ctx);
+AtspiAccessible *flat_navi_context_first(Flat_Navi_Context *ctx);
 
 /**
  * Get current element
  *
- * @param ctx FlatNaviContext
+ * @param ctx Flat_Navi_Context
  *
  * @return AtspiAccessible* pointer to current object
  */
-AtspiAccessible *flat_navi_context_current_get(FlatNaviContext *ctx);
+AtspiAccessible *flat_navi_context_current_get(Flat_Navi_Context *ctx);
 
 /**
  * Set current element.
  *
- * @note There might be situation when target object is not in FlatNaviContext.
+ * @note There might be situation when target object is not in Flat_Navi_Context.
  * (eg. was filtered by internal heuristic) in this situations function returns
  * EINA_FALSE.
  *
- * @param ctx FlatNaviContext
- * @param target new current FlatNaviContext object
+ * @param ctx Flat_Navi_Context
+ * @param target new current Flat_Navi_Context object
  *
  * @return EINA_TRUE is operation successed, EINA_FALSE otherwise
  */
-Eina_Bool flat_navi_context_current_set(FlatNaviContext *ctx, AtspiAccessible *target);
+Eina_Bool flat_navi_context_current_set(Flat_Navi_Context *ctx, AtspiAccessible *target);
 
 /**
  * Set current context at given position.
  *
- * @param ctx FlatNaviContext
- *
+ * @param ctx Flat_Navi_Context
  * @param x_cord gint X coordinate
  *
  * @param y_cord gint Y coordinate
@@ -121,25 +130,56 @@ Eina_Bool flat_navi_context_current_set(FlatNaviContext *ctx, AtspiAccessible *t
  *
  * @note current element will be first of line.
  */
-Eina_Bool flat_navi_context_current_at_x_y_set( FlatNaviContext *ctx, gint x_cord, gint y_cord , AtspiAccessible **obj);
+Eina_Bool flat_navi_context_current_at_x_y_set( Flat_Navi_Context *ctx, gint x_cord, gint y_cord , AtspiAccessible **obj);
 
 /**
- * Returns the first item in context;
- * @param ctx FlatNaviContext
- * @return Pointer to the first item in context
+ * @brief Returns the first item in context without changing the context;
+ *
+ * @param ctx Flat_Navi_Context
+ *
+ * @return Ownership of the first object in context
+ *
+ * @see flat_navi_context_first()
+ * @see flat_navi_context_free()
  */
-const AtspiAccessible *flat_navi_context_first_get(FlatNaviContext *ctx);
+const AtspiAccessible *flat_navi_context_first_get(Flat_Navi_Context *ctx);
 
 /**
- * Returns the last item in context;
- * @param ctx FlatNaviContext
- * @return Pointer to the last item in context
+ * @brief Returns the last item in context;
+ *
+ * @param ctx Flat_Navi_Context
+ *
+ * @return Ownership of the last object in context
+ *
+ * @see flat_navi_context_last()
+ * @see flat_navi_context_free()
  */
-const AtspiAccessible *flat_navi_context_last_get(FlatNaviContext *ctx);
+const AtspiAccessible *flat_navi_context_last_get(Flat_Navi_Context *ctx);
 
-Eina_Bool flat_navi_is_valid(FlatNaviContext *context, AtspiAccessible *new_root);
+/*
+ * @brief Checks if provided context is valid
+ *
+ * @description Valid context means that current AtspiAccessible has state
+ * ATSPI_STATE_SHOWING and has no state ATSPI_STATE_DEFUNCT. EINA_FALSE is returned
+ * if context, current AtspiAccessible are NULLs or provided new_root is different
+ * than present root
+ *
+ * @param context Flat_Navi_Context to validate
+ * @param new_root AtspiAccessible root of the checked context
+ *
+ * @return EINA_TRUE on success validation, EINA_FALSE otherwise
+ */
+Eina_Bool flat_navi_is_valid(Flat_Navi_Context *context, AtspiAccessible *new_root);
 Eina_Bool _has_activate_action(AtspiAccessible * obj);
 
+/*
+ * @brief Searches for object that is in particular relation with source
+ *
+ * @param source AtspiAccessible source object
+ * @param search_type AtspiRelationType variable describing relation type
+ *
+ * @ret AtspiAccessible object
+ */
 AtspiAccessible *flat_navi_get_object_in_relation(AtspiAccessible *source, AtspiRelationType search_type);
 
 #endif /* end of include guard: FLAT_NAVI_H_ */
index 9ae6a1a6a7a872f6a34c01c2f5e0d780cd930119..2f0bca00bd5911d397ef9adf20959038a9e03fd5 100644 (file)
@@ -15,6 +15,8 @@ extern bool haptic;
  * @description Initializes D-Bus Gesture Adapter, App Tracker, Window Tracker,
  *              registers callback functions for gesture detection and highlight changing
  *
+ * @param sd internal data struct of screen reader
+ *
  * @note Initializes notification system if SCREEN_READER_TV is undefined
  *
  * @see app_tracker_init(), window_tracker_init(), smart_notification_init(), system_notifications_init()
@@ -24,6 +26,7 @@ Navigator_Data *navigator_init(Service_Data *sd);
 /**
  * @brief Closes all subservices opened in initialization
  *
+ * @param sd internal data struct
  */
 void navigator_shutdown(Service_Data *sd);
 
index 106bf098e4d95d58d2d7a5cf084e3ccf94a00592..78456fefa3ac1ded47fca33cebf8e8bb5a6e330a 100644 (file)
@@ -32,10 +32,12 @@ typedef enum
 } Wrong_Validation_Reacction;
 
 typedef struct _Navigator_Data Navigator_Data;
+typedef struct _Flat_Navi_Context Flat_Navi_Context;
 
 typedef struct _Service_Data
 {
        Navigator_Data *navigator_data;
+       Flat_Navi_Context *flat_navi_context;
 
        //Set by vconf
        bool run_service;
index b3a1a200ffb1f0a0ade0e4e3b239945d71ab454e..1fbb368344c3629ef5fb067165b762fc2f4f3b22 100644 (file)
@@ -31,6 +31,10 @@ typedef struct {
        Eina_Bool is_playing;
 } Read_Command;
 
+/**
+ * @brief Initializes Text To Speech (TTS) service for the screen reader
+ * @param data screen reader internal data struct
+ */
 bool tts_init(void *data);
 void tts_shutdown(void *data);
 void state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* user_data);
index 6f4cb2f4ee1eec70aa8e635de306e48239c5eb68..ae61b42923b94e89ac85da792f4b61926b349f09 100644 (file)
@@ -41,6 +41,7 @@ static int _init_count;
 static GList *_roots;
 static AtspiEventListener *_listener;
 static AppTrackerEventCB _new_obj_highlighted_callback;
+static void *_new_obj_highlighted_callback_data;
 extern bool keyboard_feedback;
 
 static int _is_descendant(AtspiAccessible * ancestor, AtspiAccessible * descendant)
@@ -539,9 +540,10 @@ void app_tracker_callback_register(AtspiAccessible * app, AppTrackerEventCB cb,
        DEBUG("END");
 }
 
-void app_tracker_new_obj_highlighted_callback_register(AppTrackerEventCB cb)
+void app_tracker_new_obj_highlighted_callback_register(AppTrackerEventCB cb, void *user_data)
 {
        _new_obj_highlighted_callback = cb;
+       _new_obj_highlighted_callback_data = user_data;
 }
 
 void app_tracker_callback_unregister(AtspiAccessible * app, AppTrackerEventCB cb, void *user_data)
index 960199695c887c588b96d697af7396136af45529..14706b5bc48af6e1d8c30ad152a9a3368468edd0 100644 (file)
 #include "logger.h"
 #include "smart_notification.h"
 
-struct _FlatNaviContext {
-       AtspiAccessible *root;
-       AtspiAccessible *current;
-       AtspiAccessible *first;
-       AtspiAccessible *last;
-};
-
 static const AtspiStateType required_states[] = {
        ATSPI_STATE_SHOWING,
        ATSPI_STATE_VISIBLE,
@@ -73,7 +66,7 @@ static const AtspiRole interesting_roles[] = {
 
 extern bool sound_feedback;
 
-Eina_Bool _has_activate_action(AtspiAccessible * obj)
+Eina_Bool _has_activate_action(AtspiAccessible *obj)
 {
        Eina_Bool ret = EINA_FALSE;
 
@@ -97,7 +90,7 @@ Eina_Bool _has_activate_action(AtspiAccessible * obj)
        return ret;
 }
 
-static Eina_Bool _is_collapsed(AtspiStateSet * ss)
+static Eina_Bool _is_collapsed(AtspiStateSet *ss)
 {
        if (!ss)
                return EINA_FALSE;
@@ -109,7 +102,7 @@ static Eina_Bool _is_collapsed(AtspiStateSet * ss)
        return ret;
 }
 
-static Eina_Bool _object_is_item(AtspiAccessible * obj)
+static Eina_Bool _object_is_item(AtspiAccessible *obj)
 {
        if (!obj)
                return EINA_FALSE;
@@ -122,7 +115,7 @@ static Eina_Bool _object_is_item(AtspiAccessible * obj)
        return ret;
 }
 
-static AtspiAccessible *_get_object_in_relation(AtspiAccessible * source, AtspiRelationType search_type)
+static AtspiAccessible *_get_object_in_relation(AtspiAccessible *source, AtspiRelationType search_type)
 {
        GArray *relations;
        AtspiAccessible *ret = NULL;
@@ -151,7 +144,7 @@ static AtspiAccessible *_get_object_in_relation(AtspiAccessible * source, AtspiR
        return ret;
 }
 
-static Eina_Bool _accept_object(AtspiAccessible * obj)
+static Eina_Bool _accept_object(AtspiAccessible *obj)
 {
        DEBUG("START");
        if (!obj)
@@ -302,13 +295,13 @@ static Eina_Bool _accept_object(AtspiAccessible * obj)
 }
 
 #ifdef SCREEN_READER_FLAT_NAVI_TEST_DUMMY_IMPLEMENTATION
-Eina_Bool flat_navi_context_current_at_x_y_set(FlatNaviContext * ctx, gint x_cord, gint y_cord, AtspiAccessible ** target)
+Eina_Bool flat_navi_context_current_at_x_y_set(Flat_Navi_Context *ctx, gint x_cord, gint y_cord, AtspiAccessible **target)
 {
        return EINA_FALSE;
 }
 #else
 
-int _object_has_modal_state(AtspiAccessible * obj)
+int _object_has_modal_state(AtspiAccessible *obj)
 {
        if (!obj)
                return EINA_FALSE;
@@ -323,7 +316,7 @@ int _object_has_modal_state(AtspiAccessible * obj)
        return ret;
 }
 
-Eina_Bool flat_navi_context_current_at_x_y_set(FlatNaviContext * ctx, gint x_cord, gint y_cord, AtspiAccessible ** target)
+Eina_Bool flat_navi_context_current_at_x_y_set(Flat_Navi_Context *ctx, gint x_cord, gint y_cord, AtspiAccessible **target)
 {
        if (!ctx || !target)
                return EINA_FALSE;
@@ -375,7 +368,8 @@ Eina_Bool flat_navi_context_current_at_x_y_set(FlatNaviContext * ctx, gint x_cor
                        }
 
                        if (_accept_object(obj) && atspi_accessible_get_role(obj, NULL) != ATSPI_ROLE_PAGE_TAB) {
-                               DEBUG("Object  %s with role %s fulfills highlight conditions", atspi_accessible_get_name(obj, NULL), atspi_accessible_get_role_name(obj, NULL));
+                               DEBUG("Object  %s with role %s fulfills highlight conditions",
+                                       atspi_accessible_get_name(obj, NULL), atspi_accessible_get_role_name(obj, NULL));
                                if (youngest_ancestor_in_context)
                                        g_object_unref(youngest_ancestor_in_context);
                                youngest_ancestor_in_context = g_object_ref(obj);
@@ -394,7 +388,8 @@ Eina_Bool flat_navi_context_current_at_x_y_set(FlatNaviContext * ctx, gint x_cor
                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));
+                       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;
                }
@@ -405,7 +400,7 @@ Eina_Bool flat_navi_context_current_at_x_y_set(FlatNaviContext * ctx, gint x_cor
 }
 #endif
 
-AtspiAccessible *_get_child(AtspiAccessible * obj, int i)
+AtspiAccessible *_get_child(AtspiAccessible *obj, int i)
 {
        DEBUG("START:%d", i);
        if (i < 0) {
@@ -424,7 +419,7 @@ AtspiAccessible *_get_child(AtspiAccessible * obj, int i)
        return atspi_accessible_get_child_at_index(obj, i, NULL);
 }
 
-static Eina_Bool _has_next_sibling(AtspiAccessible * obj, int next_sibling_idx_modifier)
+static Eina_Bool _has_next_sibling(AtspiAccessible *obj, int next_sibling_idx_modifier)
 {
        Eina_Bool ret = EINA_FALSE;
        if (!obj) return ret;
@@ -441,7 +436,7 @@ static Eina_Bool _has_next_sibling(AtspiAccessible * obj, int next_sibling_idx_m
        return ret;
 }
 
-AtspiAccessible *_directional_depth_first_search(AtspiAccessible * root, AtspiAccessible * start, int next_sibling_idx_modifier, Eina_Bool(*stop_condition) (AtspiAccessible *))
+AtspiAccessible *_directional_depth_first_search(AtspiAccessible *root, AtspiAccessible *start, int next_sibling_idx_modifier, Eina_Bool(*stop_condition) (AtspiAccessible *))
 {
        Eina_Bool start_is_not_defunct = EINA_FALSE;
        AtspiStateSet *ss;
@@ -572,19 +567,19 @@ AtspiAccessible *_directional_depth_first_search(AtspiAccessible * root, AtspiAc
        return NULL;
 }
 
-AtspiAccessible *_first(FlatNaviContext * ctx)
+AtspiAccessible *_first(Flat_Navi_Context *ctx)
 {
        DEBUG("START");
        return _directional_depth_first_search(ctx->root, NULL, 1, &_accept_object);
 }
 
-AtspiAccessible *_last(FlatNaviContext * ctx)
+AtspiAccessible *_last(Flat_Navi_Context *ctx)
 {
        DEBUG("START");
        return _directional_depth_first_search(ctx->root, NULL, -1, &_accept_object);
 }
 
-AtspiAccessible *_next(FlatNaviContext * ctx)
+AtspiAccessible *_next(Flat_Navi_Context *ctx)
 {
        DEBUG("START");
        AtspiAccessible *root = ctx->root;
@@ -602,7 +597,7 @@ AtspiAccessible *_next(FlatNaviContext * ctx)
        return ret;
 }
 
-AtspiAccessible *_prev(FlatNaviContext * ctx)
+AtspiAccessible *_prev(Flat_Navi_Context *ctx)
 {
        DEBUG("START\n");
        AtspiAccessible *root = ctx->root;
@@ -619,7 +614,7 @@ AtspiAccessible *_prev(FlatNaviContext * ctx)
        return ret;
 }
 
-int flat_navi_context_current_children_count_visible_get(FlatNaviContext * ctx)
+int flat_navi_context_current_children_count_visible_get(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return -1;
@@ -646,29 +641,36 @@ int flat_navi_context_current_children_count_visible_get(FlatNaviContext * ctx)
        return count;
 }
 
-FlatNaviContext *flat_navi_context_create(AtspiAccessible * root)
+Flat_Navi_Context *flat_navi_context_create(AtspiAccessible *root)
 {
        DEBUG("START");
-       if (!root)
+
+       if (!root) {
+               ERROR("NULL root object");
                return NULL;
-       FlatNaviContext *ret;
-       ret = calloc(1, sizeof(FlatNaviContext));
-       if (!ret)
+       }
+
+       Flat_Navi_Context *fnc = calloc(1, sizeof(Flat_Navi_Context));
+
+       if (fnc == NULL) {
+               ERROR("No memory allocated");
                return NULL;
+       }
 
-       ret->root = root;
-       ret->current = _first(ret);
-       return ret;
+       fnc->root = root;
+       fnc->current = _first(fnc);
+
+       return fnc;
 }
 
-void flat_navi_context_free(FlatNaviContext * ctx)
+void flat_navi_context_free(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return;
        free(ctx);
 }
 
-AtspiAccessible *flat_navi_context_root_get(FlatNaviContext * ctx)
+AtspiAccessible *flat_navi_context_root_get(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return NULL;
@@ -676,7 +678,7 @@ AtspiAccessible *flat_navi_context_root_get(FlatNaviContext * ctx)
        return ctx->root;
 }
 
-const AtspiAccessible *flat_navi_context_first_get(FlatNaviContext * ctx)
+const AtspiAccessible *flat_navi_context_first_get(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return NULL;
@@ -684,7 +686,7 @@ const AtspiAccessible *flat_navi_context_first_get(FlatNaviContext * ctx)
        return _first(ctx);
 }
 
-const AtspiAccessible *flat_navi_context_last_get(FlatNaviContext * ctx)
+const AtspiAccessible *flat_navi_context_last_get(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return NULL;
@@ -692,7 +694,7 @@ const AtspiAccessible *flat_navi_context_last_get(FlatNaviContext * ctx)
        return _last(ctx);
 }
 
-AtspiAccessible *flat_navi_context_current_get(FlatNaviContext * ctx)
+AtspiAccessible *flat_navi_context_current_get(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return NULL;
@@ -700,7 +702,7 @@ AtspiAccessible *flat_navi_context_current_get(FlatNaviContext * ctx)
        return ctx->current;
 }
 
-Eina_Bool flat_navi_context_current_set(FlatNaviContext * ctx, AtspiAccessible * target)
+Eina_Bool flat_navi_context_current_set(Flat_Navi_Context *ctx, AtspiAccessible *target)
 {
        if (!ctx || !target)
                return EINA_FALSE;
@@ -710,7 +712,7 @@ Eina_Bool flat_navi_context_current_set(FlatNaviContext * ctx, AtspiAccessible *
        return EINA_TRUE;
 }
 
-AtspiAccessible *flat_navi_context_next(FlatNaviContext * ctx)
+AtspiAccessible *flat_navi_context_next(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return NULL;
@@ -722,7 +724,7 @@ AtspiAccessible *flat_navi_context_next(FlatNaviContext * ctx)
 
 }
 
-AtspiAccessible *flat_navi_context_prev(FlatNaviContext * ctx)
+AtspiAccessible *flat_navi_context_prev(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return NULL;
@@ -733,7 +735,7 @@ AtspiAccessible *flat_navi_context_prev(FlatNaviContext * ctx)
        return ret;
 }
 
-AtspiAccessible *flat_navi_context_first(FlatNaviContext * ctx)
+AtspiAccessible *flat_navi_context_first(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return NULL;
@@ -744,7 +746,7 @@ AtspiAccessible *flat_navi_context_first(FlatNaviContext * ctx)
        return ret;
 }
 
-AtspiAccessible *flat_navi_context_last(FlatNaviContext * ctx)
+AtspiAccessible *flat_navi_context_last(Flat_Navi_Context *ctx)
 {
        if (!ctx)
                return NULL;
@@ -755,7 +757,7 @@ AtspiAccessible *flat_navi_context_last(FlatNaviContext * ctx)
        return ret;
 }
 
-Eina_Bool flat_navi_is_valid(FlatNaviContext * context, AtspiAccessible * new_root)
+Eina_Bool flat_navi_is_valid(Flat_Navi_Context *context, AtspiAccessible *new_root)
 {
        Eina_Bool ret = EINA_FALSE;
        if (!context || !context->current || context->root != new_root)
@@ -777,4 +779,3 @@ AtspiAccessible *flat_navi_get_object_in_relation(AtspiAccessible *source, Atspi
 
        return ret;
 }
-
index c0bfd04065164b19af764abf75e57819303a8072..f209730149cc8f02f5942563879cb5e0925e4992 100644 (file)
@@ -216,11 +216,11 @@ void set_signal_handler()
 
 static int app_create(void *data)
 {
-       Service_Data *sd = get_pointer_to_service_data_struct();
+       Service_Data *sd = (Service_Data *)data;
 
        elm_init(0, NULL);
        atspi_init();
-       screen_reader_create_service(data);
+       screen_reader_create_service(sd);
        DEBUG("[START] init direct reading");
        if (dbus_direct_reading_init() != 0) {
                ERROR("direct reading initialization has failed");
@@ -243,9 +243,15 @@ 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");
+
+       Service_Data *sd = (Service_Data *)data;
+
+       if (sd == NULL) {
+               ERROR("NULL context");
+               return -1;
+       }
+
 #ifndef SCREEN_READER_TV
        DEBUG("terminate navigator");
        navigator_shutdown(sd);
index b7a869760040a0f41f3a464401cdaec235f2b009..f0aca45cde0e2ef2569858413248193a4208b5aa 100644 (file)
@@ -104,8 +104,6 @@ struct _Navigator_Data {
        bool auto_review_on;
 };
 
-static FlatNaviContext *context;
-
 extern bool read_description;
 extern bool haptic;
 extern bool sound_feedback;
@@ -1207,7 +1205,7 @@ void test_debug(AtspiAccessible * current_widget)
        g_object_unref(parent);
 }
 
-static void _focus_widget(Navigator_Data *nd, Gesture_Info *info)
+static void _focus_widget(Navigator_Data *nd, Flat_Navi_Context *context, Gesture_Info *info)
 {
        DEBUG("START");
 
@@ -1224,7 +1222,7 @@ static void _focus_widget(Navigator_Data *nd, Gesture_Info *info)
        DEBUG("END");
 }
 
-static void _focus_next(Navigator_Data *nd)
+static void _focus_next(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("START");
 
@@ -1242,7 +1240,7 @@ static void _focus_next(Navigator_Data *nd)
        DEBUG("END");
 }
 
-static void _focus_next_visible(Navigator_Data *nd)
+static void _focus_next_visible(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("START");
 
@@ -1272,7 +1270,7 @@ static void _focus_next_visible(Navigator_Data *nd)
        DEBUG("END");
 }
 
-static void _focus_prev_visible(Navigator_Data *nd)
+static void _focus_prev_visible(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        AtspiAccessible *obj;
        AtspiStateSet *ss = NULL;
@@ -1298,7 +1296,7 @@ static void _focus_prev_visible(Navigator_Data *nd)
                DEBUG("Previous widget not found. Abort");
 }
 
-static void _focus_prev(Navigator_Data *nd)
+static void _focus_prev(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        AtspiAccessible *obj;
        if (!context) {
@@ -1849,7 +1847,7 @@ static void _widget_scroll_end(Gesture_Info *gi)
 }
 */
 
-static void _widget_scroll(Navigator_Data *nd, Gesture_Info *gi)
+static void _widget_scroll(Navigator_Data *nd, Flat_Navi_Context *context, Gesture_Info *gi)
 {
        DEBUG("Recognized gesture state: %d", gi->state);
        int x_diff, y_diff;
@@ -1896,21 +1894,21 @@ static void _widget_scroll(Navigator_Data *nd, Gesture_Info *gi)
                if (abs(y_diff) >= abs(x_diff)) {
                        if (y_diff > 0) {
                                DEBUG("PREVIOUS");
-                               _focus_prev_visible(nd);
+                               _focus_prev_visible(nd, context);
                        }
                        else {
                                DEBUG("NEXT");
-                               _focus_next_visible(nd);
+                               _focus_next_visible(nd, context);
                        }
                }
                else {
                        if (x_diff > 0) {
                                DEBUG("PREVIOUS");
-                               _focus_prev_visible(nd);
+                               _focus_prev_visible(nd, context);
                        }
                        else {
                                DEBUG("NEXT");
-                               _focus_next_visible(nd);
+                               _focus_next_visible(nd, context);
                        }
                }
        }
@@ -1958,7 +1956,7 @@ static void _set_pause(void)
        DEBUG("END");
 }
 
-void auto_review_highlight_set(Navigator_Data *nd)
+void auto_review_highlight_set(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        if (nd == NULL) {
                ERROR("NULL context");
@@ -1983,7 +1981,7 @@ void auto_review_highlight_set(Navigator_Data *nd)
        DEBUG("END");
 }
 
-void auto_review_highlight_top(Navigator_Data *nd)
+void auto_review_highlight_top(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("START");
        char *text_to_speak = NULL;
@@ -2014,6 +2012,7 @@ static void _on_utterance()
        DEBUG("START");
 
        Service_Data *sd = get_pointer_to_service_data_struct();
+       Flat_Navi_Context *context = sd->flat_navi_context;
 
        if (sd == NULL) {
                ERROR("NULL context");
@@ -2023,34 +2022,34 @@ static void _on_utterance()
        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);
+               auto_review_highlight_set(sd->navigator_data, context);
        }
        DEBUG("END");
 }
 
-static void _review_from_current(Navigator_Data *nd)
+static void _review_from_current(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("START");
 
        nd->focused_object = flat_navi_context_current_get(context);
        nd->auto_review_on = true;
-       auto_review_highlight_set(nd);
+       auto_review_highlight_set(nd, context);
 
        DEBUG("END");
 }
 
-static void _review_from_top(Navigator_Data *nd)
+static void _review_from_top(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("START");
 
        nd->focused_object = flat_navi_context_current_get(context);
        nd->auto_review_on = true;
-       auto_review_highlight_top(nd);
+       auto_review_highlight_top(nd, context);
 
        DEBUG("END");
 }
 
-static void _direct_scroll_back(Navigator_Data *nd)
+static void _direct_scroll_back(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("ONE_FINGER_FLICK_LEFT_RETURN");
        if (!context) {
@@ -2109,7 +2108,7 @@ static void _direct_scroll_back(Navigator_Data *nd)
        g_object_unref(current);
 }
 
-static void _direct_scroll_forward(Navigator_Data *nd)
+static void _direct_scroll_forward(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("ONE_FINGER_FLICK_RIGHT_RETURN");
 
@@ -2169,7 +2168,7 @@ static void _direct_scroll_forward(Navigator_Data *nd)
        g_object_unref(current);
 }
 
-static void _direct_scroll_to_first(Navigator_Data *nd)
+static void _direct_scroll_to_first(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("ONE_FINGER_FLICK_UP_RETURN");
        if (!context) {
@@ -2184,7 +2183,7 @@ static void _direct_scroll_to_first(Navigator_Data *nd)
        DEBUG("END");
 }
 
-static void _direct_scroll_to_last(Navigator_Data *nd)
+static void _direct_scroll_to_last(Navigator_Data *nd, Flat_Navi_Context *context)
 {
        DEBUG("ONE_FINGER_FLICK_DOWN_RETURN");
        if (!context) {
@@ -2248,7 +2247,7 @@ static Eina_Bool _is_enabled(Navigator_Data *nd)
        }
 }
 
-static Eina_Bool _is_active_entry(void)
+static Eina_Bool _is_active_entry(Flat_Navi_Context *context)
 {
        DEBUG("START");
 
@@ -2305,7 +2304,7 @@ static Eina_Bool _is_slider(AtspiAccessible * obj)
        return EINA_FALSE;
 }
 
-static Eina_Bool _is_index_item()
+static Eina_Bool _is_index_item(Flat_Navi_Context *context)
 {
        DEBUG("START");
 
@@ -2353,7 +2352,7 @@ void end_scroll(int x, int y)
 #endif
 }
 
-static void _move_slider(Navigator_Data *nd, Gesture_Info *gi)
+static void _move_slider(Navigator_Data *nd, Flat_Navi_Context *context, Gesture_Info *gi)
 {
        DEBUG("ONE FINGER DOUBLE TAP AND HOLD");
 
@@ -2451,7 +2450,7 @@ static void _move_slider(Navigator_Data *nd, Gesture_Info *gi)
        DEBUG("END");
 }
 
-AtspiAction *_get_main_window(void)
+AtspiAction *_get_main_window(Flat_Navi_Context *context)
 {
        AtspiAccessible *win = flat_navi_context_root_get(context);
        if (!win) {
@@ -2485,11 +2484,11 @@ static int _find_action_index(AtspiAction * action, char *action_name_to_find)
        return -i;
 }
 
-static void _start_stop_signal_send(void)
+static void _start_stop_signal_send(Flat_Navi_Context *context)
 {
        int action_index = -1;
        char *action_name = "pause_play";
-       AtspiAction *action = _get_main_window();
+       AtspiAction *action = _get_main_window(context);
        if (!action) {
                ERROR("Could not get the action inteface");
        }
@@ -2509,7 +2508,7 @@ static void _start_stop_signal_send(void)
        atspi_action_do_action(action, action_index, NULL);
 }
 
-static Eina_Bool _check_access_object_internal(Highlight_Type h_type)
+static Eina_Bool _check_access_object_internal(Flat_Navi_Context *context, Highlight_Type h_type)
 {
        AtspiRole role;
        AtspiAccessible *obj;
@@ -2538,10 +2537,23 @@ 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;
+       Service_Data *sd = (Service_Data *)data;
+
+       if (sd == NULL) {
+               ERROR("NULL context service_data");
+               return;
+       }
+
+       Navigator_Data *nd = sd->navigator_data;
+       Flat_Navi_Context *context = sd->flat_navi_context;
 
        if (nd == NULL) {
-               ERROR("NULL context");
+               ERROR("NULL context navigator_data");
+               return;
+       }
+
+       if (context == NULL) {
+               ERROR("NULL context context");
                return;
        }
 
@@ -2597,7 +2609,7 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
        case ONE_FINGER_HOVER:
                if (nd->prepared) {
                        DEBUG("Prepare to move slider");
-                       _move_slider(nd, info);
+                       _move_slider(nd, context, info);
                } else {
                        if (nd->last_hover_event_time < 0)
                                nd->last_hover_event_time = info->event_time;
@@ -2620,41 +2632,41 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
                                        break;
                                }
 #endif
-                       _focus_widget(nd, info);
+                       _focus_widget(nd, context, info);
                }
                break;
        case TWO_FINGERS_HOVER:
-               _widget_scroll(nd, info);
+               _widget_scroll(nd, context, info);
                break;
        case ONE_FINGER_FLICK_LEFT:
-               if (_check_access_object_internal(HIGHLIGHT_PREV)) break;
-               _focus_prev(nd);
-               if (_is_index_item())
+               if (_check_access_object_internal(context, HIGHLIGHT_PREV)) break;
+               _focus_prev(nd, context);
+               if (_is_index_item(context))
                        _activate_widget(nd);
 
                break;
        case ONE_FINGER_FLICK_RIGHT:
-               if (_check_access_object_internal(HIGHLIGHT_NEXT)) break;
-               _focus_next(nd);
-               if (_is_index_item())
+               if (_check_access_object_internal(context, HIGHLIGHT_NEXT)) break;
+               _focus_next(nd, context);
+               if (_is_index_item(context))
                        _activate_widget(nd);
 
                break;
        case ONE_FINGER_FLICK_UP:
-               if (_is_active_entry())
+               if (_is_active_entry(context))
                        _caret_move_backward(nd);
                else if (_has_value(nd) && _is_enabled(nd))
                        _value_inc(nd);
                else
-                       _focus_prev(nd);
+                       _focus_prev(nd, context);
                break;
        case ONE_FINGER_FLICK_DOWN:
-               if (_is_active_entry())
+               if (_is_active_entry(context))
                        _caret_move_forward(nd);
                else if (_has_value(nd) && _is_enabled(nd))
                        _value_dec(nd);
                else
-                       _focus_next(nd);
+                       _focus_next(nd, context);
                break;
        case ONE_FINGER_SINGLE_TAP:
 #if defined(ELM_ACCESS_KEYBOARD) && defined(X11_ENABLED)
@@ -2672,7 +2684,7 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
                        }
 #endif
                if (!nd->prepared)
-                       _focus_widget(nd, info);
+                       _focus_widget(nd, context, info);
                break;
        case ONE_FINGER_DOUBLE_TAP:
 #if defined(ELM_ACCESS_KEYBOARD) && defined(X11_ENABLED)
@@ -2695,7 +2707,7 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
                _set_pause();
                break;
        case TWO_FINGERS_DOUBLE_TAP:
-               _start_stop_signal_send();
+               _start_stop_signal_send(context);
                break;
        case TWO_FINGERS_TRIPLE_TAP:
 #ifndef SCREEN_READER_TV
@@ -2703,10 +2715,10 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
 #endif
                break;
        case THREE_FINGERS_SINGLE_TAP:
-               _review_from_top(nd);
+               _review_from_top(nd, context);
                break;
        case THREE_FINGERS_DOUBLE_TAP:
-               _review_from_current(nd);
+               _review_from_current(nd, context);
                break;
        case THREE_FINGERS_FLICK_DOWN:
                _quickpanel_change_state(QUICKPANEL_DOWN);
@@ -2715,22 +2727,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(nd);
+               _direct_scroll_back(nd, context);
                break;
        case ONE_FINGER_FLICK_RIGHT_RETURN:
-               _direct_scroll_forward(nd);
+               _direct_scroll_forward(nd, context);
                break;
        case ONE_FINGER_FLICK_UP_RETURN:
-               if (_is_active_entry())
+               if (_is_active_entry(context))
                        _caret_move_beg(nd);
                else
-                       _direct_scroll_to_first(nd);
+                       _direct_scroll_to_first(nd, context);
                break;
        case ONE_FINGER_FLICK_DOWN_RETURN:
-               if (_is_active_entry())
+               if (_is_active_entry(context))
                        _caret_move_end(nd);
                else
-                       _direct_scroll_to_last(nd);
+                       _direct_scroll_to_last(nd, context);
                break;
        default:
                DEBUG("Gesture type %d not handled in switch", info->type);
@@ -2740,33 +2752,46 @@ static void on_gesture_detected(void *data, const Eldbus_Message *msg)
 }
 
 
-static void _view_content_changed(AtspiAccessible * root, void *user_data)
+static void _view_content_changed(AtspiAccessible *root, void *user_data)
 {
-       Navigator_Data *nd = (Navigator_Data *)user_data;
+       AtspiRole role = -1;
 
-       if (nd == NULL) {
-               ERROR("NULL context");
+       Service_Data *sd = (Service_Data *)user_data;
+
+       if (sd == NULL) {
+               ERROR("NULL context service_data");
                return;
        }
 
-       AtspiRole role = -1;
+       Navigator_Data *nd = sd->navigator_data;
 
-       if (flat_navi_is_valid(context, root))
+       if (nd == NULL) {
+               ERROR("NULL context navigator_data");
                return;
+       }
+
+       if (flat_navi_is_valid(sd->flat_navi_context, root))
+               return;
+
        if (!_widget_has_state(root, ATSPI_STATE_SHOWING))
                return;
-       flat_navi_context_free(context);
-       context = flat_navi_context_create(root);
-       if(!context)
+
+       flat_navi_context_free(sd->flat_navi_context);
+       sd->flat_navi_context = flat_navi_context_create(root);
+
+       if (sd->flat_navi_context == NULL) {
+               ERROR("Flat navi context not created");
                return;
+       }
+
        switch(atspi_accessible_get_role(root, NULL))
        {
        case ATSPI_ROLE_WINDOW :
-               role = atspi_accessible_get_role(flat_navi_context_current_get(context), NULL);
+               role = atspi_accessible_get_role(flat_navi_context_current_get(sd->flat_navi_context), NULL);
                if(role == ATSPI_ROLE_PAGE_TAB ||       //add more roles...
                        role == ATSPI_ROLE_PAGE_TAB_LIST)
                {
-                       _current_highlight_object_set(nd, flat_navi_context_current_get(context), HIGHLIGHT_FIRST);
+                       _current_highlight_object_set(nd, flat_navi_context_current_get(sd->flat_navi_context), HIGHLIGHT_FIRST);
                }
                else
                {
@@ -2781,7 +2806,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(nd, flat_navi_context_current_get(context), HIGHLIGHT_FIRST);
+               _current_highlight_object_set(nd, flat_navi_context_current_get(sd->flat_navi_context), HIGHLIGHT_FIRST);
                break;
        default :
                break;
@@ -2792,9 +2817,23 @@ static void _view_content_changed(AtspiAccessible * root, void *user_data)
 
 static void _new_highlighted_obj_changed(AtspiAccessible * new_highlighted_obj, void *user_data)
 {
+       Service_Data *sd = (Service_Data *)user_data;
+
+       if (sd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
+       Flat_Navi_Context *context = sd->flat_navi_context;
+       Navigator_Data *nd = sd->navigator_data;
+
+       if (nd == NULL) {
+               ERROR("NULL context");
+               return;
+       }
+
        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));
                nd->current_obj = new_highlighted_obj;
@@ -2853,26 +2892,33 @@ static void on_window_activate(void *data, AtspiAccessible * window)
 {
        DEBUG("START");
 
-       Navigator_Data *nd = (Navigator_Data *)data;
+       Service_Data *service_data = (Service_Data *)data;
+
+       if (service_data == NULL) {
+               ERROR("NULL context service_data");
+               return;
+       }
+
+       Navigator_Data *nd = service_data->navigator_data;
 
        if (nd == NULL) {
-               ERROR("NULL context");
+               ERROR("NULL context navigator_data");
                return;
        }
 
        if (nd->top_window)
-               app_tracker_callback_unregister(nd->top_window, _view_content_changed, nd);
+               app_tracker_callback_unregister(nd->top_window, _view_content_changed, service_data);
 
        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, nd);
-               _view_content_changed(modal_descendant ? modal_descendant : window, nd);
+               app_tracker_callback_register(modal_descendant ? modal_descendant : window, _view_content_changed, service_data);
+               _view_content_changed(modal_descendant ? modal_descendant : window, service_data);
                nd->top_window = modal_descendant ? modal_descendant : window;
                g_object_unref(modal_descendant);
        } else {
-               flat_navi_context_free(context);
+               flat_navi_context_free(service_data->flat_navi_context);
                ERROR("No top window found!");
        }
        DEBUG("END");
@@ -2926,13 +2972,13 @@ Navigator_Data *navigator_init(Service_Data *sd)
 
        set_utterance_cb(_on_utterance);
 
-       navigator_gestures_tracker_register(on_gesture_detected, nd);
+       navigator_gestures_tracker_register(on_gesture_detected, sd);
        // register on active_window
        dbus_gesture_adapter_init();
        app_tracker_init();
-       app_tracker_new_obj_highlighted_callback_register(_new_highlighted_obj_changed);
+       app_tracker_new_obj_highlighted_callback_register(_new_highlighted_obj_changed, sd);
        window_tracker_init();
-       window_tracker_register(on_window_activate, nd);
+       window_tracker_register(on_window_activate, sd);
        window_tracker_active_window_request();
        smart_notification_init();
 #ifndef SCREEN_READER_TV
@@ -2963,10 +3009,8 @@ void navigator_shutdown(Service_Data *sd)
                        GERROR_CHECK(err);
                }
        }
-
-       if (context) {
-               flat_navi_context_free(context);
-               context = NULL;
+       if (sd->flat_navi_context != NULL) {
+               flat_navi_context_free(sd->flat_navi_context);
        }
 
        dbus_gesture_adapter_shutdown();
index 2cc978e9bef718994796c8d7595fe05c6bb874c9..3c4614c5dde4186dbdc24e472240064a57511286 100644 (file)
@@ -50,7 +50,7 @@ static AtspiAccessible *child20;
 static AtspiAccessible *child21;
 static AtspiAccessible *child22;
 static AtspiAccessible *child23;
-static FlatNaviContext *ctx;
+static Flat_Navi_Context *ctx;
 
 void setup(void)
 {
@@ -395,13 +395,13 @@ END_TEST START_TEST(spi_on_value_changed)
 
 END_TEST START_TEST(spi_flat_navi_context_create_null_parameter)
 {
-       FlatNaviContext *test_ctx = flat_navi_context_create(NULL);
+       Flat_Navi_Context *test_ctx = flat_navi_context_create(NULL);
        fail_if(test_ctx);
 }
 
 END_TEST START_TEST(spi_flat_navi_context_create_valid_parameter)
 {
-       FlatNaviContext *test_ctx = flat_navi_context_create(win);
+       Flat_Navi_Context *test_ctx = flat_navi_context_create(win);
        fail_if(!test_ctx);
        flat_navi_context_free(test_ctx);
 }