From b5e1f13681090fc327dc2cabee1dc123273e785b Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Thu, 11 Feb 2021 09:48:12 +0100 Subject: [PATCH] dix: Add POINTER_RAWONLY flag This add a new flag POINTER_RAWONLY for GetPointerEvents() which does pretty much the opposite of POINTER_NORAW. Basically, this tells GetPointerEvents() that we only want the DeviceChanged events and any raw events for this motion but no actual motion events. This is preliminary work for Xwayland to be able to use relative motion events for raw events. Xwayland would use absolute events for raw events, but some X11 clients (wrongly) assume raw events to be always relative. To allow such clients to work with Xwayland, it needs to switch to relative raw events (if those are available from the Wayland compositor). However, Xwayland cannot use relative motion events for actual pointer location because that would cause a drift over time, the pointer being actually controlled by the Wayland compositor. So Xwayland needs to be able to send only relative raw events, hence this API. Bump the ABI_XINPUT_VERSION minor version to reflect that API addition. v2: Actually avoid sending motion events (Peter) v3: Keep sending raw emulated events with RAWONLY (Peter) Suggested-by: Peter Hutterer Signed-off-by: Olivier Fourdan Reviewed-by: Peter Hutterer Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130 --- dix/getevents.c | 57 ++++++++++++++++++---------------- hw/xfree86/common/xf86Module.h | 2 +- include/input.h | 1 + 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/dix/getevents.c b/dix/getevents.c index b2b8f124f..5dceec39b 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -1343,7 +1343,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons, CARD32 ms, int flags, const ValuatorMask *mask_in) { - int num_events = 1; + int num_events = 0; DeviceEvent *event; RawDeviceEvent *raw = NULL; double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ @@ -1386,6 +1386,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, num_events++; init_raw(pDev, raw, ms, type, buttons); + + if (flags & POINTER_EMULATED) + raw->flags = XIPointerEmulated; + set_raw_valuators(raw, &mask, TRUE, raw->valuators.data_raw); } @@ -1454,36 +1458,37 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, master->last.valuators[1] = screeny; } - event = &events->device_event; - init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL); + if ((flags & POINTER_RAWONLY) == 0) { + num_events++; - if (type == MotionNotify) { - event->type = ET_Motion; - event->detail.button = 0; - } - else { - if (type == ButtonPress) { - event->type = ET_ButtonPress; - set_button_down(pDev, buttons, BUTTON_POSTED); + event = &events->device_event; + init_device_event(event, pDev, ms, EVENT_SOURCE_NORMAL); + + if (type == MotionNotify) { + event->type = ET_Motion; + event->detail.button = 0; } - else if (type == ButtonRelease) { - event->type = ET_ButtonRelease; - set_button_up(pDev, buttons, BUTTON_POSTED); + else { + if (type == ButtonPress) { + event->type = ET_ButtonPress; + set_button_down(pDev, buttons, BUTTON_POSTED); + } + else if (type == ButtonRelease) { + event->type = ET_ButtonRelease; + set_button_up(pDev, buttons, BUTTON_POSTED); + } + event->detail.button = buttons; } - event->detail.button = buttons; + + /* root_x and root_y must be in per-screen coordinates */ + event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y); + + if (flags & POINTER_EMULATED) + event->flags = XIPointerEmulated; + + set_valuators(pDev, event, &mask); } - /* root_x and root_y must be in per-screen coordinates */ - event_set_root_coordinates(event, screenx - scr->x, screeny - scr->y); - - if (flags & POINTER_EMULATED) { - if (raw) - raw->flags = XIPointerEmulated; - event->flags = XIPointerEmulated; - } - - set_valuators(pDev, event, &mask); - return num_events; } diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h index af1fe4187..7b478d5c2 100644 --- a/hw/xfree86/common/xf86Module.h +++ b/hw/xfree86/common/xf86Module.h @@ -75,7 +75,7 @@ */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) #define ABI_VIDEODRV_VERSION SET_ABI_VERSION(25, 2) -#define ABI_XINPUT_VERSION SET_ABI_VERSION(24, 2) +#define ABI_XINPUT_VERSION SET_ABI_VERSION(24, 3) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(10, 0) #define MODINFOSTRING1 0xef23fdc5 diff --git a/include/input.h b/include/input.h index 0208562d9..98fdf0aed 100644 --- a/include/input.h +++ b/include/input.h @@ -94,6 +94,7 @@ SOFTWARE. #define POINTER_NORAW (1 << 5) /* Don't generate RawEvents */ #define POINTER_EMULATED (1 << 6) /* Event was emulated from another event */ #define POINTER_DESKTOP (1 << 7) /* Data in desktop coordinates */ +#define POINTER_RAWONLY (1 << 8) /* Only generate RawEvents */ /* GetTouchEvent flags */ #define TOUCH_ACCEPT (1 << 0)