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