[PATCH xserver 06/12] xwayland: Add a new input device used for pointer warping/locking

Jonas Ådahl jadahl at gmail.com
Thu Sep 8 10:46:35 UTC 2016


From: Krzysztof Sobiecki <sobkas at gmail.com>

Generating relative and absolute movement events from the same input
device is problematic, because an absolute pointer device doesn't
expect to see any relative motion events. To be able to generate
relative pointer motion events including unaccelerated deltas, create a
secondary pointer device 'xwayland-relative-pointer', and use that for
emitting relative motion events.

Signed-off-by: Krzysztof Sobiecki <sobkas at gmail.com>
Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
---
 hw/xwayland/xwayland-input.c | 66 ++++++++++++++++++++++++++++++++++++++++++++
 hw/xwayland/xwayland.h       |  1 +
 2 files changed, 67 insertions(+)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index f194cf1..24ba5fa 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -124,6 +124,51 @@ xwl_pointer_proc(DeviceIntPtr device, int what)
 #undef NAXES
 }
 
+static int
+xwl_pointer_proc_relative(DeviceIntPtr device, int what)
+{
+#define NAXES 2
+    Atom axes_labels[NAXES] = { 0 };
+
+    switch (what) {
+    case DEVICE_INIT:
+        device->public.on = FALSE;
+
+        axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+        axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+
+        if (!InitValuatorClassDeviceStruct(device, NAXES, axes_labels,
+                                           GetMotionHistorySize(), Relative))
+            return BadValue;
+
+        /* Valuators */
+        InitValuatorAxisStruct(device, 0, axes_labels[0],
+                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative);
+        InitValuatorAxisStruct(device, 1, axes_labels[1],
+                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative);
+
+        if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
+            return BadValue;
+
+        device->button = NULL;
+
+        return Success;
+
+    case DEVICE_ON:
+        device->public.on = TRUE;
+        return Success;
+
+    case DEVICE_OFF:
+    case DEVICE_CLOSE:
+        device->public.on = FALSE;
+        return Success;
+    }
+
+    return BadMatch;
+
+#undef NAXES
+}
+
 static void
 xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl)
 {
@@ -795,6 +840,25 @@ release_pointer(struct xwl_seat *xwl_seat)
 }
 
 static void
+init_relative_pointer(struct xwl_seat *xwl_seat)
+{
+    if (xwl_seat->relative_pointer == NULL) {
+        xwl_seat->relative_pointer =
+            add_device(xwl_seat, "xwayland-relative-pointer",
+                       xwl_pointer_proc_relative);
+        ActivateDevice(xwl_seat->relative_pointer, TRUE);
+    }
+    EnableDevice(xwl_seat->relative_pointer, TRUE);
+}
+
+static void
+release_relative_pointer(struct xwl_seat *xwl_seat)
+{
+    if (xwl_seat->relative_pointer)
+        DisableDevice(xwl_seat->relative_pointer, TRUE);
+}
+
+static void
 init_keyboard(struct xwl_seat *xwl_seat)
 {
     DeviceIntPtr master;
@@ -860,8 +924,10 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
 
     if (caps & WL_SEAT_CAPABILITY_POINTER && xwl_seat->wl_pointer == NULL) {
         init_pointer(xwl_seat);
+        init_relative_pointer(xwl_seat);
     } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && xwl_seat->wl_pointer) {
         release_pointer(xwl_seat);
+        release_relative_pointer(xwl_seat);
     }
 
     if (caps & WL_SEAT_CAPABILITY_KEYBOARD && xwl_seat->wl_keyboard == NULL) {
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 2d19133..f78f464 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -119,6 +119,7 @@ struct xwl_touch {
 
 struct xwl_seat {
     DeviceIntPtr pointer;
+    DeviceIntPtr relative_pointer;
     DeviceIntPtr keyboard;
     DeviceIntPtr touch;
     struct xwl_screen *xwl_screen;
-- 
2.7.4



More information about the xorg-devel mailing list