From 317ce1201a2ec848f9066294ea544b756f735385 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 7 Feb 2017 12:23:46 +1000 Subject: [PATCH xserver 06/12] xwayland: handle button events after motion events Make sure the button events are sent after the motion events into the new position. Signed-off-by: Peter Hutterer Acked-by: Ping Cheng (cherry picked from commit 773b04748d0c839bc8b12e33f74bb8d11c447f5b) --- hw/xwayland/xwayland-input.c | 44 +++++++++++++++++++++++++++++++++++++------- hw/xwayland/xwayland.h | 3 +++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 142862f7e..50da10839 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "tablet-unstable-v2-client-protocol.h" /* Copied from mipointer.c */ @@ -1543,8 +1544,8 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool, { struct xwl_tablet_tool *xwl_tablet_tool = data; struct xwl_seat *xwl_seat = xwl_tablet_tool->seat; + uint32_t *mask = &xwl_tablet_tool->buttons_now; int xbtn = 0; - ValuatorMask mask; /* BTN_0 .. BTN_9 */ if (button >= 0x100 && button <= 0x109) { @@ -1592,11 +1593,14 @@ tablet_tool_button_state(void *data, struct zwp_tablet_tool_v2 *tool, return; } - xwl_seat->xwl_screen->serial = serial; + BUG_RETURN(xbtn >= 8 * sizeof(*mask)); - valuator_mask_zero(&mask); - QueuePointerEvents(xwl_tablet_tool->xdevice, - state ? ButtonPress : ButtonRelease, xbtn, 0, &mask); + if (state) + SetBit(mask, xbtn); + else + ClearBit(mask, xbtn); + + xwl_seat->xwl_screen->serial = serial; } static void @@ -1604,6 +1608,8 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) { struct xwl_tablet_tool *xwl_tablet_tool = data; ValuatorMask mask; + uint32_t released, pressed, diff; + int button; valuator_mask_zero(&mask); valuator_mask_set(&mask, 0, xwl_tablet_tool->x); @@ -1613,10 +1619,34 @@ tablet_tool_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) valuator_mask_set(&mask, 4, xwl_tablet_tool->tilt_y); valuator_mask_set(&mask, 5, xwl_tablet_tool->rotation + xwl_tablet_tool->slider); - /* FIXME: Store button mask in xwl_tablet_tool and send events *HERE* if - changed */ QueuePointerEvents(xwl_tablet_tool->xdevice, MotionNotify, 0, POINTER_ABSOLUTE | POINTER_SCREEN, &mask); + + valuator_mask_zero(&mask); + + diff = xwl_tablet_tool->buttons_prev ^ xwl_tablet_tool->buttons_now; + released = diff & ~xwl_tablet_tool->buttons_now; + pressed = diff & xwl_tablet_tool->buttons_now; + + button = 1; + while (released) { + if (released & 0x1) + QueuePointerEvents(xwl_tablet_tool->xdevice, + ButtonRelease, button, 0, &mask); + button++; + released >>= 1; + } + + button = 1; + while (pressed) { + if (pressed & 0x1) + QueuePointerEvents(xwl_tablet_tool->xdevice, + ButtonPress, button, 0, &mask); + button++; + pressed >>= 1; + } + + xwl_tablet_tool->buttons_prev = xwl_tablet_tool->buttons_now; } static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index fb9ac4804..bb119dad7 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -202,6 +202,9 @@ struct xwl_tablet_tool { float tilt_y; float rotation; float slider; + + uint32_t buttons_now, + buttons_prev; }; struct xwl_tablet_pad { -- 2.13.5