diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index 21dc8ca7..9d3728de 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -22,6 +22,7 @@ #include "xdg-decoration-unstable-v1-client-protocol.h" #include "xdg-shell-client-protocol.h" #include "tablet-unstable-v2-client-protocol.h" +#include "relative-pointer-unstable-v1-client-protocol.h" struct wlr_wl_backend *get_wl_backend_from_backend(struct wlr_backend *backend) { assert(wlr_backend_is_wl(backend)); @@ -116,6 +117,9 @@ static void registry_global(void *data, struct wl_registry *registry, &zwp_linux_dmabuf_v1_interface, 3); zwp_linux_dmabuf_v1_add_listener(wl->zwp_linux_dmabuf_v1, &linux_dmabuf_v1_listener, wl); + } else if (strcmp(iface, zwp_relative_pointer_manager_v1_interface.name) == 0) { + wl->zwp_relative_pointer_manager_v1 = wl_registry_bind(registry, name, + &zwp_relative_pointer_manager_v1_interface, 1); } } @@ -201,6 +205,9 @@ static void backend_destroy(struct wlr_backend *backend) { if (wl->zwp_linux_dmabuf_v1) { zwp_linux_dmabuf_v1_destroy(wl->zwp_linux_dmabuf_v1); } + if (wl->zwp_relative_pointer_manager_v1) { + zwp_relative_pointer_manager_v1_destroy(wl->zwp_relative_pointer_manager_v1); + } xdg_wm_base_destroy(wl->xdg_wm_base); wl_compositor_destroy(wl->compositor); wl_registry_destroy(wl->registry); diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index dd498153..40cbf74a 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -16,6 +16,7 @@ #include #include "pointer-gestures-unstable-v1-client-protocol.h" +#include "relative-pointer-unstable-v1-client-protocol.h" #include "backend/wayland.h" #include "util/signal.h" @@ -446,6 +447,31 @@ static struct zwp_pointer_gesture_pinch_v1_listener gesture_pinch_impl = { }; +void relative_pointer_handle_relative_motion(void *data, + struct zwp_relative_pointer_v1 *relative_pointer, uint32_t utime_hi, + uint32_t utime_lo, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, + wl_fixed_t dy_unaccel) { + struct wlr_wl_input_device *input_device = data; + struct wlr_input_device *wlr_dev = &input_device->wlr_input_device; + + uint64_t time_usec = (uint64_t)utime_hi << 32 | utime_lo; + + struct wlr_event_pointer_motion wlr_event = { + .device = wlr_dev, + .time_msec = (uint32_t)(time_usec / 1000), + .delta_x = wl_fixed_to_double(dx), + .delta_y = wl_fixed_to_double(dy), + .unaccel_dx = wl_fixed_to_double(dx_unaccel), + .unaccel_dy = wl_fixed_to_double(dy_unaccel), + }; + wlr_signal_emit_safe(&wlr_dev->pointer->events.motion, &wlr_event); +} + +static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = { + .relative_motion = relative_pointer_handle_relative_motion, +}; + + static void pointer_handle_output_destroy(struct wl_listener *listener, void *data) { struct wlr_wl_pointer *pointer = @@ -501,6 +527,14 @@ void create_wl_pointer(struct wl_pointer *wl_pointer, struct wlr_wl_output *outp zwp_pointer_gesture_pinch_v1_add_listener(pointer->gesture_pinch, &gesture_pinch_impl, dev); } + if (backend->zwp_relative_pointer_manager_v1) { + pointer->relative_pointer = + zwp_relative_pointer_manager_v1_get_relative_pointer( + backend->zwp_relative_pointer_manager_v1, wl_pointer); + zwp_relative_pointer_v1_add_listener(pointer->relative_pointer, + &relative_pointer_listener, dev); + } + wlr_signal_emit_safe(&backend->backend.events.new_input, wlr_dev); } diff --git a/include/backend/wayland.h b/include/backend/wayland.h index 886aea9f..f2cf55ed 100644 --- a/include/backend/wayland.h +++ b/include/backend/wayland.h @@ -36,6 +36,7 @@ struct wlr_wl_backend { struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1; struct zwp_pointer_gestures_v1 *zwp_pointer_gestures_v1; struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf_v1; + struct zwp_relative_pointer_manager_v1 *zwp_relative_pointer_manager_v1; struct wl_seat *seat; struct wl_pointer *pointer; struct wl_keyboard *keyboard; @@ -86,6 +87,7 @@ struct wlr_wl_pointer { struct wl_pointer *wl_pointer; struct zwp_pointer_gesture_swipe_v1 *gesture_swipe; struct zwp_pointer_gesture_pinch_v1 *gesture_pinch; + struct zwp_relative_pointer_v1 *relative_pointer; enum wlr_axis_source axis_source; int32_t axis_discrete; struct wlr_wl_output *output;