diff options
author | Daniel d'Andrada <daniel.dandrada@luxoft.com> | 2018-01-11 11:08:29 +0100 |
---|---|---|
committer | Robert Griebl <robert.griebl@pelagicore.com> | 2018-01-11 15:42:18 +0000 |
commit | 9e9446bab80664aa707d8360ef8956ca6851b32d (patch) | |
tree | a60132485e96918842ae11261841043f7c6a9605 | |
parent | 348203c0dc4c859af7db9d9cfc13b33ea1e110bd (diff) | |
download | qtapplicationmanager-9e9446bab80664aa707d8360ef8956ca6851b32d.tar.gz |
TouchEmulationX11: leave XI2 event intact after processing it
Otherwise the XCB QPA will get a modified event once it processes it
after this native filter
Change-Id: Idc27edb7d0925ac03f53a7fc8fcdba96be5d89ca
Reviewed-by: Lukáš Tinkl <ltinkl@luxoft.com>
Reviewed-by: Robert Griebl <robert.griebl@pelagicore.com>
-rw-r--r-- | src/window-lib/touchemulation_x11.cpp | 83 | ||||
-rw-r--r-- | 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<xcb_ge_event_t *>(xcbEvent); + + // Because xi2PrepareXIGenericDeviceEvent modifies data inplace + backupEventData(xcbGeneric); + xi2PrepareXIGenericDeviceEvent(xcbGeneric); auto xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(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<WId>(xiDeviceEvent->event), - xiDeviceEvent->detail, - xiDeviceEvent->mods.base_mods, - fixed1616ToReal(xiDeviceEvent->event_x), - fixed1616ToReal(xiDeviceEvent->event_y)); - case XI_ButtonRelease: - return handleButtonRelease( - static_cast<WId>(xiDeviceEvent->event), - xiDeviceEvent->detail, - xiDeviceEvent->mods.base_mods, - fixed1616ToReal(xiDeviceEvent->event_x), - fixed1616ToReal(xiDeviceEvent->event_y)); - case XI_Motion: - return handleMotionNotify( - static_cast<WId>(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<WId>(xiDeviceEvent->event), + xiDeviceEvent->detail, + xiDeviceEvent->mods.base_mods, + fixed1616ToReal(xiDeviceEvent->event_x), + fixed1616ToReal(xiDeviceEvent->event_y)); + break; + case XI_ButtonRelease: + result = handleButtonRelease( + static_cast<WId>(xiDeviceEvent->event), + xiDeviceEvent->detail, + xiDeviceEvent->mods.base_mods, + fixed1616ToReal(xiDeviceEvent->event_x), + fixed1616ToReal(xiDeviceEvent->event_y)); + break; + case XI_Motion: + result = handleMotionNotify( + static_cast<WId>(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 |