summaryrefslogtreecommitdiffstats
path: root/sys/dev/evdev/evdev_mt.c
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2016-10-22 16:38:39 +0000
committergonzo <gonzo@FreeBSD.org>2016-10-22 16:38:39 +0000
commit32ea5f778d1dc67ab08967d62ad31b12e70b7095 (patch)
tree62fe2fd620968748a2d93b9bf101cb13a040fcd2 /sys/dev/evdev/evdev_mt.c
parent797c95b142be87731cfeb6bb6f2268e2218742cf (diff)
downloadFreeBSD-src-32ea5f778d1dc67ab08967d62ad31b12e70b7095.zip
FreeBSD-src-32ea5f778d1dc67ab08967d62ad31b12e70b7095.tar.gz
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>
Diffstat (limited to 'sys/dev/evdev/evdev_mt.c')
-rw-r--r--sys/dev/evdev/evdev_mt.c39
1 files changed, 31 insertions, 8 deletions
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);
+ }
+ }
}
OpenPOWER on IntegriCloud