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