diff --git a/registryd/deviceeventcontroller.c b/registryd/deviceeventcontroller.c index 20d5ea2..aa62786 100644 --- a/registryd/deviceeventcontroller.c +++ b/registryd/deviceeventcontroller.c @@ -997,7 +997,7 @@ spi_controller_register_device_listener (SpiDEController *controller, { have_mouse_listener = TRUE; if (!have_mouse_event_listener) - g_timeout_add (100, spi_dec_poll_mouse_idle, controller->registry); + g_timeout_add (100, spi_dec_poll_mouse_idle, controller); } spi_dbus_add_disconnect_match (controller->bus, listener->bus_name); break; @@ -2643,6 +2643,76 @@ impl_notify_listeners_async (DBusConnection *bus, DBusMessage *message, void *us return reply; } +/* + * Accessibility::DEController::MousePollAdd + */ +static DBusMessage * +impl_mouse_poll_add (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + SpiDEController *controller = SPI_DEVICE_EVENT_CONTROLLER (user_data); + const char *bus_name = dbus_message_get_sender (message); + GList *l; + + for (l = controller->mouse_poll_list; l; l = l->next) + if (!strcmp (l->data, bus_name)) + return NULL; + + controller->mouse_poll_list = g_list_prepend (controller->mouse_poll_list, + g_strdup (bus_name)); + spi_dbus_add_disconnect_match (controller->bus, bus_name); + spi_device_event_controller_start_poll_mouse (controller); + + return NULL; +} + +typedef struct { + DBusConnection *bus; + const char *sender; +} RemoveMousePollClosure; + +static SpiReEntrantContinue +remove_mouse_poll_cb (GList * const *list, gpointer user_data) +{ + char *poll_client = (*list)->data; + RemoveMousePollClosure *ctx = user_data; + + if (!strcmp (poll_client, ctx->sender)) + { + spi_re_entrant_list_delete_link (list); + spi_dbus_remove_disconnect_match (ctx->bus, ctx->sender); + g_free (poll_client); + + return SPI_RE_ENTRANT_TERMINATE; + } + + return SPI_RE_ENTRANT_CONTINUE; +} + +void +spi_remove_mouse_poll_client (SpiDEController *controller, const char *bus_name) +{ + RemoveMousePollClosure ctx; + + ctx.bus = controller->bus; + ctx.sender = bus_name; + spi_re_entrant_list_foreach (&controller->mouse_poll_list, + remove_mouse_poll_cb, &ctx); + + if (!controller->mouse_poll_list) + spi_device_event_controller_stop_poll_mouse (); +} + +/* + * Accessibility::DEController::MousePollRemove + */ +static DBusMessage * +impl_mouse_poll_remove (DBusConnection *bus, DBusMessage *message, void *user_data) +{ + spi_remove_mouse_poll_client (SPI_DEVICE_EVENT_CONTROLLER (user_data), + dbus_message_get_sender (message)); + return NULL; +} + static void spi_device_event_controller_class_init (SpiDEControllerClass *klass) { @@ -2824,6 +2894,10 @@ handle_dec_method (DBusConnection *bus, DBusMessage *message, void *user_data) reply = impl_notify_listeners_sync (bus, message, user_data); else if (!strcmp (member, "NotifyListenersAsync")) reply = impl_notify_listeners_async (bus, message, user_data); + else if (!strcmp (member, "MousePollAdd")) + reply = impl_mouse_poll_add (bus, message, user_data); + else if (!strcmp (member, "MousePollRemove")) + reply = impl_mouse_poll_remove (bus, message, user_data); else return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -2860,13 +2934,13 @@ spi_registry_dec_new (SpiRegistry *reg, DBusConnection *bus) } void -spi_device_event_controller_start_poll_mouse (SpiRegistry *registry) +spi_device_event_controller_start_poll_mouse (SpiDEController *controller) { if (!have_mouse_event_listener) { have_mouse_event_listener = TRUE; if (!have_mouse_listener) - g_timeout_add (100, spi_dec_poll_mouse_idle, registry); + g_timeout_add (100, spi_dec_poll_mouse_idle, controller); } } diff --git a/registryd/deviceeventcontroller.h b/registryd/deviceeventcontroller.h index f69c57b..2b3fa30 100644 --- a/registryd/deviceeventcontroller.h +++ b/registryd/deviceeventcontroller.h @@ -47,6 +47,7 @@ struct _SpiDEController { GList *key_listeners; GList *mouse_listeners; GList *keygrabs_list; + GList *mouse_poll_list; Display *xevie_display; }; @@ -58,10 +59,11 @@ GType spi_device_event_controller_get_type (void); SpiDEController *spi_device_event_controller_new (SpiRegistry *registry, DBusConnection *bus); -void spi_device_event_controller_start_poll_mouse (SpiRegistry *registry); +void spi_device_event_controller_start_poll_mouse (SpiDEController *controller); void spi_device_event_controller_stop_poll_mouse (void); void spi_remove_device_listeners (SpiDEController *controller, const char *bus_name); +void spi_remove_mouse_poll_client (SpiDEController *controller, const char *bus_name); SpiDEController *spi_registry_dec_new (SpiRegistry *reg, DBusConnection *bus); G_END_DECLS diff --git a/xml/org.freedesktop.atspi.DeviceEventController.xml b/xml/org.freedesktop.atspi.DeviceEventController.xml index 952d9c5..3e2587f 100644 --- a/xml/org.freedesktop.atspi.DeviceEventController.xml +++ b/xml/org.freedesktop.atspi.DeviceEventController.xml @@ -177,5 +177,17 @@ + + +

Enable mouse polling.

+

Mouse polling is required to receive Mouse.Abs and Mouse.Rel + events from the Registry.

+
+
+ + +

Disable mouse polling.

+
+