2003-03-07 Padraig O'Briain <padraig.obriain@sun.com>
[platform/core/uifw/at-spi2-atk.git] / test / event-listener-test.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001, 2002, 2003 Sun Microsystems Inc.,
6  * Copyright 2001, 2002, 2003 Ximian, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include "../cspi/spi-private.h" /* A hack for now */
27
28 static void traverse_accessible_tree (Accessible *accessible);
29
30 static void report_event  (const AccessibleEvent *event, void *user_data);
31 static void report_detail_event  (const AccessibleEvent *event, void *user_data);
32 static void report_detail1_event  (const AccessibleEvent *event, void *user_data);
33 static void report_text_event  (const AccessibleEvent *event, void *user_data);
34 static void report_children_changed_event (const AccessibleEvent *event, void *user_data);
35 static void timing_test_event (const AccessibleEvent *event, void *user_data);
36 static SPIBoolean report_mouse_event  (const AccessibleDeviceEvent *event, void *user_data);
37
38 static AccessibleEventListener *generic_listener;
39 static AccessibleEventListener *specific_listener;
40 static AccessibleEventListener *detail1_listener;
41 static AccessibleEventListener *test_listener;
42 static AccessibleEventListener *text_listener;
43 static AccessibleEventListener *children_changed_listener;
44 static AccessibleDeviceListener *mouse_device_listener;
45 static gint n_elements_traversed = 0;
46 static GTimer *timer;
47
48 static gboolean report_mouse_events = TRUE;
49
50 void 
51 usage_and_exit( void )
52 {
53   g_print("\nUsage: event-listener-test [-h] [-m]\n");
54   g_print("       -h    : prints this usage message.\n");
55   g_print("       -m    : disable mouse event reporting.\n\n");
56
57   exit( 1 );
58 }
59
60 int
61 main (int argc, char **argv)
62 {
63   int i, j, c;
64   int n_desktops;
65   int n_apps;
66   char *s;
67   gdouble elapsed_time;
68   Accessible *desktop;
69   Accessible *application;
70   const char *modules;
71
72   /* Parse Command-line */
73   if ( argc > 1 ) {
74       while ( ( c = getopt( argc, argv, "hm")) != EOF ) {
75           switch( c ) {
76               case 'm':
77                   report_mouse_events = FALSE;
78                   break;
79               default:
80                   usage_and_exit();
81                   break;
82           }
83       }
84       if ( optind < argc ) {
85           usage_and_exit();
86       }
87   }
88
89   fprintf (stderr, "RUNNING\n");
90
91   SPI_init ();
92
93   generic_listener = SPI_createAccessibleEventListener (
94           report_event, NULL); 
95   specific_listener = SPI_createAccessibleEventListener (
96           report_detail_event, NULL); 
97   text_listener = SPI_createAccessibleEventListener (
98           report_text_event, NULL);
99   children_changed_listener = SPI_createAccessibleEventListener (
100           report_children_changed_event, NULL);
101   test_listener = SPI_createAccessibleEventListener (
102           timing_test_event, NULL);
103   mouse_device_listener = SPI_createAccessibleDeviceListener (
104           report_mouse_event, NULL);
105   detail1_listener = SPI_createAccessibleEventListener (
106           report_detail1_event, NULL); 
107
108   SPI_registerGlobalEventListener (generic_listener,
109                                    "focus:");
110   if ( report_mouse_events ) {
111       SPI_registerGlobalEventListener (specific_listener,
112                                        "mouse:rel");
113       SPI_registerGlobalEventListener (specific_listener,
114                                        "mouse:button");
115       SPI_registerGlobalEventListener (specific_listener,
116                                        "mouse:abs");
117   }
118   SPI_registerDeviceEventListener (mouse_device_listener, 
119                                    SPI_BUTTON_PRESSED | SPI_BUTTON_RELEASED,
120                                    NULL);
121   SPI_registerGlobalEventListener (specific_listener,
122                                    "keyboard:modifiers");
123   SPI_registerGlobalEventListener (generic_listener,
124                                    "object:property-change");
125 /*  SPI_registerGlobalEventListener (specific_listener,
126     "object:property-change:accessible-name");*/
127   SPI_registerGlobalEventListener (generic_listener,
128                                    "object:state-changed"); 
129 /*  SPI_registerGlobalEventListener (specific_listener,
130     "object:state-changed:focused"); */
131   SPI_registerGlobalEventListener (generic_listener,
132                                    "object:selection-changed"); 
133   SPI_registerGlobalEventListener (children_changed_listener,
134                                    "object:children-changed"); 
135   SPI_registerGlobalEventListener (generic_listener,
136                                    "object:active-descendant"); 
137   SPI_registerGlobalEventListener (generic_listener,
138                                    "object:visible-data-changed"); 
139   SPI_registerGlobalEventListener (generic_listener,
140                                    "object:text-selection-changed"); 
141
142   SPI_registerGlobalEventListener (generic_listener,
143                                    "object:text-caret-moved"); 
144   SPI_registerGlobalEventListener (text_listener,
145                                    "object:text-changed"); 
146   SPI_registerGlobalEventListener (generic_listener,
147                                    "object:column-inserted"); 
148   SPI_registerGlobalEventListener (generic_listener,
149                                    "object:row-inserted"); 
150   SPI_registerGlobalEventListener (generic_listener,
151                                    "object:column-reordered"); 
152   SPI_registerGlobalEventListener (generic_listener,
153                                    "object:row-reordered"); 
154   SPI_registerGlobalEventListener (generic_listener,
155                                    "object:column-deleted"); 
156   SPI_registerGlobalEventListener (generic_listener,
157                                    "object:row-deleted"); 
158   SPI_registerGlobalEventListener (generic_listener,
159                                    "object:model-changed"); 
160   SPI_registerGlobalEventListener (detail1_listener,
161                                    "object:link-selected"); 
162   SPI_registerGlobalEventListener (generic_listener,
163                                    "window:minimize");
164   SPI_registerGlobalEventListener (generic_listener,
165                                    "window:maximize");
166   SPI_registerGlobalEventListener (generic_listener,
167                                    "window:restore");
168   SPI_registerGlobalEventListener (generic_listener,
169                                    "window:activate");
170   SPI_registerGlobalEventListener (generic_listener,
171                                    "window:deactivate");
172   SPI_registerGlobalEventListener (generic_listener,
173                                    "window:close");
174   SPI_registerGlobalEventListener (generic_listener,
175                                    "window:lower");
176   SPI_registerGlobalEventListener (generic_listener,
177                                    "window:raise");
178   SPI_registerGlobalEventListener (generic_listener,
179                                    "window:resize");
180   SPI_registerGlobalEventListener (generic_listener,
181                                    "window:shade");
182   SPI_registerGlobalEventListener (generic_listener,
183                                    "window:unshade");
184   SPI_registerGlobalEventListener (test_listener,
185                                    "object:test");
186 #ifdef NOT_YET_IMPLEMENTED
187   /* event below possibly should just be property change? */
188   SPI_registerGlobalEventListener (generic_listener,
189                                    "window:restyle"); 
190   SPI_registerGlobalEventListener (generic_listener,
191                                    "window:desktop-create");
192   SPI_registerGlobalEventListener (generic_listener,
193                                    "window:desktop-destroy");
194 #endif
195   
196   timer = g_timer_new ();
197   traverse_accessible_tree (SPI_getDesktop (0));
198   g_print ("Time for first traversal of %d elements: %lf\n", 
199            n_elements_traversed,
200            g_timer_elapsed (timer, NULL));
201   g_timer_start (timer);
202   traverse_accessible_tree (SPI_getDesktop (0));
203   g_timer_stop (timer);
204   g_print ("Time for subsequent traversal %f\n", g_timer_elapsed (timer, NULL));
205   g_print ("[%f elements/sec, %f SPI calls/sec]\n", 
206         n_elements_traversed/g_timer_elapsed(timer, NULL),
207         (n_elements_traversed*8+1)/g_timer_elapsed(timer, NULL));
208   g_timer_reset (timer);
209   SPI_event_main ();
210
211   putenv ("AT_BRIDGE_SHUTDOWN=1");
212
213   /*
214    * TODO: Add a key event listener that calls test_exit, to
215    * deregister and cleanup appropriately.
216    */
217
218   return SPI_exit ();
219 }
220
221 static void
222 traverse_accessible_tree (Accessible *accessible)
223 {
224         int n_children;
225         int i;
226         char *name;
227         char *role_name;
228         Accessible *child;
229         
230         n_elements_traversed++;
231         name = Accessible_getName (accessible);
232         role_name = Accessible_getRoleName (accessible);
233 #ifdef VERBOSE
234         fprintf (stdout, "[%s] \"%s\"\n",
235                  role_name, name);
236 #endif
237         SPI_freeString (name);
238         SPI_freeString (role_name);
239         n_children = Accessible_getChildCount (accessible);
240         if (!Accessible_isTable (accessible)) 
241         {
242                 for (i = 0; i < n_children; ++i)
243                 {
244                         child = Accessible_getChildAtIndex (accessible, i);
245                         traverse_accessible_tree (child);
246                         Accessible_unref (child);
247                 }
248         }
249 }
250
251 void
252 report_event (const AccessibleEvent *event, void *user_data)
253 {
254   static long count = 0;
255   char *s = Accessible_getName (event->source);
256   fprintf (stderr, "%s %s\n", event->type, s);
257   if (s) SPI_freeString (s);
258   if (count == 0) {
259           g_timer_reset (timer);
260           g_timer_start (timer);
261   }
262   ++count;
263   if ((count % 100) == 0) {
264           g_print ("%d events received, %f events/sec\n",
265                    count,
266                    count/g_timer_elapsed(timer, NULL));
267   }
268 }
269
270 void
271 report_detail_event (const AccessibleEvent *event, void *user_data)
272 {
273   char *s = Accessible_getName (event->source);
274   fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
275            event->detail1, event->detail2);
276   if (s) SPI_freeString (s);
277 }
278
279 void
280 report_detail1_event (const AccessibleEvent *event, void *user_data)
281 {
282   char *s = Accessible_getName (event->source);
283   fprintf (stderr, "(detail) %s %s %d\n", event->type, s,
284            event->detail1);
285   if (s) SPI_freeString (s);
286 }
287
288 void
289 report_text_event (const AccessibleEvent *event, void *user_data)
290 {
291   char *s = Accessible_getName (event->source);
292   fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
293            event->detail1, event->detail2);
294   SPI_freeString (s);
295   s = AccessibleTextChangedEvent_getChangeString (event);
296   fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
297   SPI_freeString (s);
298 }
299
300 void
301 report_children_changed_event (const AccessibleEvent *event, void *user_data)
302 {
303   char *s = Accessible_getName (event->source);
304   char *s1;
305   Accessible *ao;
306
307   ao = AccessibleChildChangedEvent_getChildAccessible (event);
308   s1 = Accessible_getName (ao);
309   fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type, 
310            s ? s : "<null>", s1 ? s1 : "<null>",
311            event->detail1, event->detail2);
312   SPI_freeString (s);
313   SPI_freeString (s1);
314   Accessible_unref (ao);
315 }
316
317 SPIBoolean
318 report_mouse_event (const AccessibleDeviceEvent *event, void *user_data)
319 {
320   fprintf (stderr, "mouse event %ld %d %x %x\n", 
321            event->keyID, 
322            (int) event->keycode,
323            (unsigned) event->type,
324            (unsigned) event->modifiers);
325   return FALSE;
326 }
327
328 void
329 timing_test_event (const AccessibleEvent *event, void *user_data)
330 {
331         static long count = 0;
332         if (count == 0) g_timer_start (timer);
333         ++count;
334         if ((count % 500) == 0) {
335                 g_print ("%d events received, %f events/sec\n",
336                          count,
337                          count/g_timer_elapsed(timer, NULL));
338         }
339 }
340
341 void
342 test_exit ()
343 {
344   SPI_deregisterGlobalEventListenerAll (generic_listener);
345   AccessibleEventListener_unref (generic_listener);
346   SPI_deregisterGlobalEventListenerAll (specific_listener);
347   AccessibleEventListener_unref (specific_listener);
348 }