2003-02-14 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 timing_test_event (const AccessibleEvent *event, void *user_data);
35 static SPIBoolean report_mouse_event  (const AccessibleDeviceEvent *event, void *user_data);
36
37 static AccessibleEventListener *generic_listener;
38 static AccessibleEventListener *specific_listener;
39 static AccessibleEventListener *detail1_listener;
40 static AccessibleEventListener *test_listener;
41 static AccessibleEventListener *text_listener;
42 static AccessibleDeviceListener *mouse_device_listener;
43 static gint n_elements_traversed = 0;
44 static GTimer *timer;
45
46 static gboolean report_mouse_events = TRUE;
47
48 void 
49 usage_and_exit( void )
50 {
51   g_print("\nUsage: event-listener-test [-h] [-m]\n");
52   g_print("       -h    : prints this usage message.\n");
53   g_print("       -m    : disable mouse event reporting.\n\n");
54
55   exit( 1 );
56 }
57
58 int
59 main (int argc, char **argv)
60 {
61   int i, j, c;
62   int n_desktops;
63   int n_apps;
64   char *s;
65   gdouble elapsed_time;
66   Accessible *desktop;
67   Accessible *application;
68   const char *modules;
69
70   /* Parse Command-line */
71   if ( argc > 1 ) {
72       while ( ( c = getopt( argc, argv, "hm")) != EOF ) {
73           switch( c ) {
74               case 'm':
75                   report_mouse_events = FALSE;
76                   break;
77               default:
78                   usage_and_exit();
79                   break;
80           }
81       }
82       if ( optind < argc ) {
83           usage_and_exit();
84       }
85   }
86
87   fprintf (stderr, "RUNNING\n");
88
89   SPI_init ();
90
91   generic_listener = SPI_createAccessibleEventListener (
92           report_event, NULL); 
93   specific_listener = SPI_createAccessibleEventListener (
94           report_detail_event, NULL); 
95   text_listener = SPI_createAccessibleEventListener (
96           report_text_event, NULL);
97   test_listener = SPI_createAccessibleEventListener (
98           timing_test_event, NULL);
99   mouse_device_listener = SPI_createAccessibleDeviceListener (
100           report_mouse_event, NULL);
101   detail1_listener = SPI_createAccessibleEventListener (
102           report_detail1_event, NULL); 
103
104   SPI_registerGlobalEventListener (generic_listener,
105                                    "focus:");
106   if ( report_mouse_events ) {
107       SPI_registerGlobalEventListener (specific_listener,
108                                        "mouse:rel");
109       SPI_registerGlobalEventListener (specific_listener,
110                                        "mouse:button");
111       SPI_registerGlobalEventListener (specific_listener,
112                                        "mouse:abs");
113   }
114   SPI_registerDeviceEventListener (mouse_device_listener, 
115                                    SPI_BUTTON_PRESSED | SPI_BUTTON_RELEASED,
116                                    NULL);
117   SPI_registerGlobalEventListener (specific_listener,
118                                    "keyboard:modifiers");
119   SPI_registerGlobalEventListener (generic_listener,
120                                    "object:property-change");
121 /*  SPI_registerGlobalEventListener (specific_listener,
122     "object:property-change:accessible-name");*/
123   SPI_registerGlobalEventListener (generic_listener,
124                                    "object:state-changed"); 
125 /*  SPI_registerGlobalEventListener (specific_listener,
126     "object:state-changed:focused"); */
127   SPI_registerGlobalEventListener (generic_listener,
128                                    "object:selection-changed"); 
129   SPI_registerGlobalEventListener (generic_listener,
130                                    "object:children-changed"); 
131 /*  SPI_registerGlobalEventListener (specific_listener,
132     "object:children-changed:add"); */
133   SPI_registerGlobalEventListener (generic_listener,
134                                    "object:active-descendant"); 
135   SPI_registerGlobalEventListener (generic_listener,
136                                    "object:visible-data-changed"); 
137   SPI_registerGlobalEventListener (generic_listener,
138                                    "object:text-selection-changed"); 
139
140   SPI_registerGlobalEventListener (generic_listener,
141                                    "object:text-caret-moved"); 
142   SPI_registerGlobalEventListener (text_listener,
143                                    "object:text-changed"); 
144   SPI_registerGlobalEventListener (generic_listener,
145                                    "object:column-inserted"); 
146   SPI_registerGlobalEventListener (generic_listener,
147                                    "object:row-inserted"); 
148   SPI_registerGlobalEventListener (generic_listener,
149                                    "object:column-reordered"); 
150   SPI_registerGlobalEventListener (generic_listener,
151                                    "object:row-reordered"); 
152   SPI_registerGlobalEventListener (generic_listener,
153                                    "object:column-deleted"); 
154   SPI_registerGlobalEventListener (generic_listener,
155                                    "object:row-deleted"); 
156   SPI_registerGlobalEventListener (generic_listener,
157                                    "object:model-changed"); 
158   SPI_registerGlobalEventListener (detail1_listener,
159                                    "object:link-selected"); 
160   SPI_registerGlobalEventListener (generic_listener,
161                                    "window:minimize");
162   SPI_registerGlobalEventListener (generic_listener,
163                                    "window:maximize");
164   SPI_registerGlobalEventListener (generic_listener,
165                                    "window:restore");
166   SPI_registerGlobalEventListener (generic_listener,
167                                    "window:activate");
168   SPI_registerGlobalEventListener (generic_listener,
169                                    "window:deactivate");
170   SPI_registerGlobalEventListener (generic_listener,
171                                    "window:close");
172   SPI_registerGlobalEventListener (generic_listener,
173                                    "window:lower");
174   SPI_registerGlobalEventListener (generic_listener,
175                                    "window:raise");
176   SPI_registerGlobalEventListener (generic_listener,
177                                    "window:resize");
178   SPI_registerGlobalEventListener (generic_listener,
179                                    "window:shade");
180   SPI_registerGlobalEventListener (generic_listener,
181                                    "window:unshade");
182   SPI_registerGlobalEventListener (test_listener,
183                                    "object:test");
184 #ifdef NOT_YET_IMPLEMENTED
185   /* event below possibly should just be property change? */
186   SPI_registerGlobalEventListener (generic_listener,
187                                    "window:restyle"); 
188   SPI_registerGlobalEventListener (generic_listener,
189                                    "window:desktop-create");
190   SPI_registerGlobalEventListener (generic_listener,
191                                    "window:desktop-destroy");
192 #endif
193   
194   timer = g_timer_new ();
195   traverse_accessible_tree (SPI_getDesktop (0));
196   g_print ("Time for first traversal of %d elements: %lf\n", 
197            n_elements_traversed,
198            g_timer_elapsed (timer, NULL));
199   g_timer_start (timer);
200   traverse_accessible_tree (SPI_getDesktop (0));
201   g_timer_stop (timer);
202   g_print ("Time for subsequent traversal %f\n", g_timer_elapsed (timer, NULL));
203   g_print ("[%f elements/sec, %f SPI calls/sec]\n", 
204         n_elements_traversed/g_timer_elapsed(timer, NULL),
205         (n_elements_traversed*8+1)/g_timer_elapsed(timer, NULL));
206   g_timer_reset (timer);
207   SPI_event_main ();
208
209   putenv ("AT_BRIDGE_SHUTDOWN=1");
210
211   /*
212    * TODO: Add a key event listener that calls test_exit, to
213    * deregister and cleanup appropriately.
214    */
215
216   return SPI_exit ();
217 }
218
219 static void
220 traverse_accessible_tree (Accessible *accessible)
221 {
222         int n_children;
223         int i;
224         char *name;
225         char *role_name;
226         Accessible *child;
227         
228         n_elements_traversed++;
229         name = Accessible_getName (accessible);
230         role_name = Accessible_getRoleName (accessible);
231 #ifdef VERBOSE
232         fprintf (stdout, "[%s] \"%s\"\n",
233                  role_name, name);
234 #endif
235         SPI_freeString (name);
236         SPI_freeString (role_name);
237         n_children = Accessible_getChildCount (accessible);
238         if (!Accessible_isTable (accessible)) 
239         {
240                 for (i = 0; i < n_children; ++i)
241                 {
242                         child = Accessible_getChildAtIndex (accessible, i);
243                         traverse_accessible_tree (child);
244                         Accessible_unref (child);
245                 }
246         }
247 }
248
249 void
250 report_event (const AccessibleEvent *event, void *user_data)
251 {
252   static long count = 0;
253   char *s = Accessible_getName (event->source);
254   fprintf (stderr, "%s %s\n", event->type, s);
255   if (s) SPI_freeString (s);
256   if (count == 0) {
257           g_timer_reset (timer);
258           g_timer_start (timer);
259   }
260   ++count;
261   if ((count % 100) == 0) {
262           g_print ("%d events received, %f events/sec\n",
263                    count,
264                    count/g_timer_elapsed(timer, NULL));
265   }
266 }
267
268 void
269 report_detail_event (const AccessibleEvent *event, void *user_data)
270 {
271   char *s = Accessible_getName (event->source);
272   fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
273            event->detail1, event->detail2);
274   if (s) SPI_freeString (s);
275 }
276
277 void
278 report_detail1_event (const AccessibleEvent *event, void *user_data)
279 {
280   char *s = Accessible_getName (event->source);
281   fprintf (stderr, "(detail) %s %s %d\n", event->type, s,
282            event->detail1);
283   if (s) SPI_freeString (s);
284 }
285
286 void
287 report_text_event (const AccessibleEvent *event, void *user_data)
288 {
289   char *s = Accessible_getName (event->source);
290   fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
291            event->detail1, event->detail2);
292   if (s) SPI_freeString (s);
293   s = AccessibleTextChangedEvent_getChangeString (event);
294   fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
295 }
296
297 SPIBoolean
298 report_mouse_event (const AccessibleDeviceEvent *event, void *user_data)
299 {
300   fprintf (stderr, "mouse event %ld %d %x %x\n", 
301            event->keyID, 
302            (int) event->keycode,
303            (unsigned) event->type,
304            (unsigned) event->modifiers);
305   return FALSE;
306 }
307
308 void
309 timing_test_event (const AccessibleEvent *event, void *user_data)
310 {
311         static long count = 0;
312         if (count == 0) g_timer_start (timer);
313         ++count;
314         if ((count % 500) == 0) {
315                 g_print ("%d events received, %f events/sec\n",
316                          count,
317                          count/g_timer_elapsed(timer, NULL));
318         }
319 }
320
321 void
322 test_exit ()
323 {
324   SPI_deregisterGlobalEventListenerAll (generic_listener);
325   AccessibleEventListener_unref (generic_listener);
326   SPI_deregisterGlobalEventListenerAll (specific_listener);
327   AccessibleEventListener_unref (specific_listener);
328 }