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:
parent
bfbd1bb744
commit
c736a75712
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user