2 * AT-SPI - Assistive Technology Service Provider Interface
3 * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
5 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.,
6 * Copyright 2001, 2002, 2003 Ximian, Inc.
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.
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.
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.
27 #include "../cspi/spi-private.h" /* A hack for now */
29 static void traverse_accessible_tree (Accessible *accessible);
31 static void report_event (const AccessibleEvent *event, void *user_data);
32 static void report_detail_event (const AccessibleEvent *event, void *user_data);
33 static void report_detail1_event (const AccessibleEvent *event, void *user_data);
34 static void report_text_event (const AccessibleEvent *event, void *user_data);
35 static void report_text_selection_event (const AccessibleEvent *event, void *user_data);
36 static void report_active_descendant_event (const AccessibleEvent *event, void *user_data);
37 static void report_children_changed_event (const AccessibleEvent *event, void *user_data);
38 static void report_name_changed_event (const AccessibleEvent *event, void *user_data);
39 static void report_description_changed_event (const AccessibleEvent *event, void *user_data);
40 static void report_parent_changed_event (const AccessibleEvent *event, void *user_data);
41 static void report_window_event (const AccessibleEvent *event, void *user_data);
42 static void report_table_summary_event (const AccessibleEvent *event, void *user_data);
43 static void report_table_header_event (const AccessibleEvent *event, void *user_data);
44 static void report_table_caption_event (const AccessibleEvent *event, void *user_data);
45 static void report_table_row_description_event (const AccessibleEvent *event, void *user_data);
46 static void report_table_column_description_event (const AccessibleEvent *event, void *user_data);
47 static void timing_test_event (const AccessibleEvent *event, void *user_data);
48 static SPIBoolean report_mouse_event (const AccessibleDeviceEvent *event, void *user_data);
50 static AccessibleEventListener *generic_listener;
51 static AccessibleEventListener *specific_listener;
52 static AccessibleEventListener *detail1_listener;
53 static AccessibleEventListener *test_listener;
54 static AccessibleEventListener *text_listener;
55 static AccessibleEventListener *text_selection_listener;
56 static AccessibleEventListener *active_descendant_listener;
57 static AccessibleEventListener *children_changed_listener;
58 static AccessibleEventListener *name_changed_listener;
59 static AccessibleEventListener *description_changed_listener;
60 static AccessibleEventListener *parent_changed_listener;
61 static AccessibleEventListener *window_listener;
62 static AccessibleEventListener *table_summary_listener;
63 static AccessibleEventListener *table_header_listener;
64 static AccessibleEventListener *table_caption_listener;
65 static AccessibleEventListener *table_row_description_listener;
66 static AccessibleEventListener *table_column_description_listener;
67 static AccessibleDeviceListener *mouse_device_listener;
68 static gint n_elements_traversed = 0;
71 static gboolean report_mouse_events = TRUE;
74 usage_and_exit( void )
76 g_print("\nUsage: event-listener-test [-h] [-m]\n");
77 g_print(" -h : prints this usage message.\n");
78 g_print(" -m : disable mouse event reporting.\n\n");
84 main (int argc, char **argv)
92 Accessible *application;
95 /* Parse Command-line */
97 while ( ( c = getopt( argc, argv, "hm")) != EOF ) {
100 report_mouse_events = FALSE;
107 if ( optind < argc ) {
112 fprintf (stderr, "RUNNING\n");
116 generic_listener = SPI_createAccessibleEventListener (
118 specific_listener = SPI_createAccessibleEventListener (
119 report_detail_event, NULL);
120 text_listener = SPI_createAccessibleEventListener (
121 report_text_event, NULL);
122 text_selection_listener = SPI_createAccessibleEventListener (
123 report_text_selection_event, NULL);
124 active_descendant_listener = SPI_createAccessibleEventListener (
125 report_active_descendant_event, NULL);
126 children_changed_listener = SPI_createAccessibleEventListener (
127 report_children_changed_event, NULL);
128 name_changed_listener = SPI_createAccessibleEventListener (
129 report_name_changed_event, NULL);
130 description_changed_listener = SPI_createAccessibleEventListener (
131 report_description_changed_event, NULL);
132 parent_changed_listener = SPI_createAccessibleEventListener (
133 report_parent_changed_event, NULL);
134 window_listener = SPI_createAccessibleEventListener (
135 report_window_event, NULL);
136 table_summary_listener = SPI_createAccessibleEventListener (
137 report_table_summary_event, NULL);
138 table_header_listener = SPI_createAccessibleEventListener (
139 report_table_header_event, NULL);
140 table_caption_listener = SPI_createAccessibleEventListener (
141 report_table_caption_event, NULL);
142 table_row_description_listener = SPI_createAccessibleEventListener (
143 report_table_row_description_event, NULL);
144 table_column_description_listener = SPI_createAccessibleEventListener (
145 report_table_column_description_event, NULL);
146 test_listener = SPI_createAccessibleEventListener (
147 timing_test_event, NULL);
148 mouse_device_listener = SPI_createAccessibleDeviceListener (
149 report_mouse_event, NULL);
150 detail1_listener = SPI_createAccessibleEventListener (
151 report_detail1_event, NULL);
153 SPI_registerGlobalEventListener (generic_listener,
155 if ( report_mouse_events ) {
156 SPI_registerGlobalEventListener (specific_listener,
158 SPI_registerGlobalEventListener (specific_listener,
160 SPI_registerGlobalEventListener (specific_listener,
163 SPI_registerDeviceEventListener (mouse_device_listener,
164 SPI_BUTTON_PRESSED | SPI_BUTTON_RELEASED,
166 SPI_registerGlobalEventListener (specific_listener,
167 "keyboard:modifiers");
168 SPI_registerGlobalEventListener (generic_listener,
169 "object:property-change");
170 SPI_registerGlobalEventListener (name_changed_listener,
171 "object:property-change:accessible-name");
172 SPI_registerGlobalEventListener (description_changed_listener,
173 "object:property-change:accessible-description");
174 SPI_registerGlobalEventListener (parent_changed_listener,
175 "object:property-change:accessible-parent");
176 SPI_registerGlobalEventListener (generic_listener,
177 "object:state-changed");
178 /* SPI_registerGlobalEventListener (specific_listener,
179 "object:state-changed:focused"); */
180 SPI_registerGlobalEventListener (generic_listener,
181 "object:selection-changed");
182 SPI_registerGlobalEventListener (children_changed_listener,
183 "object:children-changed");
184 SPI_registerGlobalEventListener (active_descendant_listener,
185 "object:active-descendant");
186 SPI_registerGlobalEventListener (generic_listener,
187 "object:visible-data-changed");
188 SPI_registerGlobalEventListener (text_selection_listener,
189 "object:text-selection-changed");
191 SPI_registerGlobalEventListener (generic_listener,
192 "object:text-caret-moved");
193 SPI_registerGlobalEventListener (text_listener,
194 "object:text-changed");
195 SPI_registerGlobalEventListener (generic_listener,
196 "object:column-inserted");
197 SPI_registerGlobalEventListener (generic_listener,
198 "object:row-inserted");
199 SPI_registerGlobalEventListener (generic_listener,
200 "object:column-reordered");
201 SPI_registerGlobalEventListener (generic_listener,
202 "object:row-reordered");
203 SPI_registerGlobalEventListener (generic_listener,
204 "object:column-deleted");
205 SPI_registerGlobalEventListener (generic_listener,
206 "object:row-deleted");
207 SPI_registerGlobalEventListener (generic_listener,
208 "object:model-changed");
209 SPI_registerGlobalEventListener (detail1_listener,
210 "object:link-selected");
211 SPI_registerGlobalEventListener (window_listener,
213 SPI_registerGlobalEventListener (window_listener,
215 SPI_registerGlobalEventListener (window_listener,
217 SPI_registerGlobalEventListener (window_listener,
219 SPI_registerGlobalEventListener (window_listener,
220 "window:deactivate");
221 SPI_registerGlobalEventListener (window_listener,
223 SPI_registerGlobalEventListener (window_listener,
225 SPI_registerGlobalEventListener (window_listener,
227 SPI_registerGlobalEventListener (window_listener,
229 SPI_registerGlobalEventListener (window_listener,
231 SPI_registerGlobalEventListener (window_listener,
233 SPI_registerGlobalEventListener (table_summary_listener,
234 "object:property-change:accessible-table-summary");
235 SPI_registerGlobalEventListener (table_header_listener,
236 "object:property-change:accessible-table-row-header");
237 SPI_registerGlobalEventListener (table_header_listener,
238 "object:property-change:accessible-table-column-header");
239 SPI_registerGlobalEventListener (table_summary_listener,
240 "object:property-change:accessible-table-summary");
241 SPI_registerGlobalEventListener (table_row_description_listener,
242 "object:property-change:accessible-table-row-description");
243 SPI_registerGlobalEventListener (table_column_description_listener,
244 "object:property-change:accessible-table-column-description");
245 SPI_registerGlobalEventListener (test_listener,
247 #ifdef NOT_YET_IMPLEMENTED
248 /* event below possibly should just be property change? */
249 SPI_registerGlobalEventListener (generic_listener,
251 SPI_registerGlobalEventListener (generic_listener,
252 "window:desktop-create");
253 SPI_registerGlobalEventListener (generic_listener,
254 "window:desktop-destroy");
257 timer = g_timer_new ();
258 traverse_accessible_tree (SPI_getDesktop (0));
259 g_print ("Time for first traversal of %d elements: %lf\n",
260 n_elements_traversed,
261 g_timer_elapsed (timer, NULL));
262 g_timer_start (timer);
263 traverse_accessible_tree (SPI_getDesktop (0));
264 g_timer_stop (timer);
265 g_print ("Time for subsequent traversal %f\n", g_timer_elapsed (timer, NULL));
266 g_print ("[%f elements/sec, %f SPI calls/sec]\n",
267 n_elements_traversed/g_timer_elapsed(timer, NULL),
268 (n_elements_traversed*8+1)/g_timer_elapsed(timer, NULL));
269 g_timer_reset (timer);
272 putenv ("AT_BRIDGE_SHUTDOWN=1");
275 * TODO: Add a key event listener that calls test_exit, to
276 * deregister and cleanup appropriately.
283 traverse_accessible_tree (Accessible *accessible)
291 n_elements_traversed++;
292 name = Accessible_getName (accessible);
293 role_name = Accessible_getRoleName (accessible);
295 fprintf (stdout, "[%s] \"%s\"\n",
298 SPI_freeString (name);
299 SPI_freeString (role_name);
300 n_children = Accessible_getChildCount (accessible);
301 if (!Accessible_isTable (accessible))
303 for (i = 0; i < n_children; ++i)
305 child = Accessible_getChildAtIndex (accessible, i);
306 traverse_accessible_tree (child);
307 Accessible_unref (child);
313 report_event (const AccessibleEvent *event, void *user_data)
315 static long count = 0;
316 char *s = Accessible_getName (event->source);
317 fprintf (stderr, "%s %s\n", event->type, s);
318 if (s) SPI_freeString (s);
320 g_timer_reset (timer);
321 g_timer_start (timer);
324 if ((count % 100) == 0) {
325 g_print ("%d events received, %f events/sec\n",
327 count/g_timer_elapsed(timer, NULL));
332 report_detail_event (const AccessibleEvent *event, void *user_data)
334 char *s = Accessible_getName (event->source);
335 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
336 event->detail1, event->detail2);
337 if (s) SPI_freeString (s);
341 report_detail1_event (const AccessibleEvent *event, void *user_data)
343 char *s = Accessible_getName (event->source);
344 fprintf (stderr, "(detail) %s %s %d\n", event->type, s,
346 if (s) SPI_freeString (s);
350 report_text_event (const AccessibleEvent *event, void *user_data)
352 char *s = Accessible_getName (event->source);
353 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
354 event->detail1, event->detail2);
356 s = AccessibleTextChangedEvent_getChangeString (event);
357 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
362 report_text_selection_event (const AccessibleEvent *event, void *user_data)
364 char *s = Accessible_getName (event->source);
365 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
366 event->detail1, event->detail2);
368 s = AccessibleTextSelectionChangedEvent_getSelectionString (event);
369 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
374 report_active_descendant_event (const AccessibleEvent *event, void *user_data)
376 char *s = Accessible_getName (event->source);
380 ao = AccessibleActiveDescendantChangedEvent_getActiveDescendant (event);
381 s1 = Accessible_getName (ao);
382 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
383 s ? s : "<null>", s1 ? s1 : "<null>",
384 event->detail1, event->detail2);
387 Accessible_unref (ao);
390 report_children_changed_event (const AccessibleEvent *event, void *user_data)
392 char *s = Accessible_getName (event->source);
396 ao = AccessibleChildChangedEvent_getChildAccessible (event);
397 s1 = Accessible_getName (ao);
398 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
399 s ? s : "<null>", s1 ? s1 : "<null>",
400 event->detail1, event->detail2);
403 Accessible_unref (ao);
407 report_name_changed_event (const AccessibleEvent *event, void *user_data)
409 char *s = Accessible_getName (event->source);
410 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
411 event->detail1, event->detail2);
413 s = AccessibleNameChangedEvent_getNameString (event);
414 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
419 report_description_changed_event (const AccessibleEvent *event, void *user_data)
421 char *s = Accessible_getName (event->source);
422 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
423 event->detail1, event->detail2);
425 s = AccessibleDescriptionChangedEvent_getDescriptionString (event);
426 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
431 report_parent_changed_event (const AccessibleEvent *event, void *user_data)
433 char *s = Accessible_getName (event->source);
437 ao = AccessibleParentChangedEvent_getParentAccessible (event);
438 s1 = Accessible_getName (ao);
439 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
440 s ? s : "<null>", s1 ? s1 : "<null>",
441 event->detail1, event->detail2);
444 Accessible_unref (ao);
448 report_window_event (const AccessibleEvent *event, void *user_data)
450 char *s = Accessible_getName (event->source);
451 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
452 event->detail1, event->detail2);
454 s = AccessibleWindowEvent_getTitleString (event);
455 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
460 report_table_summary_event (const AccessibleEvent *event, void *user_data)
462 char *s = Accessible_getName (event->source);
466 ao = AccessibleTableSummaryChangedEvent_getSummaryAccessible (event);
467 s1 = Accessible_getName (ao);
468 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
469 s ? s : "<null>", s1 ? s1 : "<null>",
470 event->detail1, event->detail2);
473 Accessible_unref (ao);
477 report_table_header_event (const AccessibleEvent *event, void *user_data)
479 char *s = Accessible_getName (event->source);
483 ao = AccessibleTableHeaderChangedEvent_getHeaderAccessible (event);
484 s1 = Accessible_getName (ao);
485 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
486 s ? s : "<null>", s1 ? s1 : "<null>",
487 event->detail1, event->detail2);
490 Accessible_unref (ao);
494 report_table_caption_event (const AccessibleEvent *event, void *user_data)
496 char *s = Accessible_getName (event->source);
497 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
498 event->detail1, event->detail2);
500 s = AccessibleTableCaptionChangedEvent_getCaptionString (event);
501 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
506 report_table_row_description_event (const AccessibleEvent *event, void *user_data)
508 char *s = Accessible_getName (event->source);
509 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
510 event->detail1, event->detail2);
512 s = AccessibleTableRowDescriptionChangedEvent_getDescriptionString (event);
513 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
518 report_table_column_description_event (const AccessibleEvent *event, void *user_data)
520 char *s = Accessible_getName (event->source);
521 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
522 event->detail1, event->detail2);
524 s = AccessibleTableColumnDescriptionChangedEvent_getDescriptionString (event);
525 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
530 report_mouse_event (const AccessibleDeviceEvent *event, void *user_data)
532 fprintf (stderr, "mouse event %ld %d %x %x\n",
534 (int) event->keycode,
535 (unsigned) event->type,
536 (unsigned) event->modifiers);
541 timing_test_event (const AccessibleEvent *event, void *user_data)
543 static long count = 0;
544 if (count == 0) g_timer_start (timer);
546 if ((count % 500) == 0) {
547 g_print ("%d events received, %f events/sec\n",
549 count/g_timer_elapsed(timer, NULL));
556 SPI_deregisterGlobalEventListenerAll (generic_listener);
557 AccessibleEventListener_unref (generic_listener);
558 SPI_deregisterGlobalEventListenerAll (specific_listener);
559 AccessibleEventListener_unref (specific_listener);