+void
+report_window_event (const AccessibleEvent *event, void *user_data)
+{
+ fprintf (stderr, "%s event received\n", event->type);
+ if (!strcmp (event->type, "window:activate"))
+ {
+ print_accessible_tree (event->source, "window");
+ }
+}
+
+void
+report_text_event (const AccessibleEvent *event, void *user_data)
+{
+ AccessibleText *text = Accessible_getText (event->source);
+ fprintf (stderr, "%s event received\n", event->type);
+#ifdef MAGNIFIER_ENABLED
+ if (use_magnifier && strcmp (event->type, "object:text-changed"))
+ {
+ long offset = AccessibleText_getCaretOffset (text);
+ long x, y, w, h;
+ fprintf (stderr, "offset %d\n", (int) offset);
+ AccessibleText_getCharacterExtents (text, offset, &x, &y, &w, &h,
+ SPI_COORD_TYPE_SCREEN);
+ fprintf (stderr, "new roi %d %d %d %d\n", (int) x, (int) y, (int) w, (int) h);
+ magnifier_set_roi ((short) 0, x, y, w, h);
+ }
+#endif
+ if (!strcmp (event->type, "object:text-changed"))
+ {
+ long start, end;
+ char *new_text = AccessibleText_getTextAtOffset (text, (long) event->detail1, SPI_TEXT_BOUNDARY_WORD_START, &start, &end);
+ _festival_say (new_text, "voice_kal_diphone", FALSE);
+ fprintf (stderr, "text changed: %s", new_text ? new_text : "");
+ SPI_freeString (new_text);
+ }
+ else
+ {
+ long start, end;
+ char *word_text = AccessibleText_getTextAtOffset (text, (long) event->detail1, SPI_TEXT_BOUNDARY_WORD_START, &start, &end);
+ char *sentence_text = AccessibleText_getTextAtOffset (text, (long) event->detail1, SPI_TEXT_BOUNDARY_SENTENCE_START, &start, &end);
+ fprintf (stderr, "text changed: word %s; sentence %s at %ld",
+ (word_text ? word_text : ""),
+ (sentence_text ? sentence_text : ""),
+ event->detail1);
+ if (word_text) SPI_freeString (word_text);
+ if (sentence_text) SPI_freeString (sentence_text);
+ }
+}
+
+void
+report_button_press (const AccessibleEvent *event, void *user_data)
+{
+ char *s;
+
+ g_return_if_fail (event->source != NULL);
+
+ s = Accessible_getName (event->source);
+
+ fprintf (stderr, "%s event from %s\n", event->type, s);
+ SPI_freeString (s);
+ s = Accessible_getDescription (event->source);
+ fprintf (stderr, "Object description %s\n", s);
+ SPI_freeString (s);
+}
+
+void
+check_property_change (const AccessibleEvent *event, void *user_data)
+{
+ AccessibleSelection *selection = Accessible_getSelection (event->source);
+ int n_selections;
+ int i;
+ char *s;
+ fprintf (stderr, "property change event!\n");
+ if (selection)
+ {
+ n_selections = (int) AccessibleSelection_getNSelectedChildren (selection);
+ s = Accessible_getName (event->source);
+ fprintf (stderr, "(Property) %s event from %s, %d selected children\n",
+ event->type, s, n_selections);
+ SPI_freeString (s);
+ /* for now, speak entire selection set */
+ for (i=0; i<n_selections; ++i)
+ {
+ Accessible *obj = AccessibleSelection_getSelectedChild (selection, (long) i);
+ g_return_if_fail (obj);
+ s = Accessible_getName (obj);
+ fprintf (stderr, "Child %d, name=%s\n", i, s);
+ SPI_freeString (s);
+ report_focussed_accessible (obj, i==0);
+ }
+ }
+ else if (!strcmp (event->type, "object:property-change:accessible-name"))
+ {
+ name_changed = TRUE;
+ report_focussed_accessible (event->source, TRUE);
+ }
+ else
+ {
+ fprintf (stderr, "Property change %s received\n", event->type);
+ }
+}
+
+static void
+simple_at_exit (void)
+{
+ SPI_deregisterGlobalEventListenerAll (focus_listener);
+ AccessibleEventListener_unref (focus_listener);
+
+ SPI_deregisterGlobalEventListenerAll (property_listener);
+ AccessibleEventListener_unref (property_listener);
+
+ SPI_deregisterGlobalEventListenerAll (generic_listener);
+ AccessibleEventListener_unref (generic_listener);
+
+ SPI_deregisterGlobalEventListenerAll (text_listener);
+ AccessibleEventListener_unref (text_listener);
+
+ SPI_deregisterGlobalEventListenerAll (button_listener);
+ AccessibleEventListener_unref (button_listener);
+
+ SPI_deregisterAccessibleKeystrokeListener (command_key_listener, SPI_KEYMASK_ALT | SPI_KEYMASK_CONTROL);
+ AccessibleKeystrokeListener_unref (command_key_listener);
+ SPI_freeAccessibleKeySet (command_keyset);
+
+ SPI_deregisterAccessibleKeystrokeListener (ordinary_key_listener, SPI_KEYMASK_SHIFTLOCK);
+ AccessibleKeystrokeListener_unref (ordinary_key_listener);
+
+ SPI_event_quit ();
+}
+
+static SPIBoolean
+is_command_key (const AccessibleKeystroke *key)
+{
+ switch (key->keyID)
+ {
+ case 'Q':
+ case 'q':
+ simple_at_exit();
+ return TRUE; /* not reached */
+#ifdef MAGNIFIER_ENABLED
+ case 'M':
+ case 'm':
+ use_magnifier = ! use_magnifier;
+ fprintf (stderr, "%ssing magnifier\n", use_magnifier ? "U" : "Not u");
+ return TRUE;
+#endif
+ case 'F':
+ case 'f':
+ use_festival = ! use_festival;
+ fprintf (stderr, "%speech output\n", use_festival ? "S" : "No s");
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+static SPIBoolean
+report_command_key_event (const AccessibleKeystroke *key, void *user_data)
+{
+ fprintf (stderr, "Command KeyEvent %s%c (keycode %d); string=%s; time=%lx\n",
+ (key->modifiers & SPI_KEYMASK_ALT)?"Alt-":"",
+ ((key->modifiers & SPI_KEYMASK_SHIFT)^(key->modifiers & SPI_KEYMASK_SHIFTLOCK))?
+ (char) toupper((int) key->keyID) : (char) tolower((int) key->keyID),
+ (int) key->keycode,
+ key->keystring,
+ (long int) key->timestamp);
+ return is_command_key (key);
+}
+
+
+static SPIBoolean
+report_ordinary_key_event (const AccessibleKeystroke *key, void *user_data)
+{
+ fprintf (stderr, "Received key event:\tsym %ld\n\tmods %x\n\tcode %d\n\tstring=\'%s\'\n\ttime %lx\n",
+ (long) key->keyID,
+ (unsigned int) key->modifiers,
+ (int) key->keycode,
+ key->keystring,
+ (long int) key->timestamp);
+ return FALSE;
+}
+
+static int
+_festival_init (void)