1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include "Elementary.h"
6
7 #ifndef EFL_BUILD
8 # define EFL_BUILD
9 #endif
10 #undef ELM_MODULE_HELPER_H
11 #include "elm_module_helper.h"
12
13 /* to enable this module
14 export ELM_MODULES="access_output>access/api"
15 export ELM_ACCESS_MODE=1
16 */
17
18 static void (*cb_func) (void *data);
19 static void *cb_data;
20 static Ecore_Exe *espeak = NULL;
21 static Ecore_Event_Handler *exe_exit_handler = NULL;
22 static char *tmpf = NULL;
23 static int tmpfd = -1;
24
25 static Eina_Bool
_exe_del(void * data EINA_UNUSED,int type EINA_UNUSED,void * event)26 _exe_del(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
27 {
28 Ecore_Exe_Event_Del *ev = event;
29
30 if ((espeak) && (ev->exe == espeak))
31 {
32 if (tmpf)
33 {
34 unlink(tmpf);
35 free(tmpf);
36 tmpf = NULL;
37 close(tmpfd);
38 tmpfd = -1;
39 }
40 espeak = NULL;
41 if (cb_func) cb_func(cb_data);
42 }
43 return ECORE_CALLBACK_RENEW;
44 }
45
46 // module api funcs needed
47 EAPI int
elm_modapi_init(void * m EINA_UNUSED)48 elm_modapi_init(void *m EINA_UNUSED)
49 {
50 exe_exit_handler =
51 ecore_event_handler_add(ECORE_EXE_EVENT_DEL,
52 _exe_del, NULL);
53 return 1; // succeed always
54 }
55
56 EAPI int
elm_modapi_shutdown(void * m EINA_UNUSED)57 elm_modapi_shutdown(void *m EINA_UNUSED)
58 {
59 if (exe_exit_handler)
60 {
61 ecore_event_handler_del(exe_exit_handler);
62 exe_exit_handler = NULL;
63 }
64 return 1; // succeed always
65 }
66
67 // module fucns for the specific module type
68 EAPI void
out_read(const char * txt)69 out_read(const char *txt)
70 {
71 if (!tmpf)
72 {
73 char buf[PATH_MAX];
74 mode_t cur_umask;
75
76 snprintf(buf, sizeof(buf), "/tmp/.elm-speak-XXXXXX");
77 cur_umask = umask(S_IRWXO | S_IRWXG);
78 tmpfd = mkstemp(buf);
79 umask(cur_umask);
80 if (tmpfd >= 0) tmpf = strdup(buf);
81 else return;
82 }
83 if (write(tmpfd, txt, strlen(txt)) < 0) perror("write to tmpfile (espeak)");
84 }
85
86 EAPI void
out_read_done(void)87 out_read_done(void)
88 {
89 char buf[PATH_MAX];
90
91 if (espeak)
92 {
93 ecore_exe_interrupt(espeak);
94 espeak = NULL;
95 }
96 if (tmpf)
97 {
98 // FIXME: espeak supporets -v XX for voice locale. should provide this
99 // based on actual lang/locale
100 if (tmpfd >= 0) close(tmpfd);
101 tmpfd = -1;
102 snprintf(buf, sizeof(buf), "espeak -p 2 -s 120 -k 10 -m -f %s", tmpf);
103 espeak = ecore_exe_pipe_run(buf,
104 ECORE_EXE_NOT_LEADER,
105 NULL);
106 }
107 }
108
109 EAPI void
out_cancel(void)110 out_cancel(void)
111 {
112 if (espeak)
113 {
114 ecore_exe_interrupt(espeak);
115 espeak = NULL;
116 }
117 if (tmpf)
118 {
119 unlink(tmpf);
120 free(tmpf);
121 tmpf = NULL;
122 close(tmpfd);
123 tmpfd = -1;
124 }
125 }
126
127 EAPI void
out_done_callback_set(void (* func)(void * data),const void * data)128 out_done_callback_set(void (*func) (void *data), const void *data)
129 {
130 cb_func = func;
131 cb_data = (void *)data;
132 }
133
134 static Eina_Bool
_module_init(void)135 _module_init(void)
136 {
137 return EINA_TRUE;
138 }
139
140 static void
_module_shutdown(void)141 _module_shutdown(void)
142 {
143 }
144
145 EINA_MODULE_INIT(_module_init);
146 EINA_MODULE_SHUTDOWN(_module_shutdown);
147