Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pckbport Add double finger scroll feature. If the d...
details: https://anonhg.NetBSD.org/src/rev/d8e2a1887dbc
branches: trunk
changeset: 445620:d8e2a1887dbc
user: blymn <blymn%NetBSD.org@localhost>
date: Tue Nov 06 09:13:17 2018 +0000
description:
Add double finger scroll feature. If the detected width is between a
defined range then report y movement as z-axis. Effectively emulating
a mouse scroll wheel.
diffstat:
sys/dev/pckbport/synaptics.c | 150 ++++++++++++++++++++++++++++++++++-----
sys/dev/pckbport/synapticsvar.h | 14 ++-
2 files changed, 139 insertions(+), 25 deletions(-)
diffs (truncated from 323 to 300 lines):
diff -r 5eb0fdae4a8c -r d8e2a1887dbc sys/dev/pckbport/synaptics.c
--- a/sys/dev/pckbport/synaptics.c Tue Nov 06 08:55:02 2018 +0000
+++ b/sys/dev/pckbport/synaptics.c Tue Nov 06 09:13:17 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: synaptics.c,v 1.43 2018/11/06 08:55:02 blymn Exp $ */
+/* $NetBSD: synaptics.c,v 1.44 2018/11/06 09:13:17 blymn Exp $ */
/*
* Copyright (c) 2005, Steve C. Woodford
@@ -48,7 +48,7 @@
#include "opt_pms.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.43 2018/11/06 08:55:02 blymn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: synaptics.c,v 1.44 2018/11/06 09:13:17 blymn Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -115,9 +115,14 @@
static int synaptics_two_fingers_emul = 0;
static int synaptics_scale_x = 16;
static int synaptics_scale_y = 16;
+static int synaptics_scale_z = 1;
static int synaptics_max_speed_x = 32;
static int synaptics_max_speed_y = 32;
+static int synaptics_max_speed_z = 2;
static int synaptics_movement_threshold = 4;
+static int synaptics_fscroll_min = 5;
+static int synaptics_fscroll_max = 12;
+static int synaptics_dz_hold = 30;
static int synaptics_movement_enable = 1;
/* Sysctl nodes. */
@@ -138,9 +143,14 @@
static int synaptics_two_fingers_emul_nodenum;
static int synaptics_scale_x_nodenum;
static int synaptics_scale_y_nodenum;
+static int synaptics_scale_z_nodenum;
static int synaptics_max_speed_x_nodenum;
static int synaptics_max_speed_y_nodenum;
+static int synaptics_max_speed_z_nodenum;
static int synaptics_movement_threshold_nodenum;
+static int synaptics_finger_scroll_min_nodenum;
+static int synaptics_finger_scroll_max_nodenum;
+static int synaptics_dz_hold_nodenum;
static int synaptics_movement_enable_nodenum;
static int
@@ -424,7 +434,7 @@
struct pms_softc *psc = vsc;
struct synaptics_softc *sc = &psc->u.synaptics;
u_char enable_modes;
- int res;
+ int res, i;
if (sc->flags & SYN_FLAG_HAS_PASSTHROUGH) {
/*
@@ -452,7 +462,7 @@
*/
synaptics_poll_cmd(psc, PMS_DEV_DISABLE, 0);
/* a couple of set scales to clear out pending commands */
- for (int i = 0; i < 2; i++)
+ for (i = 0; i < 2; i++)
synaptics_poll_cmd(psc, PMS_SET_SCALE11, 0);
res = synaptics_special_write(psc, SYNAPTICS_CMD_SET_MODE2, enable_modes);
@@ -460,7 +470,7 @@
aprint_error("synaptics: set mode error\n");
/* a couple of set scales to clear out pending commands */
- for (int i = 0; i < 2; i++)
+ for (i = 0; i < 2; i++)
synaptics_poll_cmd(psc, PMS_SET_SCALE11, 0);
/* Set advanced gesture mode */
@@ -476,10 +486,11 @@
sc->gesture_tap_packet = 0;
sc->gesture_type = 0;
sc->gesture_buttons = 0;
- sc->rem_x[0] = sc->rem_y[0] = 0;
- sc->rem_x[1] = sc->rem_y[1] = 0;
- sc->movement_history[0] = 0;
- sc->movement_history[1] = 0;
+ sc->dz_hold = 0;
+ for (i = 0; i < SYN_MAX_FINGERS; i++) {
+ sc->rem_x[i] = sc->rem_y[i] = sc->rem_z[i] = 0;
+ sc->movement_history[i] = 0;
+ }
sc->button_history = 0;
}
@@ -673,6 +684,18 @@
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "scale_z",
+ SYSCTL_DESCR("Sroll wheel emulation scale factor"),
+ pms_sysctl_synaptics_verify, 0,
+ &synaptics_scale_z,
+ 0, CTL_HW, root_num, CTL_CREATE,
+ CTL_EOL)) != 0)
+ goto err;
+
+ synaptics_scale_z_nodenum = node->sysctl_num;
+
+ if ((rc = sysctl_createv(clog, 0, NULL, &node,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
CTLTYPE_INT, "max_speed_x",
SYSCTL_DESCR("Horizontal movement maximum speed"),
pms_sysctl_synaptics_verify, 0,
@@ -697,6 +720,18 @@
if ((rc = sysctl_createv(clog, 0, NULL, &node,
CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "max_speed_z",
+ SYSCTL_DESCR("Scroll wheel emulation maximum speed"),
+ pms_sysctl_synaptics_verify, 0,
+ &synaptics_max_speed_z,
+ 0, CTL_HW, root_num, CTL_CREATE,
+ CTL_EOL)) != 0)
+ goto err;
+
+ synaptics_max_speed_z_nodenum = node->sysctl_num;
+
+ if ((rc = sysctl_createv(clog, 0, NULL, &node,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
CTLTYPE_INT, "movement_threshold",
SYSCTL_DESCR("Minimum reported movement threshold"),
pms_sysctl_synaptics_verify, 0,
@@ -754,6 +789,42 @@
goto err;
synaptics_button3_nodenum = node->sysctl_num;
+
+ if ((rc = sysctl_createv(clog, 0, NULL, &node,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "finger_scroll-min",
+ SYSCTL_DESCR("Minimum width for finger scrolling detection"),
+ pms_sysctl_synaptics_verify, 0,
+ &synaptics_fscroll_min,
+ 0, CTL_HW, root_num, CTL_CREATE,
+ CTL_EOL)) != 0)
+ goto err;
+
+ synaptics_finger_scroll_min_nodenum = node->sysctl_num;
+
+ if ((rc = sysctl_createv(clog, 0, NULL, &node,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "finger_scroll-max",
+ SYSCTL_DESCR("Maximum width for finger scrolling detection"),
+ pms_sysctl_synaptics_verify, 0,
+ &synaptics_fscroll_max,
+ 0, CTL_HW, root_num, CTL_CREATE,
+ CTL_EOL)) != 0)
+ goto err;
+
+ synaptics_finger_scroll_max_nodenum = node->sysctl_num;
+
+ if ((rc = sysctl_createv(clog, 0, NULL, &node,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "finger_scroll-hysteresis",
+ SYSCTL_DESCR("Number of packets to stay in finger scroll mode"),
+ pms_sysctl_synaptics_verify, 0,
+ &synaptics_dz_hold,
+ 0, CTL_HW, root_num, CTL_CREATE,
+ CTL_EOL)) != 0)
+ goto err;
+
+ synaptics_dz_hold_nodenum = node->sysctl_num;
return;
err:
@@ -825,6 +896,13 @@
if (t < SYNAPTICS_EDGE_LEFT || t > SYNAPTICS_EDGE_RIGHT)
return (EINVAL);
} else
+ if (node.sysctl_num == synaptics_finger_scroll_min_nodenum ||
+ node.sysctl_num == synaptics_finger_scroll_max_nodenum) {
+ /* make sure we avoid the "magic" widths, 4 and below
+ are for fingers, 15 is palm detect. */
+ if ((t < 5) || (t > 14))
+ return (EINVAL);
+ } else
if (node.sysctl_num == synaptics_movement_enable_nodenum) {
if (t < 0 || t > 1)
return (EINVAL);
@@ -1446,17 +1524,27 @@
static inline void
synaptics_movement(struct synaptics_softc *sc, struct synaptics_packet *sp,
- int finger, int *dxp, int *dyp)
+ int finger, int scroll_emul, int *dxp, int *dyp, int *dzp)
{
- int dx, dy, edge;
+ int dx, dy, dz, edge;
+
+ dx = dy = dz = 0;
/*
- * Compute the next values of dx and dy
+ * Compute the next values of dx and dy and dz. If scroll_emul
+ * is non-zero, take the dy and used it as use it as dz so we
+ * can emulate a scroll wheel.
*/
- dx = synaptics_filter_policy(sc, finger, sc->history_x[finger],
- sp->sp_x);
- dy = synaptics_filter_policy(sc, finger, sc->history_y[finger],
- sp->sp_y);
+ if (scroll_emul == 0) {
+ dx = synaptics_filter_policy(sc, finger, sc->history_x[finger],
+ sp->sp_x);
+ dy = synaptics_filter_policy(sc, finger, sc->history_y[finger],
+ sp->sp_y);
+ } else {
+ dz = synaptics_filter_policy(sc, finger, sc->history_z[finger],
+ sp->sp_y);
+ dx = dy = 0;
+ }
/*
* If we're dealing with a drag gesture, and the finger moves to
@@ -1477,10 +1565,11 @@
}
/*
- * Apply scaling to both deltas
+ * Apply scaling to the deltas
*/
dx = synaptics_scale(dx, synaptics_scale_x, &sc->rem_x[finger]);
dy = synaptics_scale(dy, synaptics_scale_y, &sc->rem_y[finger]);
+ dz = synaptics_scale(dz, synaptics_scale_z, &sc->rem_z[finger]);
/*
* Clamp deltas to specified maximums.
@@ -1489,9 +1578,12 @@
dx = ((dx >= 0)? 1 : -1) * synaptics_max_speed_x;
if (abs(dy) > synaptics_max_speed_y)
dy = ((dy >= 0)? 1 : -1) * synaptics_max_speed_y;
+ if (abs(dz) > synaptics_max_speed_z)
+ dz = ((dz >= 0)? 1 : -1) * synaptics_max_speed_z;
*dxp = dx;
*dyp = dy;
+ *dzp = dz;
sc->movement_history[finger]++;
}
@@ -1502,7 +1594,7 @@
struct synaptics_softc *sc = &psc->u.synaptics;
int dx, dy, dz;
int fingers, palm, buttons, changed;
- int s;
+ int s, z_emul;
/*
* Do Z-axis emulation using up/down buttons if required.
@@ -1571,7 +1663,20 @@
*/
if (palm == 0 && synaptics_movement_enable) {
if (fingers == 1) {
- synaptics_movement(sc, sp, sp->sp_finger, &dx, &dy);
+ z_emul = 0;
+
+ if ((sp->sp_w >= synaptics_fscroll_min) &&
+ (sp->sp_w <= synaptics_fscroll_max)) {
+ z_emul = 1;
+ sc->dz_hold = synaptics_dz_hold;
+ }
+
+ if (sc->dz_hold > 0) {
+ z_emul = 1;
+ }
+
+ synaptics_movement(sc, sp, sp->sp_finger,
+ z_emul, &dx, &dy, &dz);
} else {
/*
* No valid finger. Therefore no movement.
@@ -1585,10 +1690,13 @@
* No valid finger. Therefore no movement.
*/
sc->movement_history[0] = 0;
- sc->rem_x[0] = sc->rem_y[0] = 0;
- dx = dy = 0;
+ sc->rem_x[0] = sc->rem_y[0] = sc->rem_z[0] = 0;
+ dx = dy = dz = 0;
}
+ if (sc->dz_hold > 0)
+ sc->dz_hold--;
+
/*
* Pass the final results up to wsmouse_input() if necessary.
*/
diff -r 5eb0fdae4a8c -r d8e2a1887dbc sys/dev/pckbport/synapticsvar.h
--- a/sys/dev/pckbport/synapticsvar.h Tue Nov 06 08:55:02 2018 +0000
+++ b/sys/dev/pckbport/synapticsvar.h Tue Nov 06 09:13:17 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: synapticsvar.h,v 1.7 2017/11/06 21:07:17 blymn Exp $ */
+/* $NetBSD: synapticsvar.h,v 1.8 2018/11/06 09:13:17 blymn Exp $ */
Home |
Main Index |
Thread Index |
Old Index