Added implementations for AtkObject:property-change support. Fixed some (but not...
[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 static void report_focus_event (void *fp);
29 static void report_button_press (void *fp);
30 static boolean report_key_event (void *fp);
31 static void check_property_change (void *fp);
32 static void get_environment_vars (void);
33
34 static int _festival_init ();
35 static void _festival_say (const char *text, const char *voice, boolean shutup);
36 static void _festival_write (const char *buff, int fd);
37
38 static boolean use_magnifier = FALSE;
39 static boolean use_festival = FALSE;
40 static boolean festival_chatty = FALSE;
41
42 int
43 main(int argc, char **argv)
44 {
45   int i, j;
46   int n_desktops;
47   int n_apps;
48   Accessible *desktop;
49   Accessible *application;
50   AccessibleEventListener *focus_listener;
51   AccessibleEventListener *property_listener;
52   AccessibleEventListener *button_listener;
53   KeystrokeListener *key_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   property_listener = createEventListener (check_property_change); 
66   button_listener = createEventListener (report_button_press);
67   registerGlobalEventListener (focus_listener, "focus:");
68   registerGlobalEventListener (property_listener, "object:property-change:accessible-selection"); 
69   registerGlobalEventListener (button_listener, "Gtk:GtkWidget:button-press-event");
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           Accessible_unref (application);
82         }
83     }
84
85   /* prepare the keyboard snoopers */
86   /* key_listener = createKeystrokeListener(report_key_event);
87      registerKeystrokeListener(key_listener, KEYMASK_SHIFT); */
88
89   get_environment_vars();
90
91   SPI_event_main(FALSE);
92 }
93
94 static void
95 get_environment_vars()
96 {
97   if (getenv ("FESTIVAL"))
98   {
99     use_festival = TRUE;
100     if (getenv ("FESTIVAL_CHATTY"))
101     {
102       festival_chatty = TRUE;
103     }
104   }
105   if (getenv("MAGNIFIER"))
106   {
107     use_magnifier = TRUE;
108   }  
109 }
110
111 void
112 report_focussed_accessible (Accessible *obj, boolean shutup_previous_speech)
113 {
114   if (use_festival)
115     {
116     if (festival_chatty)            
117       {
118         _festival_say (Accessible_getRole (obj), "voice_don_diphone", shutup_previous_speech);
119       }
120       fprintf (stderr, "getting Name\n");
121       _festival_say (Accessible_getName (obj), "voice_kal_diphone",
122                      shutup_previous_speech || festival_chatty);
123     }
124   
125   if (Accessible_isComponent (obj))
126     {
127       long x, y, width, height;
128       AccessibleComponent *component = Accessible_getComponent (obj);
129       AccessibleComponent_getExtents (component, &x, &y, &width, &height,
130                                       COORD_TYPE_SCREEN);
131       fprintf (stderr, "Bounding box: (%ld, %ld) ; (%ld, %ld)\n",
132                x, y, x+width, y+height);
133       if (use_magnifier) {
134               magnifier_set_roi (x, y, width, height);        
135       }
136     }
137   /* if this is a text object, speak the first sentence. */
138   if (Accessible_isText(obj))
139   {
140      AccessibleText *text_interface;
141      long start_offset, end_offset;
142      char *first_sentence = "empty";
143      text_interface = Accessible_getText (obj);
144      fprintf (stderr, "isText...%p %p\n", text_interface, (void *)*text_interface);
145      first_sentence = AccessibleText_getTextAtOffset (
146                text_interface, (long) 0, TEXT_BOUNDARY_SENTENCE_START, &start_offset, &end_offset);
147      if (first_sentence) _festival_say(first_sentence, "voice_don_diphone", FALSE);
148      fprintf (stderr, "done reporting on focussed object\n");
149   }
150 }
151
152 void
153 report_focus_event (void *p)
154 {
155   AccessibleEvent *ev = (AccessibleEvent *) p;
156   fprintf (stderr, "%s event from %s\n", ev->type,
157            Accessible_getName (&ev->source));
158   report_focussed_accessible (&ev->source, TRUE);
159 }
160
161 void
162 report_button_press (void *p)
163 {
164   AccessibleEvent *ev = (AccessibleEvent *) p;
165   fprintf (stderr, "%s event from %s\n", ev->type,
166            Accessible_getName (&ev->source));
167 }
168
169
170 void
171 check_property_change (void *p)
172 {
173   AccessibleEvent *ev = (AccessibleEvent *) p;
174   AccessibleSelection *selection = Accessible_getSelection (&ev->source);
175   int n_selections;
176   int i;
177   if (selection)
178   {
179     n_selections = (int) AccessibleSelection_getNSelectedChildren (selection);
180     fprintf (stderr, "(Property) %s event from %s, %d selected children\n", ev->type,
181            Accessible_getName (&ev->source), n_selections);
182   /* for now, speak entire selection set */
183     for (i=0; i<n_selections; ++i)
184     {
185           Accessible *obj = AccessibleSelection_getSelectedChild (selection, (long) i);
186           g_return_if_fail (obj);
187           fprintf (stderr, "Child %d, name=%s\n", i, Accessible_getName (obj));
188           report_focussed_accessible (obj, i==0);
189     }
190   }
191 }
192
193 static boolean
194 report_key_event (void *p)
195 {
196   KeyStroke *key = (KeyStroke *) p;
197   fprintf (stderr, ".");
198   return FALSE;
199 }
200
201 static int _festival_init ()
202 {
203   int fd;
204   struct sockaddr_in name;
205   int tries = 2;
206
207   name.sin_family = AF_INET;
208   name.sin_port = htons (1314);
209   name.sin_addr.s_addr = htonl(INADDR_ANY);
210   fd = socket (PF_INET, SOCK_STREAM, 0);
211
212   while (connect(fd, (struct sockaddr *) &name, sizeof (name)) < 0) {
213     if (!tries--) {
214       perror ("connect");
215       return -1;
216     }
217   }
218
219   _festival_write ("(audio_mode'async)\n", fd);
220   _festival_write ("(Parameter.set 'Duration_Model 'Tree_ZScore)\n", fd);
221   _festival_write ("(Parameter.set 'Duration_Stretch 0.75)\n", fd);
222   return fd;
223 }
224
225 static void _festival_say (const char *text, const char *voice, boolean shutup)
226 {
227   static int fd = 0;
228   gchar *quoted;
229   gchar *p;
230   gchar prefix[50];
231   static gchar voice_spec[32];
232   
233   if (!fd)
234     {
235       fd = _festival_init ();
236     }
237
238   fprintf (stderr, "saying text: %s\n", text);
239   
240   quoted = g_malloc(64+strlen(text)*2);
241
242   sprintf (prefix, "(SayText \"");
243
244   strncpy(quoted, prefix, 10);
245   p = quoted+strlen(prefix);
246   while (*text) {
247     if ( *text == '\\' || *text == '"' )
248       *p = '\\';
249     *p++ = *text++;
250   }
251   *p++ = '"';
252   *p++ = ')';
253   *p++ = '\n';
254   *p = 0;
255
256   if (shutup) _festival_write ("(audio_mode'shutup)\n", fd);
257   if (voice && (strncmp (voice, (char *) (voice_spec+1), strlen(voice))))
258     {
259       snprintf (voice_spec, 32, "(%s)\n", voice); 
260       _festival_write (voice_spec, fd);
261       _festival_write ("(Parameter.set 'Duration_Model 'Tree_ZScore)\n", fd);
262       _festival_write ("(Parameter.set 'Duration_Stretch 0.75)\n", fd);
263     }
264
265   _festival_write (quoted, fd);
266
267   g_free(quoted);
268 }
269
270 static void _festival_write (const gchar *command_string, int fd)
271 {
272   fprintf(stderr, command_string);
273   if (fd < 0) {
274     perror("socket");
275     return;
276   }
277   write(fd, command_string, strlen(command_string));
278 }
279