summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel d'Andrada <daniel.dandrada@luxoft.com>2018-01-11 11:08:29 +0100
committerRobert Griebl <robert.griebl@pelagicore.com>2018-01-11 15:42:18 +0000
commit9e9446bab80664aa707d8360ef8956ca6851b32d (patch)
treea60132485e96918842ae11261841043f7c6a9605
parent348203c0dc4c859af7db9d9cfc13b33ea1e110bd (diff)
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.cpp83
-rw-r--r--src/window-lib/touchemulation_x11.h5
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