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