From cb37ab82982569ef316d4948e0f13a9bfa6b3f55 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 13 Jun 2014 15:54:56 +0200 Subject: [PATCH] xcb: support Wacom touch devices; distinguish from tablets A tablet which can also do touch will show up as several XInput devices. The touch device should be treated as a touch pad, not as a tablet. [ChangeLog][Platform Specific Changes][X11 / XCB] Wacom touch devices are not mistaken for additional graphics tablets Task-number: QTBUG-39572 Change-Id: I7a61a4c0d82925080edb0175b7d03870748f55ce Reviewed-by: Shawn Rutledge Reviewed-by: Allan Sandfeld Jensen --- .../platforms/xcb/qxcbconnection_xi2.cpp | 50 ++++++++++++++++--- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 60a36a8da1..879862b9d2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -190,17 +190,43 @@ void QXcbConnection::xi2SetupDevices() } bool isTablet = false; #ifndef QT_NO_TABLETEVENT - // If we have found the valuators which we expect a tablet to have, assume it's a tablet. + // If we have found the valuators which we expect a tablet to have, it might be a tablet. if (tabletData.valuatorInfo.contains(QXcbAtom::AbsX) && tabletData.valuatorInfo.contains(QXcbAtom::AbsY) && - tabletData.valuatorInfo.contains(QXcbAtom::AbsPressure)) { - tabletData.deviceId = devices[i].deviceid; - tabletData.pointerType = QTabletEvent::Pen; - if (QByteArray(devices[i].name).toLower().contains("eraser")) - tabletData.pointerType = QTabletEvent::Eraser; - m_tabletData.append(tabletData); + tabletData.valuatorInfo.contains(QXcbAtom::AbsPressure)) isTablet = true; - qCDebug(lcQpaXInputDevices) << " it's a tablet with pointer type" << tabletData.pointerType; + + // But we need to be careful not to take the touch and tablet-button devices as tablets. + QByteArray name = QByteArray(devices[i].name).toLower(); + QString dbgType = QLatin1String("UNKNOWN"); + if (name.contains("eraser")) { + isTablet = true; + tabletData.pointerType = QTabletEvent::Eraser; + dbgType = QLatin1String("eraser"); + } else if (name.contains("cursor")) { + isTablet = true; + tabletData.pointerType = QTabletEvent::Cursor; + dbgType = QLatin1String("cursor"); + } else if ((name.contains("pen") || name.contains("stylus")) && isTablet) { + tabletData.pointerType = QTabletEvent::Pen; + dbgType = QLatin1String("pen"); + } else if (name.contains("wacom") && isTablet && !name.contains("touch")) { + // combined device (evdev) rather than separate pen/eraser (wacom driver) + tabletData.pointerType = QTabletEvent::Pen; + dbgType = QLatin1String("pen"); + } else if (name.contains("aiptek") /* && device == QXcbAtom::KEYBOARD */) { + // some "Genius" tablets + isTablet = true; + tabletData.pointerType = QTabletEvent::Pen; + dbgType = QLatin1String("pen"); + } else { + isTablet = false; + } + + if (isTablet) { + tabletData.deviceId = devices[i].deviceid; + m_tabletData.append(tabletData); + qCDebug(lcQpaXInputDevices) << " it's a tablet with pointer type" << dbgType; } #endif // QT_NO_TABLETEVENT @@ -378,6 +404,10 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) } else if (vci->label == atom(QXcbAtom::RelY)) { hasRelativeCoords = true; dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution); + } else if (vci->label == atom(QXcbAtom::AbsX)) { + dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution); + } else if (vci->label == atom(QXcbAtom::AbsY)) { + dev->size.setWidth((vci->max - vci->min) * 1000.0 / vci->resolution); } break; } @@ -492,6 +522,10 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) nx = valuatorNormalized(value, vci); } else if (vci->label == atom(QXcbAtom::RelY)) { ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsY)) { + ny = valuatorNormalized(value, vci); } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) { nx = valuatorNormalized(value, vci); } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) {