/** * SPI_registerDeviceEventListener: * @listener: a pointer to the #AccessibleDeviceListener which requests * the events. * @eventmask: an #AccessibleDeviceEventMask mask indicating which * types of key events are requested (#SPI_KEY_PRESSED, etc.). * @filter: Unused parameter. * * Register a listener for device events, for instance button events. * * Returns: #TRUE if successful, otherwise #FALSE. **/ SPIBoolean SPI_registerDeviceEventListener (AccessibleDeviceListener *listener, AccessibleDeviceEventMask eventmask, void *filter) { SPIBoolean retval = FALSE; dbus_uint32_t event_types = 0; gint i; gchar *path = cspi_device_listener_get_path (listener); DBusError error; if (!listener) { return retval; } /* copy the event filter values from the C api into the CORBA KeyEventTypeSeq */ if (eventmask & SPI_BUTTON_PRESSED) { event_types |= (1 << Accessibility_BUTTON_PRESSED_EVENT); } if (eventmask & SPI_BUTTON_RELEASED) { event_types |= (1 << Accessibility_BUTTON_RELEASED_EVENT); } dbus_error_init (&error); dbind_method_call_reentrant (SPI_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "registerDeviceEventListener", &error, "ou=>b", path, event_types, &retval); g_free (path); return retval; }
/** * SPI_generateMouseEvent: * @x: a #long indicating the screen x coordinate of the mouse event. * @y: a #long indicating the screen y coordinate of the mouse event. * @name: a string indicating which mouse event to be synthesized * (e.g. "b1p", "b1c", "b2r", "rel", "abs"). * * Synthesize a mouse event at a specific screen coordinate. * Most AT clients should use the #AccessibleAction interface when * tempted to generate mouse events, rather than this method. * Event names: b1p = button 1 press; b2r = button 2 release; * b3c = button 3 click; b2d = button 2 double-click; * abs = absolute motion; rel = relative motion. * * Returns: #TRUE if successful, otherwise #FALSE. **/ SPIBoolean SPI_generateMouseEvent (long x, long y, char *name) { dbus_int32_t dbus_x = x, dbus__y = y; DBusError error; dbus_error_init (&error); dbind_method_call_reentrant (SPI_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "generateMouseEvent", &error, "iis", x, y, name); return TRUE; }
DBusHandlerResult cspi_dbus_handle_deviceEvent (DBusConnection *bus, DBusMessage *message, void *data) { const char *path = dbus_message_get_path (message); int id; Accessibility_DeviceEvent event; CSpiDeviceListener *listener; DBusMessageIter iter; CSpiDeviceListenerClass *klass; dbus_bool_t retval = FALSE; GList *l; DBusMessage *reply; void *p = &event; if (sscanf (path, "/org/freedesktop/atspi/listeners/%d", &id) != 1) { g_warning ("Bad listener path: %s\n", path); goto done; } for (l = device_listeners; l; l = g_list_next (l)) { listener = l->data; if (listener->id == id) break; } if (!l) { goto done; } dbus_message_iter_init (message, &iter); dbind_any_demarshal (&iter, (char **) &deviceEvent_type, &p); klass = CSPI_DEVICE_LISTENER_GET_CLASS (listener); if (klass->device_event) { retval = (*klass->device_event) (listener, &event); } done: reply = dbus_message_new_method_return (message); if (reply) { dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &retval, DBUS_TYPE_INVALID); dbus_connection_send (SPI_bus(), reply, NULL); dbus_message_unref (reply); } return DBUS_HANDLER_RESULT_HANDLED; }
/** * SPI_deregisterDeviceEventListener: * @listener: a pointer to the #AccessibleDeviceListener for which * device events are requested. * @filter: Unused parameter. * * Removes a device event listener from the registry's listener queue, * ceasing notification of events of the specified type. * * Returns: #TRUE if successful, otherwise #FALSE. **/ SPIBoolean SPI_deregisterDeviceEventListener (AccessibleDeviceListener *listener, void *filter) { dbus_uint32_t event_types = 0; gchar *path = cspi_device_listener_get_path (listener); DBusError error; if (!listener) { return FALSE; } event_types |= (1 << Accessibility_BUTTON_PRESSED_EVENT); event_types |= (1 << Accessibility_BUTTON_RELEASED_EVENT); dbus_error_init (&error); dbind_method_call_reentrant (SPI_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "deregisterDeviceEventListener", &error, "ou", path, event_types); g_free (path); return TRUE; }
/** * SPI_deregisterAccessibleKeystrokeListener: * @listener: a pointer to the #AccessibleKeystrokeListener for which * keystroke events are requested. * @modmask: the key modifier mask for which this listener is to be * 'deregistered' (of type #AccessibleeyMaskType). * * Removes a keystroke event listener from the registry's listener queue, * ceasing notification of events with modifiers matching @modmask. * * Returns: #TRUE if successful, otherwise #FALSE. **/ SPIBoolean SPI_deregisterAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener, AccessibleKeyMaskType modmask) { gchar *path = cspi_device_listener_get_path (listener); Accessibility_ControllerEventMask controller_event_mask; GArray *key_set; dbus_uint32_t key_events = 0; DBusError error; if (!listener) { return FALSE; } controller_event_mask = (dbus_uint32_t) modmask; key_set = g_array_sized_new (FALSE, TRUE, sizeof (Accessibility_KeyDefinition), 0); dbind_method_call_reentrant (SPI_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "deregisterKeystrokeListener", &error, "oa(iisi)uu", path, &key_set, key_events, controller_event_mask); g_free (path); return TRUE; }
/** * SPI_generateKeyboardEvent: * @keyval: a long integer indicating the keycode or keysym of the key event * being synthesized. * @keystring: an (optional) UTF-8 string which, if @keyval is NULL, * indicates a 'composed' keyboard input string which is * being synthesized; this type of keyboard event synthesis does * not emulate hardware keypresses but injects the string * as though a composing input method (such as XIM) were used. * @synth_type: a #AccessibleKeySynthType flag indicating whether @keyval * is to be interpreted as a keysym rather than a keycode * (CSPI_KEYSYM), or whether to synthesize * SPI_KEY_PRESS, SPI_KEY_RELEASE, or both (SPI_KEY_PRESSRELEASE). * * Synthesize a keyboard event (as if a hardware keyboard event occurred in the * current UI context). * * Returns: #TRUE if successful, otherwise #FALSE. **/ SPIBoolean SPI_generateKeyboardEvent (long int keyval, char *keystring, AccessibleKeySynthType synth_type) { dbus_uint32_t keysynth_type; dbus_int32_t keycode = keyval; DBusError error; switch (synth_type) { case SPI_KEY_PRESS: keysynth_type = Accessibility_KEY_PRESS; break; case SPI_KEY_RELEASE: keysynth_type = Accessibility_KEY_RELEASE; break; case SPI_KEY_PRESSRELEASE: keysynth_type = Accessibility_KEY_PRESSRELEASE; break; case SPI_KEY_SYM: keysynth_type = Accessibility_KEY_SYM; break; case SPI_KEY_STRING: keysynth_type = Accessibility_KEY_STRING; break; default: return FALSE; } if (!keystring) keystring = ""; dbus_error_init (&error); dbind_method_call_reentrant (SPI_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "generateKeyboardEvent", &error, "isu", keycode, keystring, keysynth_type); return TRUE; }
int main (int argc, char **argv) { int leaked, i; TestWindow *win; const char *modules; AccessibleEventListener *global_listener; modules = g_getenv ("GTK_MODULES"); if (!modules || modules [0] == '\0') putenv ("GTK_MODULES=gail:atk-bridge"); modules = NULL; for (i = 1; i < argc; i++) { if (!g_strcasecmp (argv [i], "--poke")) do_poke = TRUE; } gtk_init (&argc, &argv); g_assert (!SPI_init ()); g_assert (SPI_init ()); g_assert (SPI_getDesktopCount () == 1); test_roles (); test_misc (); test_desktop (); test_keylisteners (); win = create_test_window (); global_listener = SPI_createAccessibleEventListener (global_listener_cb, win); g_assert (SPI_registerGlobalEventListener (global_listener, "focus:")); fprintf (stderr, "Waiting for focus event ...\n"); gtk_main (); g_assert (SPI_deregisterGlobalEventListenerAll (global_listener)); AccessibleEventListener_unref (global_listener); test_window_destroy (win); /* Wait for any pending events from the registry */ g_usleep (500*1000); for (i = 0; i < 100; i++) dbus_connection_read_write_dispatch (SPI_bus(), 5); if ((leaked = SPI_exit ())) g_error ("Leaked %d SPI handles", leaked); g_assert (!SPI_exit ()); fprintf (stderr, "All tests passed\n"); if (g_getenv ("_MEMPROF_SOCKET")) { fprintf (stderr, "Waiting for memprof\n"); gtk_main (); } putenv ("AT_BRIDGE_SHUTDOWN=1"); return 0; }
/** * SPI_registerAccessibleKeystrokeListener: * @listener: a pointer to the #AccessibleKeystrokeListener for which * keystroke events are requested. * @keys: a pointer to the #AccessibleKeySet indicating which * keystroke events are requested, or #SPI_KEYSET_ALL_KEYS * to indicate that all keycodes and keyvals for the specified * modifier set are to be included. * @modmask: an #AccessibleKeyMaskType mask indicating which * key event modifiers must be set in combination with @keys, * events will only be reported for key events for which all * modifiers in @modmask are set. If you wish to listen for * events with multiple modifier combinations you must call * registerAccessibleKeystrokeListener() once for each combination. * @eventmask: an #AccessibleKeyMaskType mask indicating which * types of key events are requested (#SPI_KEY_PRESSED, etc.). * @sync_type: a #AccessibleKeyListenerSyncType parameter indicating * the behavior of the notification/listener transaction. * * Register a listener for keystroke events, either pre-emptively for * all windows (SPI_KEYLISTENER_ALL_WINDOWS), * non-preemptively (SPI_KEYLISTENER_NOSYNC), or * pre-emptively at the toolkit level (SPI_KEYLISTENER_CANCONSUME). * If ALL_WINDOWS or CANCONSUME are used, the event is consumed * upon receipt if one of @listener's callbacks returns #TRUE. * ( Other sync_type values may be available in the future ) * * Returns: #TRUE if successful, otherwise #FALSE. **/ SPIBoolean SPI_registerAccessibleKeystrokeListener (AccessibleKeystrokeListener *listener, AccessibleKeySet *keys, AccessibleKeyMaskType modmask, AccessibleKeyEventMask eventmask, AccessibleKeyListenerSyncType sync_type) { gchar *path = cspi_device_listener_get_path (listener); gint i; GArray *key_set; dbus_uint32_t key_events = 0; Accessibility_ControllerEventMask controller_event_mask; Accessibility_EventListenerMode listener_mode; DBusError error; SPIBoolean retval = FALSE; if (!listener) { return retval; } /* copy the keyval filter values from the C api into the DBind KeySet */ if (keys) { key_set = g_array_sized_new (FALSE, TRUE, sizeof (Accessibility_KeyDefinition), keys->len); key_set->len = keys->len; for (i = 0; i < keys->len; ++i) { Accessibility_KeyDefinition *kd = ((Accessibility_KeyDefinition *) key_set->data) + i; kd->keycode = keys->keycodes[i]; kd->keysym = keys->keysyms[i]; if (keys->keystrings && keys->keystrings[i]) { kd->keystring = keys->keystrings[i]; } else { kd->keystring = ""; } } } else { key_set = g_array_sized_new (FALSE, TRUE, sizeof (Accessibility_KeyDefinition), 0); } /* copy the event filter values from the C api into the DBus key_events */ if (eventmask & SPI_KEY_PRESSED) { key_events |= (1 << Accessibility_KEY_PRESSED_EVENT); } if (eventmask & SPI_KEY_RELEASED) { key_events |= (1 << Accessibility_KEY_RELEASED_EVENT); } controller_event_mask = (dbus_uint32_t) modmask; listener_mode.synchronous = (dbus_bool_t) ((sync_type & SPI_KEYLISTENER_SYNCHRONOUS)!=0); listener_mode.preemptive = (dbus_bool_t) ((sync_type & SPI_KEYLISTENER_CANCONSUME)!=0); listener_mode.global = (dbus_bool_t) ((sync_type & SPI_KEYLISTENER_ALL_WINDOWS)!=0); dbus_error_init (&error); dbind_method_call_reentrant (SPI_bus(), spi_bus_registry, spi_path_dec, spi_interface_dec, "registerKeystrokeListener", &error, "oa(iisi)uu(bbb)=>b", path, key_set, controller_event_mask, key_events, &listener_mode, &retval); g_array_free (key_set, TRUE); g_free (path); return retval; }