summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbru <bru@cvs.openbsd.org>2015-09-05 13:52:55 +0000
committerbru <bru@cvs.openbsd.org>2015-09-05 13:52:55 +0000
commitd66d36ac7d36baca5baa8922a68c5bd53bf3efe1 (patch)
treef3e3917018f80151b4d4774264297295251ff14f
parent5f21e2b5b73e5d1945fb5f7f711a569bf6601015 (diff)
Improve tap-and-drag detection for ALPS touchpads.
The ALPS mechanism for gesture detection can produce long delays between a packet that signals a tap and the next packet, which either signals the end of the gesture or the start of a drag-operation. The time spans can exceed the timeouts used by the generic detection mechanism in the synaptics driver. Reporting both the touch and the release event when the second packet has arrived ensures that the tap will be recognized. ok mpi@ shadchin@
-rw-r--r--sys/dev/pckbc/pms.c60
-rw-r--r--sys/dev/pckbc/pmsreg.h6
2 files changed, 43 insertions, 23 deletions
diff --git a/sys/dev/pckbc/pms.c b/sys/dev/pckbc/pms.c
index c0e95c6bfc9..147a130c49c 100644
--- a/sys/dev/pckbc/pms.c
+++ b/sys/dev/pckbc/pms.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pms.c,v 1.65 2015/08/23 04:45:23 deraadt Exp $ */
+/* $OpenBSD: pms.c,v 1.66 2015/09/05 13:52:54 bru Exp $ */
/* $NetBSD: psm.c,v 1.11 2000/06/05 22:20:57 sommerfeld Exp $ */
/*-
@@ -120,7 +120,8 @@ struct alps_softc {
int min_x, min_y;
int max_x, max_y;
- int old_fin;
+
+ u_int gesture;
u_int sec_buttons; /* trackpoint */
@@ -1522,8 +1523,7 @@ pms_proc_alps(struct pms_softc *sc)
{
struct alps_softc *alps = sc->alps;
int x, y, z, w, dx, dy;
- u_int buttons;
- int fin, ges;
+ u_int buttons, gesture;
if ((alps->model & ALPS_DUALPOINT) && alps_sec_proc(sc))
return;
@@ -1558,28 +1558,44 @@ pms_proc_alps(struct pms_softc *sc)
y = ALPS_YMAX_BEZEL - y + ALPS_YMIN_BEZEL;
if (alps->wsmode == WSMOUSE_NATIVE) {
- ges = sc->packet[2] & 0x01;
- fin = sc->packet[2] & 0x02;
-
- /* Simulate click (tap) */
- if (ges && !fin)
- z = 35;
+ if (alps->gesture == ALPS_TAP) {
+ /* Report a touch with the tap coordinates. */
+ wsmouse_input(sc->sc_wsmousedev, buttons,
+ alps->old_x, alps->old_y, ALPS_PRESSURE, 4,
+ WSMOUSE_INPUT_ABSOLUTE_X
+ | WSMOUSE_INPUT_ABSOLUTE_Y
+ | WSMOUSE_INPUT_ABSOLUTE_Z
+ | WSMOUSE_INPUT_ABSOLUTE_W);
+ if (z > 0) {
+ /*
+ * The hardware doesn't send a null pressure
+ * event when dragging starts.
+ */
+ wsmouse_input(sc->sc_wsmousedev, buttons,
+ alps->old_x, alps->old_y, 0, 0,
+ WSMOUSE_INPUT_ABSOLUTE_X
+ | WSMOUSE_INPUT_ABSOLUTE_Y
+ | WSMOUSE_INPUT_ABSOLUTE_Z
+ | WSMOUSE_INPUT_ABSOLUTE_W);
+ }
+ }
- /* Generate a null pressure event (needed for tap & drag) */
- if (ges && fin && !alps->old_fin)
- z = 0;
+ gesture = sc->packet[2] & 0x03;
+ if (gesture != ALPS_TAP) {
+ w = z ? 4 : 0;
+ wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
+ WSMOUSE_INPUT_ABSOLUTE_X
+ | WSMOUSE_INPUT_ABSOLUTE_Y
+ | WSMOUSE_INPUT_ABSOLUTE_Z
+ | WSMOUSE_INPUT_ABSOLUTE_W);
+ }
- /* Generate a width value corresponding to one finger */
- if (z > 0)
- w = 4;
- else
- w = 0;
+ if (alps->gesture != ALPS_DRAG || gesture != ALPS_TAP)
+ alps->gesture = gesture;
- wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w,
- WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y |
- WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W);
+ alps->old_x = x;
+ alps->old_y = y;
- alps->old_fin = fin;
} else {
dx = dy = 0;
if (z > ALPS_PRESSURE) {
diff --git a/sys/dev/pckbc/pmsreg.h b/sys/dev/pckbc/pmsreg.h
index cf81d355671..684ece8c800 100644
--- a/sys/dev/pckbc/pmsreg.h
+++ b/sys/dev/pckbc/pmsreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmsreg.h,v 1.11 2015/03/26 01:30:22 jsg Exp $ */
+/* $OpenBSD: pmsreg.h,v 1.12 2015/09/05 13:52:54 bru Exp $ */
/* $NetBSD: psmreg.h,v 1.1 1998/03/22 15:41:28 drochner Exp $ */
#ifndef SYS_DEV_PCKBC_PMSREG_H
@@ -164,6 +164,10 @@
#define ALPS_Z_MAGIC 127
+/* ALPS "gesture" and "finger" bits */
+#define ALPS_TAP 0x01
+#define ALPS_DRAG 0x03
+
/* Elantech queries */
#define ELANTECH_QUE_FW_ID 0
#define ELANTECH_QUE_FW_VER 1