Implement EVDEV_FLAG_MT_AUTOREL flag (autorelease touchpoints)

Automaticaly release (send ABS_MT_TRACKING_ID = -1) MT-slots
that has not been listed in current MT protocol type B report.

Slot is counted as listed if corresponding ABS_MT_SLOT event
has been sent regardless of other MT events.

Events are sent on SYN_REPORT event.

Submitted by:	Vladimir Kondratiev <wulf@cicgroup.ru>
This commit is contained in:
Oleksandr Tymoshenko 2016-10-08 17:59:53 +00:00
parent bfbd1bb744
commit c736a75712
4 changed files with 27 additions and 7 deletions

View File

@ -686,6 +686,8 @@ evdev_sparse_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
case EV_SYN:
if (code == SYN_REPORT) {
/* Count empty reports as well as non empty */
evdev->ev_report_count++;
/* Skip empty reports */
if (!evdev->ev_report_opened)
return (EV_SKIP_EVENT);
@ -722,10 +724,7 @@ evdev_propagate_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
EVDEV_CLIENT_UNLOCKQ(client);
}
/* Update counters */
evdev->ev_event_count++;
if (type == EV_SYN && code == SYN_REPORT)
evdev->ev_report_count++;
}
void
@ -765,6 +764,9 @@ evdev_push_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
if (evdev->ev_lock_type == EV_LOCK_INTERNAL)
EVDEV_LOCK(evdev);
evdev_modify_event(evdev, type, code, &value);
if (type == EV_SYN && code == SYN_REPORT &&
bit_test(evdev->ev_flags, EVDEV_FLAG_MT_AUTOREL))
evdev_send_mt_autorel(evdev);
if (type == EV_SYN && code == SYN_REPORT && evdev->ev_report_opened &&
bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
evdev_send_mt_compat(evdev);

View File

@ -70,6 +70,8 @@ extern int evdev_rcpt_mask;
#define EVDEV_FLAG_SOFTREPEAT 0x00 /* use evdev to repeat keys */
#define EVDEV_FLAG_MT_STCOMPAT 0x01 /* autogenerate ST-compatible events
* for MT protocol type B reports */
#define EVDEV_FLAG_MT_AUTOREL 0x02 /* Autorelease MT-slots not listed in
* current MT protocol type B report */
#define EVDEV_FLAG_MAX 0x1F
#define EVDEV_FLAG_CNT (EVDEV_FLAG_MAX + 1)

View File

@ -112,6 +112,7 @@ void
evdev_set_last_mt_slot(struct evdev_dev *evdev, int32_t slot)
{
evdev->ev_mt->ev_mt_slots[slot].ev_report = evdev->ev_report_count;
evdev->ev_mt->ev_mt_last_reported_slot = slot;
}
@ -128,10 +129,6 @@ evdev_set_mt_value(struct evdev_dev *evdev, int32_t slot, int16_t code,
int32_t value)
{
if (code == ABS_MT_TRACKING_ID && value == -1)
evdev->ev_mt->ev_mt_slots[slot].ev_report =
evdev->ev_report_count;
evdev->ev_mt->ev_mt_slots[slot].ev_mt_states[ABS_MT_INDEX(code)] =
value;
}
@ -275,3 +272,21 @@ evdev_push_mt_compat(struct evdev_dev *evdev)
if (evdev->ev_lock_type == EV_LOCK_INTERNAL)
EVDEV_UNLOCK(evdev);
}
void
evdev_send_mt_autorel(struct evdev_dev *evdev)
{
int32_t slot;
EVDEV_LOCK_ASSERT(evdev);
for (slot = 0; slot <= MAXIMAL_MT_SLOT(evdev); slot++) {
if (evdev->ev_mt->ev_mt_slots[slot].ev_report !=
evdev->ev_report_count &&
evdev_get_mt_value(evdev, slot, ABS_MT_TRACKING_ID) != -1){
evdev_send_event(evdev, EV_ABS, ABS_MT_SLOT, slot);
evdev_send_event(evdev, EV_ABS, ABS_MT_TRACKING_ID,
-1);
}
}
}

View File

@ -192,6 +192,7 @@ void evdev_set_last_mt_slot(struct evdev_dev *, int32_t);
int32_t evdev_get_mt_value(struct evdev_dev *, int32_t, int16_t);
void evdev_set_mt_value(struct evdev_dev *, int32_t, int16_t, int32_t);
void evdev_send_mt_compat(struct evdev_dev *);
void evdev_send_mt_autorel(struct evdev_dev *);
/* Utility functions: */
void evdev_client_dumpqueue(struct evdev_client *);