Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add basic support for tap detection, emulating a left-click.
details: https://anonhg.NetBSD.org/src/rev/03813010da6d
branches: trunk
changeset: 339195:03813010da6d
user: bouyer <bouyer%NetBSD.org@localhost>
date: Fri Jul 03 14:18:18 2015 +0000
description:
Add basic support for tap detection, emulating a left-click.
diffstat:
share/man/man4/btmagic.4 | 9 ++-
sys/dev/bluetooth/btmagic.c | 112 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 115 insertions(+), 6 deletions(-)
diffs (242 lines):
diff -r 6ce2848dcb73 -r 03813010da6d share/man/man4/btmagic.4
--- a/share/man/man4/btmagic.4 Fri Jul 03 13:17:20 2015 +0000
+++ b/share/man/man4/btmagic.4 Fri Jul 03 14:18:18 2015 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: btmagic.4,v 1.4 2015/04/06 21:10:31 wiz Exp $
+.\" $NetBSD: btmagic.4,v 1.5 2015/07/03 14:18:18 bouyer Exp $
.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd April 6, 2015
+.Dd July 4, 2015
.Dt BTMAGIC 4
.Os
.Sh NAME
@@ -76,7 +76,10 @@
.Nm
driver emulates 3 buttons by splitting the area at the bottom of the
device in 3 equal zones and detects finger presence in one of these zones
-when the button is pressed.
+when the button is pressed. In addition, a tap in any area of the trackpad is interpreted as a left click. The timeout for tap detection defaults to 100ms
+and is adjustable with
+.Xr sysctl 8 .
+.Pp
Pointer movement is reported for single-touch
movements over the device, and scroll is reported for multi-touch movements.
.Pp
diff -r 6ce2848dcb73 -r 03813010da6d sys/dev/bluetooth/btmagic.c
--- a/sys/dev/bluetooth/btmagic.c Fri Jul 03 13:17:20 2015 +0000
+++ b/sys/dev/bluetooth/btmagic.c Fri Jul 03 14:18:18 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: btmagic.c,v 1.13 2015/04/16 19:53:19 christos Exp $ */
+/* $NetBSD: btmagic.c,v 1.14 2015/07/03 14:18:18 bouyer Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -85,7 +85,7 @@
*****************************************************************************/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.13 2015/04/16 19:53:19 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.14 2015/07/03 14:18:18 bouyer Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -171,6 +171,11 @@
/* previous mouse buttons */
int sc_mb_id; /* which ID selects the button */
uint32_t sc_mb;
+ /* button emulation with tap */
+ int sc_tapmb_id; /* which ID selects the button */
+ struct timeval sc_taptime;
+ int sc_taptimeout;
+ callout_t sc_tapcallout;
};
/* sc_flags */
@@ -191,6 +196,8 @@
static int btmagic_connect(struct btmagic_softc *);
static int btmagic_sysctl_resolution(SYSCTLFN_PROTO);
static int btmagic_sysctl_scale(SYSCTLFN_PROTO);
+static int btmagic_tap(struct btmagic_softc *, int);
+static int btmagic_sysctl_taptimeout(SYSCTLFN_PROTO);
CFATTACH_DECL_NEW(btmagic, sizeof(struct btmagic_softc),
btmagic_match, btmagic_attach, btmagic_detach, NULL);
@@ -220,6 +227,7 @@
static void btmagic_input_basic(struct btmagic_softc *, uint8_t *, size_t);
static void btmagic_input_magicm(struct btmagic_softc *, uint8_t *, size_t);
static void btmagic_input_magict(struct btmagic_softc *, uint8_t *, size_t);
+static void btmagic_tapcallout(void *);
/* report types (data[1]) */
#define BASIC_REPORT_ID 0x10
@@ -291,8 +299,12 @@
*/
sc->sc_dev = self;
sc->sc_state = BTMAGIC_CLOSED;
+ sc->sc_mb_id = -1;
+ sc->sc_tapmb_id = -1;
callout_init(&sc->sc_timeout, 0);
callout_setfunc(&sc->sc_timeout, btmagic_timeout, sc);
+ callout_init(&sc->sc_tapcallout, 0);
+ callout_setfunc(&sc->sc_tapcallout, btmagic_tapcallout, sc);
sockopt_init(&sc->sc_mode, BTPROTO_L2CAP, SO_L2CAP_LM, 0);
/*
@@ -332,6 +344,7 @@
sc->sc_firm = 6;
sc->sc_dist = 130;
sc->sc_scale = 20;
+ sc->sc_taptimeout = 100;
sysctl_createv(&sc->sc_log, 0, NULL, &node,
0,
@@ -378,6 +391,14 @@
(void *)sc, 0,
CTL_HW, node->sysctl_num,
CTL_CREATE, CTL_EOL);
+ sysctl_createv(&sc->sc_log, 0, NULL, NULL,
+ CTLFLAG_READWRITE,
+ CTLTYPE_INT, "taptimeout",
+ "timeout for tap detection in milliseconds",
+ btmagic_sysctl_taptimeout, 0,
+ (void *)sc, 0,
+ CTL_HW, node->sysctl_num,
+ CTL_CREATE, CTL_EOL);
}
/*
@@ -437,6 +458,8 @@
sc->sc_ctl = NULL;
}
+ callout_halt(&sc->sc_tapcallout, bt_lock);
+ callout_destroy(&sc->sc_tapcallout);
callout_halt(&sc->sc_timeout, bt_lock);
callout_destroy(&sc->sc_timeout);
@@ -617,6 +640,31 @@
return 0;
}
+/* validate tap timeout */
+static int
+btmagic_sysctl_taptimeout(SYSCTLFN_ARGS)
+{
+ struct sysctlnode node;
+ struct btmagic_softc *sc;
+ int t, error;
+
+ node = *rnode;
+ sc = node.sysctl_data;
+
+ t = sc->sc_taptimeout;
+ node.sysctl_data = &t;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
+
+ if (t < max(1000 / hz, 1) || t > 999)
+ return EINVAL;
+
+ sc->sc_taptimeout = t;
+ DPRINTF(sc, "taptimeout = %u", t);
+ return 0;
+}
+
/*****************************************************************************
*
* wsmouse(4) accessops
@@ -1530,6 +1578,14 @@
ty = ay - sc->sc_ay[id];
if (ISSET(sc->sc_smask, __BIT(id))) {
+ struct timeval now_tv;
+ getmicrotime(&now_tv);
+ if (sc->sc_nfingers == 1 && mb == 0 &&
+ timercmp(&sc->sc_taptime, &now_tv, >)) {
+ /* still detecting a tap */
+ continue;
+ }
+
if (sc->sc_nfingers == 1 || mb != 0) {
/* single finger moving */
dx += btmagic_scale(tx, &sc->sc_rx,
@@ -1548,10 +1604,22 @@
sc->sc_ry = 0;
sc->sc_rz = 0;
sc->sc_rw = 0;
-
KASSERT(!ISSET(sc->sc_smask, __BIT(id)));
SET(sc->sc_smask, __BIT(id));
sc->sc_nfingers++;
+ if (sc->sc_tapmb_id == -1 &&
+ mb == 0 && sc->sc_mb == 0) {
+ sc->sc_tapmb_id = id;
+ getmicrotime(&sc->sc_taptime);
+ sc->sc_taptime.tv_usec +=
+ sc->sc_taptimeout * 1000;
+ if (sc->sc_taptime.tv_usec > 1000000) {
+ sc->sc_taptime.tv_usec -=
+ 1000000;
+ sc->sc_taptime.tv_sec++;
+ }
+ }
+
}
break;
@@ -1560,6 +1628,9 @@
CLR(sc->sc_smask, __BIT(id));
sc->sc_nfingers--;
KASSERT(sc->sc_nfingers >= 0);
+ if (id == sc->sc_tapmb_id) {
+ mb = btmagic_tap(sc, id);
+ }
}
break;
}
@@ -1580,3 +1651,38 @@
splx(s);
}
}
+
+static int
+btmagic_tap(struct btmagic_softc *sc, int id)
+{
+ struct timeval now_tv;
+
+ sc->sc_tapmb_id = -1;
+ getmicrotime(&now_tv);
+ if (timercmp(&sc->sc_taptime, &now_tv, >)) {
+ /* got a tap */
+ callout_schedule(
+ &sc->sc_tapcallout,
+ mstohz(sc->sc_taptimeout));
+ return __BIT(0);
+ }
+ return 0;
+}
+
+static void
+btmagic_tapcallout(void *arg)
+{
+ struct btmagic_softc *sc = arg;
+ int s;
+
+ mutex_enter(bt_lock);
+ callout_ack(&sc->sc_tapcallout);
+ if ((sc->sc_mb & __BIT(0)) != 0) {
+ sc->sc_mb &= ~__BIT(0);
+ s = spltty();
+ wsmouse_input(sc->sc_wsmouse, sc->sc_mb,
+ 0, 0, 0, 0, WSMOUSE_INPUT_DELTA);
+ splx(s);
+ }
+ mutex_exit(bt_lock);
+}
Home |
Main Index |
Thread Index |
Old Index