506308fa85a52f4d4778da545f086d9b066369b4
[platform/core/uifw/efl-assist.git] / src / lib / efl_assist_screen_reader.c
1 #include "efl_assist.h"
2 #include "efl_assist_private.h"
3 #include <Ecore_X.h>
4 #include <vconf.h>
5 #include <tts.h>
6 #define UNAVAILABLE_TEXT "Screen reader is unavailable during using this application. You can press home or back key to go back to home screen."
7
8 static tts_h tts = NULL;
9
10 static void _tts_shutdown(void)
11 {
12    int ret = 0;
13    if (tts)
14      {
15         /* check current state */
16         tts_state_e state;
17         tts_get_state(tts, &state);
18         if (state == TTS_STATE_PLAYING || state == TTS_STATE_PAUSED)
19           {
20              ret = tts_stop(tts);
21              if (TTS_ERROR_NONE != ret)
22                {
23                   fprintf(stderr, "Fail to stop handle : result(%d)", ret);
24                   return;
25                }
26           }
27
28         /* it is possible to try to shutdown before the state is ready,
29            because tts_prepare(); works Asynchronously. see elm_modapi_init(): */
30         if (state == TTS_STATE_READY)
31           {
32              ret = tts_unprepare(tts);
33              if (TTS_ERROR_NONE != ret)
34                {
35                   fprintf(stderr, "Fail to unprepare handle : result(%d)", ret);
36                   return;
37                }
38
39              ret = tts_unset_state_changed_cb(tts);
40              if (TTS_ERROR_NONE != ret)
41                {
42                   fprintf(stderr, "Fail to set callback : result(%d)", ret);
43                   return;
44                }
45           }
46
47         ret = tts_destroy(tts);
48         if (TTS_ERROR_NONE != ret)
49           {
50              fprintf(stderr, "Fail to destroy handle : result(%d)", ret);
51              return;
52           }
53
54         if (tts) tts = NULL;
55      }
56 }
57
58 void _tts_state_changed_cb(tts_h tts, tts_state_e previous, tts_state_e current, void* data)
59 {
60    int ret = 0;
61    int u_id = 0;
62
63    if (TTS_STATE_CREATED == previous && TTS_STATE_READY == current)
64      {
65         ret = tts_add_text(tts, UNAVAILABLE_TEXT, NULL, TTS_VOICE_TYPE_AUTO,
66                            TTS_SPEED_AUTO, &u_id);
67         if (TTS_ERROR_NONE != ret)
68           {
69              fprintf(stderr, "Fail to add kept text : ret(%d)\n", ret);
70           }
71
72         ret = tts_play(tts);
73         if (TTS_ERROR_NONE != ret)
74           {
75              fprintf(stderr, "Fail to play TTS : ret(%d)\n", ret);
76           }
77      }
78 }
79
80 static void _tts_init(void)
81 {
82    int ret = 0;
83
84    ret = tts_create(&tts);
85    if (TTS_ERROR_NONE != ret)
86      {
87         fprintf(stderr, "Fail to get handle : result(%d)", ret);
88         return;
89      }
90
91    ret = tts_set_state_changed_cb(tts, _tts_state_changed_cb, NULL);
92    if (TTS_ERROR_NONE != ret)
93      {
94         fprintf(stderr, "Fail to set callback : result(%d)", ret);
95         return;
96      }
97
98    ret = tts_set_mode(tts, TTS_MODE_SCREEN_READER);
99    if (TTS_ERROR_NONE != ret)
100      {
101         fprintf(stderr, "Fail to set mode : result(%d)", ret);
102         return;
103      }
104
105    ret = tts_prepare(tts);
106    if (TTS_ERROR_NONE != ret)
107      {
108         fprintf(stderr, "Fail to prepare handle : result(%d)", ret);
109         return;
110      }
111 }
112
113 static void _timeout_cb(void *data, Evas_Object *obj, void *event_info)
114 {
115    Ecore_X_Window xwin;
116    unsigned int val;
117
118    xwin = elm_win_xwindow_get(data);
119    if (!xwin) return;
120
121    evas_object_del(obj);
122
123    val = 2;
124    ecore_x_window_prop_card32_set
125      (xwin, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, &val, 1);
126
127    _tts_shutdown();
128 }
129
130 EAPI Eina_Bool
131 ea_screen_reader_support_set(Evas_Object *win, Eina_Bool support)
132 {
133    Ecore_X_Window xwin;
134    unsigned int val;
135    int tts_val;
136    Evas_Object *base;
137    Evas_Object *body;
138    Evas_Object *popup;
139
140    if (vconf_get_bool(VCONFKEY_SETAPPL_ACCESSIBILITY_TTS, &tts_val) != 0)
141      return EINA_FALSE;
142
143    if (!tts_val) return EINA_FALSE;
144
145    if (!win) return EINA_FALSE;
146
147    xwin = elm_win_xwindow_get(win);
148    if (!xwin) return EINA_FALSE;
149
150    if (support)
151      {
152         val = 0;
153         elm_config_access_set(EINA_TRUE);
154
155         ecore_x_window_prop_card32_set
156           (xwin, ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL, &val, 1);
157      }
158    else
159      {
160         elm_config_access_set(EINA_FALSE);
161
162         popup = elm_popup_add(win);
163         evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
164         elm_object_text_set(popup, UNAVAILABLE_TEXT);
165         elm_popup_timeout_set(popup, 12.0);
166         evas_object_smart_callback_add(popup, "timeout", _timeout_cb, win);
167
168         _tts_init();
169         evas_object_show(popup);
170      }
171
172    return EINA_TRUE;
173 }
174
175 EAPI Eina_Bool
176 ea_screen_reader_support_get()
177 {
178    return elm_config_access_get();
179 }