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:
|
case EV_SYN:
|
||||||
if (code == SYN_REPORT) {
|
if (code == SYN_REPORT) {
|
||||||
|
/* Count empty reports as well as non empty */
|
||||||
|
evdev->ev_report_count++;
|
||||||
/* Skip empty reports */
|
/* Skip empty reports */
|
||||||
if (!evdev->ev_report_opened)
|
if (!evdev->ev_report_opened)
|
||||||
return (EV_SKIP_EVENT);
|
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);
|
EVDEV_CLIENT_UNLOCKQ(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update counters */
|
|
||||||
evdev->ev_event_count++;
|
evdev->ev_event_count++;
|
||||||
if (type == EV_SYN && code == SYN_REPORT)
|
|
||||||
evdev->ev_report_count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)
|
if (evdev->ev_lock_type == EV_LOCK_INTERNAL)
|
||||||
EVDEV_LOCK(evdev);
|
EVDEV_LOCK(evdev);
|
||||||
evdev_modify_event(evdev, type, code, &value);
|
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 &&
|
if (type == EV_SYN && code == SYN_REPORT && evdev->ev_report_opened &&
|
||||||
bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
|
bit_test(evdev->ev_flags, EVDEV_FLAG_MT_STCOMPAT))
|
||||||
evdev_send_mt_compat(evdev);
|
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_SOFTREPEAT 0x00 /* use evdev to repeat keys */
|
||||||
#define EVDEV_FLAG_MT_STCOMPAT 0x01 /* autogenerate ST-compatible events
|
#define EVDEV_FLAG_MT_STCOMPAT 0x01 /* autogenerate ST-compatible events
|
||||||
* for MT protocol type B reports */
|
* 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_MAX 0x1F
|
||||||
#define EVDEV_FLAG_CNT (EVDEV_FLAG_MAX + 1)
|
#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_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;
|
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)
|
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)] =
|
evdev->ev_mt->ev_mt_slots[slot].ev_mt_states[ABS_MT_INDEX(code)] =
|
||||||
value;
|
value;
|
||||||
}
|
}
|
||||||
@ -275,3 +272,21 @@ evdev_push_mt_compat(struct evdev_dev *evdev)
|
|||||||
if (evdev->ev_lock_type == EV_LOCK_INTERNAL)
|
if (evdev->ev_lock_type == EV_LOCK_INTERNAL)
|
||||||
EVDEV_UNLOCK(evdev);
|
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);
|
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_set_mt_value(struct evdev_dev *, int32_t, int16_t, int32_t);
|
||||||
void evdev_send_mt_compat(struct evdev_dev *);
|
void evdev_send_mt_compat(struct evdev_dev *);
|
||||||
|
void evdev_send_mt_autorel(struct evdev_dev *);
|
||||||
|
|
||||||
/* Utility functions: */
|
/* Utility functions: */
|
||||||
void evdev_client_dumpqueue(struct evdev_client *);
|
void evdev_client_dumpqueue(struct evdev_client *);
|
||||||
|
Loading…
Reference in New Issue
Block a user