xserver: Branch 'xwayland-21.1' - 6 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Feb 17 11:54:05 UTC 2021


 dix/getevents.c              |   53 +++++++-------
 hw/xwayland/xwayland-input.c |  160 +++++++++++++++++++++++++++----------------
 include/input.h              |    1 
 3 files changed, 133 insertions(+), 81 deletions(-)

New commits:
commit 4d2128fd1dc2ff7293e8b95b956ddb07ddb15de9
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Feb 11 11:42:01 2021 +0100

    xwayland: Use relative device for buttons/axis/enter/leave
    
    We are using the relative pointer for motion events, but buttons and
    axis events still go through the absolute pointer device.
    
    That means additional DeviceChanged events that could be avoided if the
    buttons and axis events were coming from the same device as motion
    events.
    
    However, routing just the buttons and axis events is not sufficient. In
    Weston, clicking the window decoration of an Xwayland client gives us a
    wl_pointer.button event immediately followed by a wl_pointer.leave event.
    The leave event does not contain any button state information, so the button
    remains logically down in the DIX.
    
    Once the pointer button is released, a wl_pointer.enter event is sent with
    the current button state (zero). This needs to trigger a ButtonRelease event
    but for that we need to ensure that the device is the same as the one we send
    ButtonPress events through.
    
    Route those events along with enter/leave events to the relative pointer
    if available so that motion, buttons and axis events come from the same
    device (most of the time).
    
    Suggested-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
    (cherry picked from commit a4095162ca923992a8cfae6d0f09ff9f8144762a)
    (cherry picked from commit 20c78f38a0b33b88bc82a2bcd54d2e6c74a4c132)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index b1413b11f..3e4fe2b91 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -92,6 +92,15 @@ xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl)
     /* Nothing to do, dix handles all settings */
 }
 
+static DeviceIntPtr
+get_pointer_device(struct xwl_seat *xwl_seat)
+{
+    if (xwl_seat->relative_pointer)
+        return xwl_seat->relative_pointer;
+    else
+        return xwl_seat->pointer;
+}
+
 static Bool
 init_pointer_buttons(DeviceIntPtr device)
 {
@@ -396,7 +405,7 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
                      wl_fixed_t sx_w, wl_fixed_t sy_w)
 {
     struct xwl_seat *xwl_seat = data;
-    DeviceIntPtr dev = xwl_seat->pointer;
+    DeviceIntPtr dev = get_pointer_device(xwl_seat);
     DeviceIntPtr master;
     int i;
     int sx = wl_fixed_to_int(sx_w);
@@ -471,7 +480,7 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer,
                      uint32_t serial, struct wl_surface *surface)
 {
     struct xwl_seat *xwl_seat = data;
-    DeviceIntPtr dev = xwl_seat->pointer;
+    DeviceIntPtr dev = get_pointer_device(xwl_seat);
 
     xwl_seat->xwl_screen->serial = serial;
 
@@ -619,7 +628,7 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
     }
 
     valuator_mask_zero(&mask);
-    QueuePointerEvents(xwl_seat->pointer,
+    QueuePointerEvents(get_pointer_device(xwl_seat),
                        state ? ButtonPress : ButtonRelease, index, 0, &mask);
 }
 
@@ -661,7 +670,9 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
     } else {
         valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
     }
-    QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask);
+
+    QueuePointerEvents(get_pointer_device(xwl_seat),
+                       MotionNotify, 0, POINTER_RELATIVE, &mask);
 }
 
 static void
commit 49c479a7c352265f9173efed44a9091dd696423c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Feb 11 15:32:34 2021 +0100

    xwayland: Add wheel axis to relative pointer
    
    The relative pointer only has 2 axis, if we want to route the mouse
    wheel events to that device, we need to add the axis definition, similar
    to what is done for the absolute pointer.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
    (cherry picked from commit 1abab61dc23d585860bc847bcecb1b0315977c27)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 5fe290b3c..b1413b11f 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -177,7 +177,7 @@ xwl_pointer_proc(DeviceIntPtr device, int what)
 static int
 xwl_pointer_proc_relative(DeviceIntPtr device, int what)
 {
-#define NAXES 2
+#define NAXES 4
     Atom axes_labels[NAXES] = { 0 };
 
     switch (what) {
@@ -186,6 +186,8 @@ xwl_pointer_proc_relative(DeviceIntPtr device, int what)
 
         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+        axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
+        axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
 
         /*
          * We'll never send buttons, but XGetPointerMapping might in certain
@@ -203,6 +205,13 @@ xwl_pointer_proc_relative(DeviceIntPtr device, int what)
                                NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
         InitValuatorAxisStruct(device, 1, axes_labels[1],
                                NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
+        InitValuatorAxisStruct(device, 2, axes_labels[2],
+                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
+        InitValuatorAxisStruct(device, 3, axes_labels[3],
+                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
+
+        SetScrollValuator(device, 2, SCROLL_TYPE_HORIZONTAL, 1.0, SCROLL_FLAG_NONE);
+        SetScrollValuator(device, 3, SCROLL_TYPE_VERTICAL, 1.0, SCROLL_FLAG_PREFERRED);
 
         if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
             return BadValue;
commit c3f86d2868663e80dbaeb8ae001883ca5cab1161
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Feb 9 13:33:05 2021 +0100

    xwayland: Split dispatch_pointer_motion_event
    
    This is a cleanup patch, no functional change.
    
    Split the function dispatch_pointer_motion_event() into three separate
    simpler functions, relative motion with a warp emulator, relative motion
    and absolute motion.
    
    This makes the code a lot easier to read for me, rather than having
    everything in a single function with nested if/else conditions.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 71817928247971566903d56c0571db61b7933747)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 48216c548..5fe290b3c 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -477,76 +477,88 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer,
 }
 
 static void
-dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
+dispatch_relative_motion_with_warp(struct xwl_seat *xwl_seat)
+{
+    double dx, dx_unaccel;
+    double dy, dy_unaccel;
+
+    dx = xwl_seat->pending_pointer_event.dx;
+    dy = xwl_seat->pending_pointer_event.dy;
+    dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
+    dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
+
+    xwl_pointer_warp_emulator_handle_motion(xwl_seat->pointer_warp_emulator,
+                                            dx, dy,
+                                            dx_unaccel, dy_unaccel);
+}
+
+static void
+dispatch_absolute_motion(struct xwl_seat *xwl_seat)
 {
     ValuatorMask mask;
+    DeviceIntPtr device;
+    int flags;
+    int event_x = wl_fixed_to_int(xwl_seat->pending_pointer_event.x);
+    int event_y = wl_fixed_to_int(xwl_seat->pending_pointer_event.y);
+    int drawable_x = xwl_seat->focus_window->window->drawable.x;
+    int drawable_y = xwl_seat->focus_window->window->drawable.y;
+    int x;
+    int y;
 
-    if (xwl_seat->pointer_warp_emulator &&
-        xwl_seat->pending_pointer_event.has_relative) {
-        double dx;
-        double dy;
-        double dx_unaccel;
-        double dy_unaccel;
-
-        dx = xwl_seat->pending_pointer_event.dx;
-        dy = xwl_seat->pending_pointer_event.dy;
-        dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
-        dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
-        xwl_pointer_warp_emulator_handle_motion(xwl_seat->pointer_warp_emulator,
-                                                dx, dy,
-                                                dx_unaccel, dy_unaccel);
-    } else if (xwl_seat->pending_pointer_event.has_absolute ||
-               xwl_seat->pending_pointer_event.has_relative) {
-        if (xwl_seat->pending_pointer_event.has_relative) {
-            double dx, dx_unaccel;
-            double dy, dy_unaccel;
-
-            dx = xwl_seat->pending_pointer_event.dx;
-            dy = xwl_seat->pending_pointer_event.dy;
-            dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
-            dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
-
-            valuator_mask_zero(&mask);
-            valuator_mask_set_unaccelerated(&mask, 0, dx, dx_unaccel);
-            valuator_mask_set_unaccelerated(&mask, 1, dy, dy_unaccel);
-
-            QueuePointerEvents(xwl_seat->relative_pointer, MotionNotify, 0,
-                               POINTER_RAWONLY, &mask);
-        }
+    if (xwl_window_has_viewport_enabled(xwl_seat->focus_window)) {
+        event_x *= xwl_seat->focus_window->scale_x;
+        event_y *= xwl_seat->focus_window->scale_y;
+    }
 
-        if (xwl_seat->pending_pointer_event.has_absolute) {
-            ValuatorMask mask;
-            DeviceIntPtr device;
-            int flags;
-            int sx = wl_fixed_to_int(xwl_seat->pending_pointer_event.x);
-            int sy = wl_fixed_to_int(xwl_seat->pending_pointer_event.y);
-            int dx = xwl_seat->focus_window->window->drawable.x;
-            int dy = xwl_seat->focus_window->window->drawable.y;
-            int x;
-            int y;
-
-            if (xwl_window_has_viewport_enabled(xwl_seat->focus_window)) {
-                sx *= xwl_seat->focus_window->scale_x;
-                sy *= xwl_seat->focus_window->scale_y;
-            }
+    x = drawable_x + event_x;
+    y = drawable_y + event_y;
 
-            x = dx + sx;
-            y = dy + sy;
+    valuator_mask_zero(&mask);
+    valuator_mask_set(&mask, 0, x);
+    valuator_mask_set(&mask, 1, y);
 
-            valuator_mask_zero(&mask);
-            valuator_mask_set(&mask, 0, x);
-            valuator_mask_set(&mask, 1, y);
+    if (xwl_seat->pending_pointer_event.has_relative) {
+         flags = POINTER_ABSOLUTE | POINTER_SCREEN | POINTER_NORAW;
+         device = xwl_seat->relative_pointer;
+    } else {
+         flags = POINTER_ABSOLUTE | POINTER_SCREEN;
+         device = xwl_seat->pointer;
+    }
 
-            if (xwl_seat->pending_pointer_event.has_relative) {
-                 flags = POINTER_ABSOLUTE | POINTER_SCREEN | POINTER_NORAW;
-                 device = xwl_seat->relative_pointer;
-            } else {
-                 flags = POINTER_ABSOLUTE | POINTER_SCREEN;
-                 device = xwl_seat->pointer;
-            }
+    QueuePointerEvents(device, MotionNotify, 0, flags, &mask);
+}
 
-            QueuePointerEvents(device, MotionNotify, 0, flags, &mask);
-        }
+static void
+dispatch_relative_motion(struct xwl_seat *xwl_seat)
+{
+    ValuatorMask mask;
+    double event_dx = xwl_seat->pending_pointer_event.dx;
+    double event_dy = xwl_seat->pending_pointer_event.dy;
+    double event_dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
+    double event_dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
+
+    valuator_mask_zero(&mask);
+    valuator_mask_set_unaccelerated(&mask, 0, event_dx, event_dx_unaccel);
+    valuator_mask_set_unaccelerated(&mask, 1, event_dy, event_dy_unaccel);
+
+    QueuePointerEvents(xwl_seat->relative_pointer, MotionNotify, 0,
+                       POINTER_RAWONLY, &mask);
+}
+
+static void
+dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
+{
+    Bool has_relative = xwl_seat->pending_pointer_event.has_relative;
+    Bool has_absolute = xwl_seat->pending_pointer_event.has_absolute;
+
+    if (xwl_seat->pointer_warp_emulator && has_relative) {
+        dispatch_relative_motion_with_warp(xwl_seat);
+    } else {
+        if (has_relative)
+            dispatch_relative_motion(xwl_seat);
+
+        if (has_absolute)
+            dispatch_absolute_motion(xwl_seat);
     }
 
     xwl_seat->pending_pointer_event.has_absolute = FALSE;
commit 2e212551d6922c9d7f1b2d18eddf780438c33a7f
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Feb 9 13:04:59 2021 +0100

    xwayland: Use relative values for raw events
    
    Xwayland supports relative motion events from the Wayland compositor via
    the relative-pointer protocol, and converts those to the absolute range
    in device units for raw events.
    
    Some X11 clients however wrongly assume relative values in the axis
    values even for devices explicitly labeled as absolute. While this is a
    bug in the client, such applications would work fine in plain Xorg but
    not with Xwayland.
    
    To avoid that issue, use the relative values for raw events without
    conversion, so that such application continue to work in Xwayland.
    
    Thanks Peter for figuring out the root cause.
    
    v2: Don't duplicate relative and absolute events (Peter)
    v3: Use POINTER_RAWONLY (Peter)
    
    Suggested-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
    (cherry picked from commit c5c5322ad69b0751f16c785a479b2989b8794235)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 2e4b20024..48216c548 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -497,14 +497,33 @@ dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
                                                 dx_unaccel, dy_unaccel);
     } else if (xwl_seat->pending_pointer_event.has_absolute ||
                xwl_seat->pending_pointer_event.has_relative) {
-        int x;
-        int y;
+        if (xwl_seat->pending_pointer_event.has_relative) {
+            double dx, dx_unaccel;
+            double dy, dy_unaccel;
+
+            dx = xwl_seat->pending_pointer_event.dx;
+            dy = xwl_seat->pending_pointer_event.dy;
+            dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
+            dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
+
+            valuator_mask_zero(&mask);
+            valuator_mask_set_unaccelerated(&mask, 0, dx, dx_unaccel);
+            valuator_mask_set_unaccelerated(&mask, 1, dy, dy_unaccel);
+
+            QueuePointerEvents(xwl_seat->relative_pointer, MotionNotify, 0,
+                               POINTER_RAWONLY, &mask);
+        }
 
         if (xwl_seat->pending_pointer_event.has_absolute) {
+            ValuatorMask mask;
+            DeviceIntPtr device;
+            int flags;
             int sx = wl_fixed_to_int(xwl_seat->pending_pointer_event.x);
             int sy = wl_fixed_to_int(xwl_seat->pending_pointer_event.y);
             int dx = xwl_seat->focus_window->window->drawable.x;
             int dy = xwl_seat->focus_window->window->drawable.y;
+            int x;
+            int y;
 
             if (xwl_window_has_viewport_enabled(xwl_seat->focus_window)) {
                 sx *= xwl_seat->focus_window->scale_x;
@@ -513,26 +532,21 @@ dispatch_pointer_motion_event(struct xwl_seat *xwl_seat)
 
             x = dx + sx;
             y = dy + sy;
-        } else {
-            miPointerGetPosition(xwl_seat->pointer, &x, &y);
-        }
 
-        valuator_mask_zero(&mask);
-        if (xwl_seat->pending_pointer_event.has_relative) {
-            double dx_unaccel;
-            double dy_unaccel;
-
-            dx_unaccel = xwl_seat->pending_pointer_event.dx_unaccel;
-            dy_unaccel = xwl_seat->pending_pointer_event.dy_unaccel;
-            valuator_mask_set_absolute_unaccelerated(&mask, 0, x, dx_unaccel);
-            valuator_mask_set_absolute_unaccelerated(&mask, 1, y, dy_unaccel);
-        } else {
+            valuator_mask_zero(&mask);
             valuator_mask_set(&mask, 0, x);
             valuator_mask_set(&mask, 1, y);
-        }
 
-        QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0,
-                           POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
+            if (xwl_seat->pending_pointer_event.has_relative) {
+                 flags = POINTER_ABSOLUTE | POINTER_SCREEN | POINTER_NORAW;
+                 device = xwl_seat->relative_pointer;
+            } else {
+                 flags = POINTER_ABSOLUTE | POINTER_SCREEN;
+                 device = xwl_seat->pointer;
+            }
+
+            QueuePointerEvents(device, MotionNotify, 0, flags, &mask);
+        }
     }
 
     xwl_seat->pending_pointer_event.has_absolute = FALSE;
commit 7531d71663320d47be6e0a8b73acc3ae2f84dc8c
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Tue Feb 9 13:01:21 2021 +0100

    xwayland: Use a resolution of 0 for relative motion
    
    That's what evdev/libinput drivers do.
    
    Suggested-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
    (cherry picked from commit ebdb2e264676c3b27a708328348efe73e0d3c8c2)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 8e57fda1d..2e4b20024 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -200,9 +200,9 @@ xwl_pointer_proc_relative(DeviceIntPtr device, int what)
 
         /* Valuators */
         InitValuatorAxisStruct(device, 0, axes_labels[0],
-                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative);
+                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
         InitValuatorAxisStruct(device, 1, axes_labels[1],
-                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 1, 0, 1, Relative);
+                               NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0, Relative);
 
         if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control))
             return BadValue;
commit 0663a245ad5c283fc3938e6d61d4726344556660
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Feb 11 09:48:12 2021 +0100

    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 <peter.hutterer at who-t.net>
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Related: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1130
    (cherry picked from commit b5e1f13681090fc327dc2cabee1dc123273e785b)

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,35 +1458,36 @@ 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);
+        /* 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;
-    }
+        if (flags & POINTER_EMULATED)
+            event->flags = XIPointerEmulated;
 
-    set_valuators(pDev, event, &mask);
+        set_valuators(pDev, event, &mask);
+    }
 
     return num_events;
 }
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)


More information about the xorg-commit mailing list