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 <gunnar.sletta@digia.com> Reviewed-by: Andy Nichols <andy.nichols@digia.com>
This commit is contained in:
parent
61e0534aff
commit
cfd5284249
@ -114,6 +114,7 @@ public:
|
|||||||
int findClosestContact(const QHash<int, Contact> &contacts, int x, int y, int *dist);
|
int findClosestContact(const QHash<int, Contact> &contacts, int x, int y, int *dist);
|
||||||
void reportPoints();
|
void reportPoints();
|
||||||
void registerDevice();
|
void registerDevice();
|
||||||
|
void addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates);
|
||||||
|
|
||||||
int hw_range_x_min;
|
int hw_range_x_min;
|
||||||
int hw_range_x_max;
|
int hw_range_x_max;
|
||||||
@ -342,6 +343,31 @@ void QEvdevTouchScreenHandler::readData()
|
|||||||
d->processInputEvent(&buffer[i]);
|
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)
|
void QEvdevTouchScreenData::processInputEvent(input_event *data)
|
||||||
{
|
{
|
||||||
if (data->type == EV_ABS) {
|
if (data->type == EV_ABS) {
|
||||||
@ -398,13 +424,11 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
|
|||||||
|
|
||||||
m_touchPoints.clear();
|
m_touchPoints.clear();
|
||||||
Qt::TouchPointStates combinedStates;
|
Qt::TouchPointStates combinedStates;
|
||||||
|
|
||||||
QMutableHashIterator<int, Contact> it(m_contacts);
|
QMutableHashIterator<int, Contact> it(m_contacts);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
QWindowSystemInterface::TouchPoint tp;
|
|
||||||
Contact &contact(it.value());
|
Contact &contact(it.value());
|
||||||
tp.id = contact.trackingId;
|
|
||||||
tp.flags = contact.flags;
|
|
||||||
|
|
||||||
int key = m_typeB ? it.key() : contact.trackingId;
|
int key = m_typeB ? it.key() : contact.trackingId;
|
||||||
if (m_lastContacts.contains(key)) {
|
if (m_lastContacts.contains(key)) {
|
||||||
@ -427,29 +451,24 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tp.state = contact.state;
|
addTouchPoint(contact, &combinedStates);
|
||||||
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);
|
|
||||||
|
|
||||||
if (contact.state == Qt::TouchPointReleased)
|
if (contact.state == Qt::TouchPointReleased)
|
||||||
it.remove();
|
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;
|
m_lastContacts = m_contacts;
|
||||||
if (!m_typeB && !m_singleTouch)
|
if (!m_typeB && !m_singleTouch)
|
||||||
m_contacts.clear();
|
m_contacts.clear();
|
||||||
|
Loading…
Reference in New Issue
Block a user