Started fixing IDL docs.
[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 static AccessibleEventListener *focus_listener;
43 static AccessibleEventListener *property_listener;
44 static AccessibleEventListener *button_listener;
45 static AccessibleKeystrokeListener *key_listener;
46
47 int
48 main(int argc, char **argv)
49 {
50   int i, j;
51   int n_desktops;
52   int n_apps;
53   Accessible *desktop;
54   Accessible *application;
55
56   if ((argc > 1) && (!strncmp(argv[1],"-h",2)))
57   {
58     printf ("Usage: simple-at\n");
59     printf ("\tEnvironment variables used:\n\t\tFESTIVAL\n\t\tMAGNIFIER\n\t\tFESTIVAL_CHATTY\n");
60     exit(0);
61   }
62
63   SPI_init();
64
65   focus_listener = createAccessibleEventListener (report_focus_event);
66   property_listener = createAccessibleEventListener (check_property_change); 
67   button_listener = createAccessibleEventListener (report_button_press);
68   registerGlobalEventListener (focus_listener, "focus:");
69   registerGlobalEventListener (property_listener, "object:property-change:accessible-selection"); 
70   registerGlobalEventListener (button_listener, "Gtk:GtkWidget:button-press-event");
71   n_desktops = getDesktopCount ();
72
73   for (i=0; i<n_desktops; ++i)
74     {
75       desktop = getDesktop (i);
76       fprintf (stderr, "desktop %d name: %s\n", i, Accessible_getName (desktop));
77       n_apps = Accessible_getChildCount (desktop);
78       for (j=0; j<n_apps; ++j)
79         {
80           application = Accessible_getChildAtIndex (desktop, j);
81           fprintf (stderr, "app %d name: %s\n", j, Accessible_getName (application));
82           Accessible_unref (application);
83         }
84     }
85
86   /* prepare the keyboard snoopers */
87   key_listener = createAccessibleKeystrokeListener(report_key_event);
88   /* will listen only to Alt-key combinations */
89   registerAccessibleKeystrokeListener(key_listener,
90                                       (AccessibleKeySet *) SPI_KEYSET_ALL_KEYS,
91                                       SPI_KEYMASK_ALT,
92                                       (unsigned long) ( KeyPress | KeyRelease),
93                                       SPI_KEYLISTENER_ALL_WINDOWS);
94
95   get_environment_vars();
96
97   SPI_event_main(TRUE);
98 }
99
100 static void
101 get_environment_vars()
102 {
103   if (getenv ("FESTIVAL"))
104   {
105     use_festival = TRUE;
106     if (getenv ("FESTIVAL_CHATTY"))
107     {
108       festival_chatty = TRUE;
109     }
110   }
111   if (getenv("MAGNIFIER"))
112   {
113     use_magnifier = TRUE;
114   }  
115 }
116
117 void
118 report_focussed_accessible (Accessible *obj, boolean shutup_previous_speech)
119 {
120   if (use_festival)
121     {
122     if (festival_chatty)            
123       {
124         _festival_say (Accessible_getRole (obj), "voice_don_diphone", shutup_previous_speech);
125       }
126       fprintf (stderr, "getting Name\n");
127       _festival_say (Accessible_getName (obj), "voice_kal_diphone",
128                      shutup_previous_speech || festival_chatty);
129     }
130   
131   if (Accessible_isComponent (obj))
132     {
133       long x, y, width, height;
134       AccessibleComponent *component = Accessible_getComponent (obj);
135       AccessibleComponent_getExtents (component, &x, &y, &width, &height,
136                                       SPI_COORD_TYPE_SCREEN);
137       fprintf (stderr, "Bounding box: (%ld, %ld) ; (%ld, %ld)\n",
138                x, y, x+width, y+height);
139       if (use_magnifier) {
140               magnifier_set_roi ((short) 0, x, y, width, height);
141       }
142     }
143   /* if this is a text object, speak the first sentence. */
144
145   if (Accessible_isText(obj))
146
147   {
148      AccessibleText *text_interface;
149      long start_offset, end_offset;
150      char *first_sentence = "empty";
151      text_interface = Accessible_getText (obj);
152      fprintf (stderr, "isText...%p %p\n", text_interface, (void *)*text_interface);
153      first_sentence = AccessibleText_getTextAtOffset (
154                text_interface, (long) 0, SPI_TEXT_BOUNDARY_SENTENCE_START, &start_offset, &end_offset);
155      if (first_sentence) _festival_say(first_sentence, "voice_don_diphone", FALSE);
156      fprintf (stderr, "done reporting on focussed object\n");
157   }
158 }
159
160 void
161 report_focus_event (void *p)
162 {
163   AccessibleEvent *ev = (AccessibleEvent *) p;
164   fprintf (stderr, "%s event from %s\n", ev->type,
165            Accessible_getName (&ev->source));
166   report_focussed_accessible (&ev->source, TRUE);
167 }
168
169 void
170 report_button_press (void *p)
171 {
172   AccessibleEvent *ev = (AccessibleEvent *) p;
173   fprintf (stderr, "%s event from %s\n", ev->type,
174            Accessible_getName (&ev->source));
175   fprintf (stderr, "Object description %s\n",
176            Accessible_getDescription (&ev->source));
177 }
178
179
180 void
181 check_property_change (void *p)
182 {
183   AccessibleEvent *ev = (AccessibleEvent *) p;
184   AccessibleSelection *selection = Accessible_getSelection (&ev->source);
185   int n_selections;
186   int i;
187   if (selection)
188   {
189     n_selections = (int) AccessibleSelection_getNSelectedChildren (selection);
190     fprintf (stderr, "(Property) %s event from %s, %d selected children\n", ev->type,
191            Accessible_getName (&ev->source), n_selections);
192   /* for now, speak entire selection set */
193     for (i=0; i<n_selections; ++i)
194     {
195           Accessible *obj = AccessibleSelection_getSelectedChild (selection, (long) i);
196           g_return_if_fail (obj);
197           fprintf (stderr, "Child %d, name=%s\n", i, Accessible_getName (obj));
198           report_focussed_accessible (obj, i==0);
199     }
200   }
201 }
202
203 static void
204 simple_at_exit()
205 {
206   deregisterGlobalEventListenerAll (focus_listener);
207   deregisterGlobalEventListenerAll (property_listener);
208   deregisterGlobalEventListenerAll (button_listener);
209   deregisterAccessibleKeystrokeListener (key_listener, SPI_KEYMASK_ALT );
210   
211   SPI_exit ();
212 }
213
214 static boolean
215 is_command_key (AccessibleKeyStroke *key)
216 {
217   switch (key->keyID)
218     {
219     case 'Q':
220     case 'q':
221             simple_at_exit(); 
222             return TRUE; /* not reached */
223     case 'M':
224     case 'm':
225             use_magnifier = ! use_magnifier;
226             return TRUE;
227     case 'F':
228     case 'f':
229             use_festival = ! use_festival;
230             return TRUE;
231     default:
232             return FALSE;
233     }
234 }
235
236 static boolean
237 report_key_event (void *p)
238 {
239   AccessibleKeyStroke *key = (AccessibleKeyStroke *) p;
240   fprintf (stderr, "KeyEvent %s%c (keycode %d)\n",
241           (key->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
242           ((key->modifiers & SPI_KEYMASK_SHIFT)^(key->modifiers & SPI_KEYMASK_SHIFTLOCK))?
243           (char) toupper((int) key->keyID) : (char) tolower((int) key->keyID),
244           (int) key->keycode);
245   fprintf (stderr, "Key:\tsym %ld\n\tmods %x\n\tcode %d\n\ttime %ld\n",
246            (long) key->keyID,
247            (unsigned int) key->modifiers,
248            (int) key->keycode,
249            (long int) key->timestamp);
250   return is_command_key (key);
251 }
252
253 static int _festival_init ()
254 {
255   int fd;
256   struct sockaddr_in name;
257   int tries = 2;
258
259   name.sin_family = AF_INET;
260   name.sin_port = htons (1314);
261   name.sin_addr.s_addr = htonl(INADDR_ANY);
262   fd = socket (PF_INET, SOCK_STREAM, 0);
263
264   while (connect(fd, (struct sockaddr *) &name, sizeof (name)) < 0) {
265     if (!tries--) {
266       perror ("connect");
267       return -1;
268     }
269   }
270
271   _festival_write ("(audio_mode'async)\n", fd);
272   _festival_write ("(Parameter.set 'Duration_Model 'Tree_ZScore)\n", fd);
273   _festival_write ("(Parameter.set 'Duration_Stretch 0.75)\n", fd);
274   return fd;
275 }
276
277 static void _festival_say (const char *text, const char *voice, boolean shutup)
278 {
279   static int fd = 0;
280   gchar *quoted;
281   gchar *p;
282   gchar prefix[50];
283   static gchar voice_spec[32];
284   
285   if (!fd)
286     {
287       fd = _festival_init ();
288     }
289
290   fprintf (stderr, "saying text: %s\n", text);
291   
292   quoted = g_malloc(64+strlen(text)*2);
293
294   sprintf (prefix, "(SayText \"");
295
296   strncpy(quoted, prefix, 10);
297   p = quoted+strlen(prefix);
298   while (*text) {
299     if ( *text == '\\' || *text == '"' )
300       *p = '\\';
301     *p++ = *text++;
302   }
303   *p++ = '"';
304   *p++ = ')';
305   *p++ = '\n';
306   *p = 0;
307
308   if (shutup) _festival_write ("(audio_mode'shutup)\n", fd);
309   if (voice && (strncmp (voice, (char *) (voice_spec+1), strlen(voice))))
310     {
311       snprintf (voice_spec, 32, "(%s)\n", voice); 
312       _festival_write (voice_spec, fd);
313       _festival_write ("(Parameter.set 'Duration_Model 'Tree_ZScore)\n", fd);
314       _festival_write ("(Parameter.set 'Duration_Stretch 0.75)\n", fd);
315     }
316
317   _festival_write (quoted, fd);
318
319   g_free(quoted);
320 }
321
322 static void _festival_write (const gchar *command_string, int fd)
323 {
324   fprintf(stderr, command_string);
325   if (fd < 0) {
326     perror("socket");
327     return;
328   }
329   write(fd, command_string, strlen(command_string));
330 }
331