From cfd52842492d12af26d897e0f893c80b2df5945a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 17 Sep 2013 12:26:03 +0200 Subject: evdevtouch: Make TouchPointReleased working with certain drivers The plugin failed to handle releases with protocol type A with some drivers. There is no requirement to emit ABS_MT_TOUCH_MAJOR or BTN_TOUCH to indicate a release. If the point is gone from the report, it is a release as well. Change-Id: I9527fbfb200fde3b160148e076357a29bf610427 Reviewed-by: Gunnar Sletta Reviewed-by: Andy Nichols --- .../input/evdevtouch/qevdevtouch.cpp | 61 ++++++++++++++-------- 1 file changed, 40 insertions(+), 21 deletions(-) (limited to 'src/platformsupport/input') diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp index 457b929e98..08f9860ccf 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp @@ -114,6 +114,7 @@ public: int findClosestContact(const QHash &contacts, int x, int y, int *dist); void reportPoints(); void registerDevice(); + void addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates); int hw_range_x_min; int hw_range_x_max; @@ -342,6 +343,31 @@ void QEvdevTouchScreenHandler::readData() d->processInputEvent(&buffer[i]); } +void QEvdevTouchScreenData::addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates) +{ + QWindowSystemInterface::TouchPoint tp; + tp.id = contact.trackingId; + tp.flags = contact.flags; + tp.state = contact.state; + *combinedStates |= tp.state; + + // Store the HW coordinates for now, will be updated later. + tp.area = QRectF(0, 0, contact.maj, contact.maj); + tp.area.moveCenter(QPoint(contact.x, contact.y)); + tp.pressure = contact.pressure; + + // Get a normalized position in range 0..1. + tp.normalPosition = QPointF((contact.x - hw_range_x_min) / qreal(hw_range_x_max - hw_range_x_min), + (contact.y - hw_range_y_min) / qreal(hw_range_y_max - hw_range_y_min)); + + if (!m_rotate.isIdentity()) + tp.normalPosition = m_rotate.map(tp.normalPosition); + + tp.rawPositions.append(QPointF(contact.x, contact.y)); + + m_touchPoints.append(tp); +} + void QEvdevTouchScreenData::processInputEvent(input_event *data) { if (data->type == EV_ABS) { @@ -398,13 +424,11 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data) m_touchPoints.clear(); Qt::TouchPointStates combinedStates; + QMutableHashIterator it(m_contacts); while (it.hasNext()) { it.next(); - QWindowSystemInterface::TouchPoint tp; Contact &contact(it.value()); - tp.id = contact.trackingId; - tp.flags = contact.flags; int key = m_typeB ? it.key() : contact.trackingId; if (m_lastContacts.contains(key)) { @@ -427,29 +451,24 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data) continue; } - tp.state = contact.state; - combinedStates |= tp.state; - - // Store the HW coordinates for now, will be updated later. - tp.area = QRectF(0, 0, contact.maj, contact.maj); - tp.area.moveCenter(QPoint(contact.x, contact.y)); - tp.pressure = contact.pressure; - - // Get a normalized position in range 0..1. - tp.normalPosition = QPointF((contact.x - hw_range_x_min) / qreal(hw_range_x_max - hw_range_x_min), - (contact.y - hw_range_y_min) / qreal(hw_range_y_max - hw_range_y_min)); - - if (!m_rotate.isIdentity()) - tp.normalPosition = m_rotate.map(tp.normalPosition); - - tp.rawPositions.append(QPointF(contact.x, contact.y)); - - m_touchPoints.append(tp); + addTouchPoint(contact, &combinedStates); if (contact.state == Qt::TouchPointReleased) it.remove(); } + // Now look for contacts that have disappeared since the last sync. + it = m_lastContacts; + while (it.hasNext()) { + it.next(); + Contact &contact(it.value()); + int key = m_typeB ? it.key() : contact.trackingId; + if (!m_contacts.contains(key)) { + contact.state = Qt::TouchPointReleased; + addTouchPoint(contact, &combinedStates); + } + } + m_lastContacts = m_contacts; if (!m_typeB && !m_singleTouch) m_contacts.clear(); -- cgit v1.2.3