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.
26 #include "../cspi/spi-private.h" /* A hack for now */
28 static void traverse_accessible_tree (Accessible *accessible);
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_text_selection_event (const AccessibleEvent *event, void *user_data);
35 static void report_active_descendant_event (const AccessibleEvent *event, void *user_data);
36 static void report_children_changed_event (const AccessibleEvent *event, void *user_data);
37 static void report_name_changed_event (const AccessibleEvent *event, void *user_data);
38 static void report_description_changed_event (const AccessibleEvent *event, void *user_data);
39 static void report_parent_changed_event (const AccessibleEvent *event, void *user_data);
40 static void report_window_event (const AccessibleEvent *event, void *user_data);
41 static void report_table_summary_event (const AccessibleEvent *event, void *user_data);
42 static void report_table_header_event (const AccessibleEvent *event, void *user_data);
43 static void report_table_caption_event (const AccessibleEvent *event, void *user_data);
44 static void report_table_row_description_event (const AccessibleEvent *event, void *user_data);
45 static void report_table_column_description_event (const AccessibleEvent *event, void *user_data);
46 static void timing_test_event (const AccessibleEvent *event, void *user_data);
47 static SPIBoolean report_mouse_event (const AccessibleDeviceEvent *event, void *user_data);
49 static AccessibleEventListener *generic_listener;
50 static AccessibleEventListener *specific_listener;
51 static AccessibleEventListener *detail1_listener;
52 static AccessibleEventListener *test_listener;
53 static AccessibleEventListener *text_listener;
54 static AccessibleEventListener *text_selection_listener;
55 static AccessibleEventListener *active_descendant_listener;
56 static AccessibleEventListener *children_changed_listener;
57 static AccessibleEventListener *name_changed_listener;
58 static AccessibleEventListener *description_changed_listener;
59 static AccessibleEventListener *parent_changed_listener;
60 static AccessibleEventListener *window_listener;
61 static AccessibleEventListener *table_summary_listener;
62 static AccessibleEventListener *table_header_listener;
63 static AccessibleEventListener *table_caption_listener;
64 static AccessibleEventListener *table_row_description_listener;
65 static AccessibleEventListener *table_column_description_listener;
66 static AccessibleDeviceListener *mouse_device_listener;
67 static gint n_elements_traversed = 0;
70 static gboolean report_mouse_events = TRUE;
73 usage_and_exit( void )
75 g_print("\nUsage: event-listener-test [-h] [-m]\n");
76 g_print(" -h : prints this usage message.\n");
77 g_print(" -m : disable mouse event reporting.\n\n");
83 main (int argc, char **argv)
91 Accessible *application;
94 /* Parse Command-line */
96 while ( ( c = getopt( argc, argv, "hm")) != EOF ) {
99 report_mouse_events = FALSE;
106 if ( optind < argc ) {
111 fprintf (stderr, "RUNNING\n");
115 generic_listener = SPI_createAccessibleEventListener (
117 specific_listener = SPI_createAccessibleEventListener (
118 report_detail_event, NULL);
119 text_listener = SPI_createAccessibleEventListener (
120 report_text_event, NULL);
121 text_selection_listener = SPI_createAccessibleEventListener (
122 report_text_selection_event, NULL);
123 active_descendant_listener = SPI_createAccessibleEventListener (
124 report_active_descendant_event, NULL);
125 children_changed_listener = SPI_createAccessibleEventListener (
126 report_children_changed_event, NULL);
127 name_changed_listener = SPI_createAccessibleEventListener (
128 report_name_changed_event, NULL);
129 description_changed_listener = SPI_createAccessibleEventListener (
130 report_description_changed_event, NULL);
131 parent_changed_listener = SPI_createAccessibleEventListener (
132 report_parent_changed_event, NULL);
133 window_listener = SPI_createAccessibleEventListener (
134 report_window_event, NULL);
135 table_summary_listener = SPI_createAccessibleEventListener (
136 report_table_summary_event, NULL);
137 table_header_listener = SPI_createAccessibleEventListener (
138 report_table_header_event, NULL);
139 table_caption_listener = SPI_createAccessibleEventListener (
140 report_table_caption_event, NULL);
141 table_row_description_listener = SPI_createAccessibleEventListener (
142 report_table_row_description_event, NULL);
143 table_column_description_listener = SPI_createAccessibleEventListener (
144 report_table_column_description_event, NULL);
145 test_listener = SPI_createAccessibleEventListener (
146 timing_test_event, NULL);
147 mouse_device_listener = SPI_createAccessibleDeviceListener (
148 report_mouse_event, NULL);
149 detail1_listener = SPI_createAccessibleEventListener (
150 report_detail1_event, NULL);
152 SPI_registerGlobalEventListener (generic_listener,
154 if ( report_mouse_events ) {
155 SPI_registerGlobalEventListener (specific_listener,
157 SPI_registerGlobalEventListener (specific_listener,
159 SPI_registerGlobalEventListener (specific_listener,
162 SPI_registerDeviceEventListener (mouse_device_listener,
163 SPI_BUTTON_PRESSED | SPI_BUTTON_RELEASED,
165 SPI_registerGlobalEventListener (specific_listener,
166 "keyboard:modifiers");
167 SPI_registerGlobalEventListener (generic_listener,
168 "object:property-change");
169 SPI_registerGlobalEventListener (name_changed_listener,
170 "object:property-change:accessible-name");
171 SPI_registerGlobalEventListener (description_changed_listener,
172 "object:property-change:accessible-description");
173 SPI_registerGlobalEventListener (parent_changed_listener,
174 "object:property-change:accessible-parent");
175 SPI_registerGlobalEventListener (generic_listener,
176 "object:state-changed");
177 /* SPI_registerGlobalEventListener (specific_listener,
178 "object:state-changed:focused"); */
179 SPI_registerGlobalEventListener (generic_listener,
180 "object:selection-changed");
181 SPI_registerGlobalEventListener (children_changed_listener,
182 "object:children-changed");
183 SPI_registerGlobalEventListener (active_descendant_listener,
184 "object:active-descendant");
185 SPI_registerGlobalEventListener (generic_listener,
186 "object:visible-data-changed");
187 SPI_registerGlobalEventListener (text_selection_listener,
188 "object:text-selection-changed");
190 SPI_registerGlobalEventListener (generic_listener,
191 "object:text-caret-moved");
192 SPI_registerGlobalEventListener (text_listener,
193 "object:text-changed");
194 SPI_registerGlobalEventListener (generic_listener,
195 "object:column-inserted");
196 SPI_registerGlobalEventListener (generic_listener,
197 "object:row-inserted");
198 SPI_registerGlobalEventListener (generic_listener,
199 "object:column-reordered");
200 SPI_registerGlobalEventListener (generic_listener,
201 "object:row-reordered");
202 SPI_registerGlobalEventListener (generic_listener,
203 "object:column-deleted");
204 SPI_registerGlobalEventListener (generic_listener,
205 "object:row-deleted");
206 SPI_registerGlobalEventListener (generic_listener,
207 "object:model-changed");
208 SPI_registerGlobalEventListener (detail1_listener,
209 "object:link-selected");
210 SPI_registerGlobalEventListener (window_listener,
212 SPI_registerGlobalEventListener (window_listener,
214 SPI_registerGlobalEventListener (window_listener,
216 SPI_registerGlobalEventListener (window_listener,
218 SPI_registerGlobalEventListener (window_listener,
219 "window:deactivate");
220 SPI_registerGlobalEventListener (window_listener,
222 SPI_registerGlobalEventListener (window_listener,
224 SPI_registerGlobalEventListener (window_listener,
226 SPI_registerGlobalEventListener (window_listener,
228 SPI_registerGlobalEventListener (window_listener,
230 SPI_registerGlobalEventListener (window_listener,
232 SPI_registerGlobalEventListener (table_summary_listener,
233 "object:property-change:accessible-table-summary");
234 SPI_registerGlobalEventListener (table_header_listener,
235 "object:property-change:accessible-table-row-header");
236 SPI_registerGlobalEventListener (table_header_listener,
237 "object:property-change:accessible-table-column-header");
238 SPI_registerGlobalEventListener (table_summary_listener,
239 "object:property-change:accessible-table-summary");
240 SPI_registerGlobalEventListener (table_row_description_listener,
241 "object:property-change:accessible-table-row-description");
242 SPI_registerGlobalEventListener (table_column_description_listener,
243 "object:property-change:accessible-table-column-description");
244 SPI_registerGlobalEventListener (test_listener,
246 #ifdef NOT_YET_IMPLEMENTED
247 /* event below possibly should just be property change? */
248 SPI_registerGlobalEventListener (generic_listener,
250 SPI_registerGlobalEventListener (generic_listener,
251 "window:desktop-create");
252 SPI_registerGlobalEventListener (generic_listener,
253 "window:desktop-destroy");
256 timer = g_timer_new ();
257 traverse_accessible_tree (SPI_getDesktop (0));
258 g_print ("Time for first traversal of %d elements: %lf\n",
259 n_elements_traversed,
260 g_timer_elapsed (timer, NULL));
261 g_timer_start (timer);
262 traverse_accessible_tree (SPI_getDesktop (0));
263 g_timer_stop (timer);
264 g_print ("Time for subsequent traversal %f\n", g_timer_elapsed (timer, NULL));
265 g_print ("[%f elements/sec, %f SPI calls/sec]\n",
266 n_elements_traversed/g_timer_elapsed(timer, NULL),
267 (n_elements_traversed*8+1)/g_timer_elapsed(timer, NULL));
268 g_timer_reset (timer);
271 putenv ("AT_BRIDGE_SHUTDOWN=1");
274 * TODO: Add a key event listener that calls test_exit, to
275 * deregister and cleanup appropriately.
282 traverse_accessible_tree (Accessible *accessible)
290 n_elements_traversed++;
291 name = Accessible_getName (accessible);
292 role_name = Accessible_getRoleName (accessible);
294 fprintf (stdout, "[%s] \"%s\"\n",
297 SPI_freeString (name);
298 SPI_freeString (role_name);
299 n_children = Accessible_getChildCount (accessible);
300 if (!Accessible_isTable (accessible))
302 for (i = 0; i < n_children; ++i)
304 child = Accessible_getChildAtIndex (accessible, i);
305 traverse_accessible_tree (child);
306 Accessible_unref (child);
312 report_event (const AccessibleEvent *event, void *user_data)
314 static long count = 0;
315 char *s = Accessible_getName (event->source);
316 fprintf (stderr, "%s %s\n", event->type, s);
317 if (s) SPI_freeString (s);
319 g_timer_reset (timer);
320 g_timer_start (timer);
323 if ((count % 100) == 0) {
324 g_print ("%d events received, %f events/sec\n",
326 count/g_timer_elapsed(timer, NULL));
331 report_detail_event (const AccessibleEvent *event, void *user_data)
333 char *s = Accessible_getName (event->source);
334 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
335 event->detail1, event->detail2);
336 if (s) SPI_freeString (s);
340 report_detail1_event (const AccessibleEvent *event, void *user_data)
342 char *s = Accessible_getName (event->source);
343 fprintf (stderr, "(detail) %s %s %d\n", event->type, s,
345 if (s) SPI_freeString (s);
349 report_text_event (const AccessibleEvent *event, void *user_data)
351 char *s = Accessible_getName (event->source);
352 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
353 event->detail1, event->detail2);
355 s = AccessibleTextChangedEvent_getChangeString (event);
356 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
361 report_text_selection_event (const AccessibleEvent *event, void *user_data)
363 char *s = Accessible_getName (event->source);
364 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
365 event->detail1, event->detail2);
367 s = AccessibleTextSelectionChangedEvent_getSelectionString (event);
368 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
373 report_active_descendant_event (const AccessibleEvent *event, void *user_data)
375 char *s = Accessible_getName (event->source);
379 ao = AccessibleActiveDescendantChangedEvent_getActiveDescendant (event);
380 s1 = Accessible_getName (ao);
381 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
382 s ? s : "<null>", s1 ? s1 : "<null>",
383 event->detail1, event->detail2);
386 Accessible_unref (ao);
389 report_children_changed_event (const AccessibleEvent *event, void *user_data)
391 char *s = Accessible_getName (event->source);
395 ao = AccessibleChildChangedEvent_getChildAccessible (event);
396 s1 = Accessible_getName (ao);
397 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
398 s ? s : "<null>", s1 ? s1 : "<null>",
399 event->detail1, event->detail2);
402 Accessible_unref (ao);
406 report_name_changed_event (const AccessibleEvent *event, void *user_data)
408 char *s = Accessible_getName (event->source);
409 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
410 event->detail1, event->detail2);
412 s = AccessibleNameChangedEvent_getNameString (event);
413 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
418 report_description_changed_event (const AccessibleEvent *event, void *user_data)
420 char *s = Accessible_getName (event->source);
421 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
422 event->detail1, event->detail2);
424 s = AccessibleDescriptionChangedEvent_getDescriptionString (event);
425 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
430 report_parent_changed_event (const AccessibleEvent *event, void *user_data)
432 char *s = Accessible_getName (event->source);
436 ao = AccessibleParentChangedEvent_getParentAccessible (event);
437 s1 = Accessible_getName (ao);
438 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
439 s ? s : "<null>", s1 ? s1 : "<null>",
440 event->detail1, event->detail2);
443 Accessible_unref (ao);
447 report_window_event (const AccessibleEvent *event, void *user_data)
449 char *s = Accessible_getName (event->source);
450 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
451 event->detail1, event->detail2);
453 s = AccessibleWindowEvent_getTitleString (event);
454 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
459 report_table_summary_event (const AccessibleEvent *event, void *user_data)
461 char *s = Accessible_getName (event->source);
465 ao = AccessibleTableSummaryChangedEvent_getSummaryAccessible (event);
466 s1 = Accessible_getName (ao);
467 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
468 s ? s : "<null>", s1 ? s1 : "<null>",
469 event->detail1, event->detail2);
472 Accessible_unref (ao);
476 report_table_header_event (const AccessibleEvent *event, void *user_data)
478 char *s = Accessible_getName (event->source);
482 ao = AccessibleTableHeaderChangedEvent_getHeaderAccessible (event);
483 s1 = Accessible_getName (ao);
484 fprintf (stderr, "(detail) %s parent: %s child: %s %d %d\n", event->type,
485 s ? s : "<null>", s1 ? s1 : "<null>",
486 event->detail1, event->detail2);
489 Accessible_unref (ao);
493 report_table_caption_event (const AccessibleEvent *event, void *user_data)
495 char *s = Accessible_getName (event->source);
496 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
497 event->detail1, event->detail2);
499 s = AccessibleTableCaptionChangedEvent_getCaptionString (event);
500 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
505 report_table_row_description_event (const AccessibleEvent *event, void *user_data)
507 char *s = Accessible_getName (event->source);
508 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
509 event->detail1, event->detail2);
511 s = AccessibleTableRowDescriptionChangedEvent_getDescriptionString (event);
512 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
517 report_table_column_description_event (const AccessibleEvent *event, void *user_data)
519 char *s = Accessible_getName (event->source);
520 fprintf (stderr, "(detail) %s %s %d %d\n", event->type, s,
521 event->detail1, event->detail2);
523 s = AccessibleTableColumnDescriptionChangedEvent_getDescriptionString (event);
524 fprintf (stderr, "context string %s\n", (s) ? s : "<nil>");
529 report_mouse_event (const AccessibleDeviceEvent *event, void *user_data)
531 fprintf (stderr, "mouse event %ld %d %x %x\n",
533 (int) event->keycode,
534 (unsigned) event->type,
535 (unsigned) event->modifiers);
540 timing_test_event (const AccessibleEvent *event, void *user_data)
542 static long count = 0;
543 if (count == 0) g_timer_start (timer);
545 if ((count % 500) == 0) {
546 g_print ("%d events received, %f events/sec\n",
548 count/g_timer_elapsed(timer, NULL));
555 SPI_deregisterGlobalEventListenerAll (generic_listener);
556 AccessibleEventListener_unref (generic_listener);
557 SPI_deregisterGlobalEventListenerAll (specific_listener);
558 AccessibleEventListener_unref (specific_listener);