Added support for magnifier to simple-at, and turned TTS in simple-at
[platform/core/uifw/at-spi2-atk.git] / test / simple-at.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001 Sun Microsystems Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <stdlib.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include "spi.h"
27
28 void report_focus_event (void *fp);
29
30 void report_button_press (void *fp);
31
32 static int _festival_init ();
33 static void _festival_say (const char *text, const char *voice, boolean shutup);
34 static void _festival_write (const char *buff, int fd);
35 static void _send_to_magnifier (int x, int y, int w, int h);
36
37 static boolean use_magnifier = FALSE;
38 static boolean use_festival = FALSE;
39 static boolean festival_chatty = FALSE;
40
41 static struct sockaddr_un mag_server = { AF_UNIX , "/tmp/magnifier_socket" };
42 static struct sockaddr_un client = { AF_UNIX, "/tmp/mag_client"};
43
44 int
45 main(int argc, char **argv)
46 {
47   int i, j;
48   int n_desktops;
49   int n_apps;
50   Accessible *desktop;
51   Accessible *application;
52   AccessibleEventListener *focus_listener;
53   AccessibleEventListener *button_listener;
54
55   if ((argc > 1) && (!strncmp(argv[1],"-h",2)))
56   {
57     printf ("Usage: simple-at\n");
58     printf ("\tEnvironment variables used:\n\t\tFESTIVAL\n\t\tMAGNIFIER\n\t\tFESTIVAL_CHATTY\n");
59     exit(0);
60   }
61
62   SPI_init();
63
64   focus_listener = createEventListener (report_focus_event);
65   button_listener = createEventListener (report_button_press);
66
67   registerGlobalEventListener (focus_listener, "focus:");
68   registerGlobalEventListener (button_listener, "Gtk:GtkWidget:button-press-event");
69
70   n_desktops = getDesktopCount ();
71
72   for (i=0; i<n_desktops; ++i)
73     {
74       desktop = getDesktop (i);
75       fprintf (stderr, "desktop %d name: %s\n", i, Accessible_getName (desktop));
76       n_apps = Accessible_getChildCount (desktop);
77       for (j=0; j<n_apps; ++j)
78         {
79           application = Accessible_getChildAtIndex (desktop, j);
80           fprintf (stderr, "app %d name: %s\n", j, Accessible_getName (application));
81         }
82     }
83   
84   if (getenv ("FESTIVAL"))
85   {
86     use_festival = TRUE;
87     if (getenv ("FESTIVAL_CHATTY"))
88     {
89       festival_chatty = TRUE;
90     }
91   }
92   if (getenv("MAGNIFIER"))
93   {
94     use_magnifier = TRUE;
95   }  
96
97   SPI_event_main(FALSE);
98 }
99
100 void
101 report_focus_event (void *p)
102 {
103   AccessibleEvent *ev = (AccessibleEvent *) p;
104   fprintf (stderr, "%s event from %s\n", ev->type,
105            Accessible_getName (&ev->source));
106   
107   if (use_festival)
108     {
109     if (festival_chatty)            
110       {
111         _festival_say (Accessible_getRole (&ev->source), "voice_don_diphone", TRUE);
112       }
113       _festival_say (Accessible_getName (&ev->source), "voice_kal_diphone", festival_chatty==FALSE);
114     }
115   
116   if (Accessible_isComponent (&ev->source))
117     {
118       long x, y, width, height;
119       AccessibleComponent *component = Accessible_getComponent (&ev->source);
120       fprintf (stderr, "Source implements IDL:Accessibility/Component:1.0\n");
121       AccessibleComponent_getExtents (component, &x, &y, &width, &height,
122                                       COORD_TYPE_SCREEN);
123       fprintf (stderr, "Bounding box: (%ld, %ld) ; (%ld, %ld)\n",
124                x, y, x+width, y+height);
125       if (use_magnifier)
126               _send_to_magnifier (x, y, width, height);
127     }
128 }
129
130 void
131 report_button_press (void *p)
132 {
133   AccessibleEvent *ev = (AccessibleEvent *) p;
134   fprintf (stderr, "%s event from %s\n", ev->type,
135            Accessible_getName (&ev->source));
136 }
137
138 static int _festival_init ()
139 {
140   int fd;
141   struct sockaddr_in name;
142   int tries = 2;
143
144   name.sin_family = AF_INET;
145   name.sin_port = htons (1314);
146   name.sin_addr.s_addr = htonl(INADDR_ANY);
147   fd = socket (PF_INET, SOCK_STREAM, 0);
148
149   while (connect(fd, (struct sockaddr *) &name, sizeof (name)) < 0) {
150     if (!tries--) {
151       perror ("connect");
152       return -1;
153     }
154   }
155
156   _festival_write ("(audio_mode'async)\n", fd);
157   _festival_write ("(Parameter.set 'Duration_Model 'Tree_ZScore)\n", fd);
158   _festival_write ("(Parameter.set 'Duration_Stretch 0.5)\n", fd);
159   return fd;
160 }
161
162 static void _festival_say (const char *text, const char *voice, boolean shutup)
163 {
164   static int fd = 0;
165   gchar *quoted;
166   gchar *p;
167   gchar prefix[50];
168   static gchar voice_spec[32];
169   
170   if (!fd)
171     {
172       fd = _festival_init ();
173     }
174
175   fprintf (stderr, "saying text: %s\n", text);
176   
177   quoted = g_malloc(64+strlen(text)*2);
178
179   sprintf (prefix, "(SayText \"");
180
181   strncpy(quoted, prefix, 10);
182   p = quoted+strlen(prefix);
183   while (*text) {
184     if ( *text == '\\' || *text == '"' )
185       *p = '\\';
186     *p++ = *text++;
187   }
188   *p++ = '"';
189   *p++ = ')';
190   *p++ = '\n';
191   *p = 0;
192
193   if (shutup) _festival_write ("(audio_mode'shutup)\n", fd);
194   if (voice && (strncmp (voice, (char *) (voice_spec+1), strlen(voice))))
195     {
196       snprintf (voice_spec, 32, "(%s)\n", voice); 
197       _festival_write (voice_spec, fd);
198       _festival_write ("(Parameter.set 'Duration_Model 'Tree_ZScore)\n", fd);
199       _festival_write ("(Parameter.set 'Duration_Stretch 0.5)\n", fd);
200     }
201
202   _festival_write (quoted, fd);
203
204   g_free(quoted);
205 }
206
207 static void _festival_write (const gchar *command_string, int fd)
208 {
209   fprintf(stderr, command_string);
210   if (fd < 0) {
211     perror("socket");
212     return;
213   }
214   write(fd, command_string, strlen(command_string));
215 }
216
217 static void
218 _send_to_magnifier(int x, int y, int w, int h)
219 {
220   int desc, length_msg;
221   gchar buff[100];
222
223   sprintf (buff, "~5:%d,%d:", x+w/2, y+h/2);
224
225 #ifdef MAG_DEBUG
226   g_print ("sending magnifier: %s\n", buff);
227 #endif
228
229   if((desc=socket(AF_UNIX,SOCK_STREAM,0)) == -1){
230     perror("socket");
231     return;
232   }
233   unlink("/tmp/mag_client");
234
235   if (bind(desc, (struct sockaddr*)&client, sizeof(client)) == -1)
236     {
237       perror("bind");
238       return;
239     }
240
241   if (connect(desc,(struct sockaddr*)&mag_server,sizeof(mag_server)) == -1)
242     {
243       perror("connect");
244       return;
245     }
246
247   length_msg = write(desc,buff,strlen(buff));
248   unlink("/tmp/mag_client");
249   return;
250 }