From 9e9446bab80664aa707d8360ef8956ca6851b32d Mon Sep 17 00:00:00 2001 From: Daniel d'Andrada Date: Thu, 11 Jan 2018 11:08:29 +0100 Subject: TouchEmulationX11: leave XI2 event intact after processing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise the XCB QPA will get a modified event once it processes it after this native filter Change-Id: Idc27edb7d0925ac03f53a7fc8fcdba96be5d89ca Reviewed-by: Lukáš Tinkl Reviewed-by: Robert Griebl --- src/window-lib/touchemulation_x11.cpp | 83 +++++++++++++++++++++++------------ src/window-lib/touchemulation_x11.h | 5 +++ 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/src/window-lib/touchemulation_x11.cpp b/src/window-lib/touchemulation_x11.cpp index 2fef4a60..02f5b18a 100644 --- a/src/window-lib/touchemulation_x11.cpp +++ b/src/window-lib/touchemulation_x11.cpp @@ -80,6 +80,7 @@ static Qt::MouseButton xcbButtonToQtMouseButton(xcb_button_t detail) } } +// Function copied from the XCB QPA static void xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event) { // xcb event structs contain stuff that wasn't on the wire, the full_sequence field @@ -149,6 +150,10 @@ bool TouchEmulationX11::nativeEventFilter(const QByteArray &eventType, void *mes return false; auto xcbGeneric = reinterpret_cast(xcbEvent); + + // Because xi2PrepareXIGenericDeviceEvent modifies data inplace + backupEventData(xcbGeneric); + xi2PrepareXIGenericDeviceEvent(xcbGeneric); auto xiEvent = reinterpret_cast(xcbGeneric); xXIDeviceEvent *xiDeviceEvent = nullptr; @@ -163,34 +168,42 @@ bool TouchEmulationX11::nativeEventFilter(const QByteArray &eventType, void *mes break; } - if (!xiDeviceEvent) - return false; - - switch (xiDeviceEvent->evtype) { - case XI_ButtonPress: - return handleButtonPress( - static_cast(xiDeviceEvent->event), - xiDeviceEvent->detail, - xiDeviceEvent->mods.base_mods, - fixed1616ToReal(xiDeviceEvent->event_x), - fixed1616ToReal(xiDeviceEvent->event_y)); - case XI_ButtonRelease: - return handleButtonRelease( - static_cast(xiDeviceEvent->event), - xiDeviceEvent->detail, - xiDeviceEvent->mods.base_mods, - fixed1616ToReal(xiDeviceEvent->event_x), - fixed1616ToReal(xiDeviceEvent->event_y)); - case XI_Motion: - return handleMotionNotify( - static_cast(xiDeviceEvent->event), - xiDeviceEvent->mods.base_mods, - fixed1616ToReal(xiDeviceEvent->event_x), - fixed1616ToReal(xiDeviceEvent->event_y)); - return true; - default: - return false; + bool result = false; + + if (xiDeviceEvent) { + switch (xiDeviceEvent->evtype) { + case XI_ButtonPress: + result = handleButtonPress( + static_cast(xiDeviceEvent->event), + xiDeviceEvent->detail, + xiDeviceEvent->mods.base_mods, + fixed1616ToReal(xiDeviceEvent->event_x), + fixed1616ToReal(xiDeviceEvent->event_y)); + break; + case XI_ButtonRelease: + result = handleButtonRelease( + static_cast(xiDeviceEvent->event), + xiDeviceEvent->detail, + xiDeviceEvent->mods.base_mods, + fixed1616ToReal(xiDeviceEvent->event_x), + fixed1616ToReal(xiDeviceEvent->event_y)); + break; + case XI_Motion: + result = handleMotionNotify( + static_cast(xiDeviceEvent->event), + xiDeviceEvent->mods.base_mods, + fixed1616ToReal(xiDeviceEvent->event_x), + fixed1616ToReal(xiDeviceEvent->event_y)); + result = true; + break; + default: + break; + } } + + // Put the event back in its original state so that the XCB QPA can process it normally + restoreEventData(xcbGeneric); + return result; } default: return false; @@ -271,4 +284,20 @@ QWindow *TouchEmulationX11::findQWindowWithXWindowID(WId windowId) return foundWindow; } + +// backup event data before a xi2PrepareXIGenericDeviceEvent() call +void TouchEmulationX11::backupEventData(void *event) +{ + memcpy((char*)&(m_xiEventBackupData[0]), (char*) event + 32, 4); +} + +// restore event data after a xi2PrepareXIGenericDeviceEvent() call +void TouchEmulationX11::restoreEventData(void *ev) +{ + auto *event = (xcb_ge_event_t *)ev; + + memmove((char*) event + 36, (char*) event + 32, event->length * 4); + memcpy((char*) event + 32, (char*)&(m_xiEventBackupData[0]), 4); +} + QT_END_NAMESPACE_AM diff --git a/src/window-lib/touchemulation_x11.h b/src/window-lib/touchemulation_x11.h index 8f089636..d45faea2 100644 --- a/src/window-lib/touchemulation_x11.h +++ b/src/window-lib/touchemulation_x11.h @@ -68,9 +68,14 @@ private: bool handleMotionNotify(WId windowId, uint32_t modifiers, int x, int y); QWindow *findQWindowWithXWindowID(WId windowId); + void backupEventData(void *event); + void restoreEventData(void *event); + QTouchDevice *m_touchDevice = nullptr; bool m_haveXInput2 = false; bool m_leftButtonIsPressed = false; + + quint8 m_xiEventBackupData[4]; }; QT_END_NAMESPACE_AM -- cgit v1.2.3