From cd26e66c2e8ddde06b5e22ef28d815ac1082a7c4 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Tue, 23 Aug 2016 10:44:20 +0200 Subject: Combine device and point id into 32 bit point id This allows us to not have conflicts between the point ids between different devices for QtQuick pointer handlers. We do this in QtGui because we can then safely compare point ids from QTouchEvent::TouchPoint and QQuickEventPoint. (Point ids that QtQuick pointer handlers use will be based on the point ids provided by QTouchEvent::TouchPoint::id) Change-Id: I8b9ab0d44224b15175b820d33cbb2d8bd21e99f2 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qwindowsysteminterface.cpp | 43 ++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'src/gui/kernel/qwindowsysteminterface.cpp') diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index bb778bc5fc7..ecc84e73d74 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -460,9 +460,40 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device, handleTouchEvent(w, time, device, points, mods); } +static int g_nextPointId = 1; + +// map from device-independent point id (arbitrary) to "Qt point" ids +typedef QMap PointIdMap; +Q_GLOBAL_STATIC(PointIdMap, g_pointIdMap) + +/*! + This function maps potentially arbitrary point ids \a pointId in the 32 bit + value space to start from 1 and increase incrementally for each touch point + held down. If all touch points are released it will reset the id back to 1 + for the following touch point. + + We can then assume that the touch points ids will never become too large, + and it will then put the device identifier \a deviceId in the upper 8 bits. + This leaves us with max 255 devices, and 16.7M taps without full release + before we run out of value space. +*/ +static int acquireCombinedPointId(quint8 deviceId, int pointId) +{ + quint64 combinedId64 = (quint64(deviceId) << 32) + pointId; + auto it = g_pointIdMap->constFind(combinedId64); + int uid; + if (it == g_pointIdMap->constEnd()) { + uid = g_nextPointId++; + g_pointIdMap->insert(combinedId64, uid); + } else { + uid = *it; + } + return (deviceId << 24) + uid; +} + QList QWindowSystemInterfacePrivate::fromNativeTouchPoints(const QList &points, - const QWindow *window, + const QWindow *window, quint8 deviceId, QEvent::Type *type) { QList touchPoints; @@ -473,7 +504,7 @@ QList QList::const_iterator point = points.constBegin(); QList::const_iterator end = points.constEnd(); while (point != end) { - p.setId(point->id); + p.setId(acquireCombinedPointId(deviceId, point->id)); if (point->uniqueId >= 0) p.setUniqueId(point->uniqueId); p.setPressure(point->pressure); @@ -506,6 +537,11 @@ QList *type = QEvent::TouchEnd; } + if (states == Qt::TouchPointReleased) { + g_nextPointId = 1; + g_pointIdMap->clear(); + } + return touchPoints; } @@ -540,7 +576,8 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo return; QEvent::Type type; - QList touchPoints = QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, tlw, &type); + QList touchPoints = + QWindowSystemInterfacePrivate::fromNativeTouchPoints(points, tlw, QTouchDevicePrivate::get(device)->id, &type); QWindowSystemInterfacePrivate::TouchEvent *e = new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods); -- cgit v1.2.3