From 32ea5f778d1dc67ab08967d62ad31b12e70b7095 Mon Sep 17 00:00:00 2001
From: gonzo <gonzo@FreeBSD.org>
Date: Sat, 22 Oct 2016 16:38:39 +0000
Subject: MFC r306647, r306855, r306857

r306647:
const-ify struct evdev_methods

Submitted by:	Vladimir Kondratiev <wulf@cicgroup.ru>
Suggested by:	hselasky

r306855:
Allow using of driver's mutex instead internal one for evdev locking.

Add new API call: evdev_register_mtx which takes lock argument that
should be used instead of internal one for evdev locking. Useful for
cases if evdev_push_event() is always called with driver's lock taken
and reduces amount of lock aquisitions. This allows to avoid LOR
between ev_open/ev_close invocations and evdev_push_event() Such LOR
can happen when ev_open/ev_close methods acquire driver lock and
evdev_push_event() is called with this lock taken.

Submitted by:	Vladimir Kondratiev <wulf@cicgroup.ru>

r306857:
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>
---
 sys/dev/evdev/evdev_mt.c | 39 +++++++++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 8 deletions(-)

(limited to 'sys/dev/evdev/evdev_mt.c')

diff --git a/sys/dev/evdev/evdev_mt.c b/sys/dev/evdev/evdev_mt.c
index 1ff332c..82f36d8 100644
--- a/sys/dev/evdev/evdev_mt.c
+++ b/sys/dev/evdev/evdev_mt.c
@@ -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;
 }
@@ -227,9 +224,13 @@ void
 evdev_push_nfingers(struct evdev_dev *evdev, int32_t nfingers)
 {
 
-	EVDEV_LOCK(evdev);
+	if (evdev->ev_lock_type == EV_LOCK_INTERNAL)
+		EVDEV_LOCK(evdev);
+	else
+		EVDEV_LOCK_ASSERT(evdev);
 	evdev_send_nfingers(evdev, nfingers);
-	EVDEV_UNLOCK(evdev);
+	if (evdev->ev_lock_type == EV_LOCK_INTERNAL)
+		EVDEV_UNLOCK(evdev);
 }
 
 void
@@ -263,7 +264,29 @@ void
 evdev_push_mt_compat(struct evdev_dev *evdev)
 {
 
-	EVDEV_LOCK(evdev);
+	if (evdev->ev_lock_type == EV_LOCK_INTERNAL)
+		EVDEV_LOCK(evdev);
+	else
+		EVDEV_LOCK_ASSERT(evdev);
 	evdev_send_mt_compat(evdev);
-	EVDEV_UNLOCK(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);
+		}
+	}
 }
-- 
cgit v1.1