aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/usb/input
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/input')
-rw-r--r--sys/dev/usb/input/atp.c1
-rw-r--r--sys/dev/usb/input/uhid.c5
-rw-r--r--sys/dev/usb/input/ukbd.c73
-rw-r--r--sys/dev/usb/input/ums.c6
-rw-r--r--sys/dev/usb/input/usbhid.c16
-rw-r--r--sys/dev/usb/input/wmt.c1
-rw-r--r--sys/dev/usb/input/wsp.c234
7 files changed, 240 insertions, 96 deletions
diff --git a/sys/dev/usb/input/atp.c b/sys/dev/usb/input/atp.c
index fa78f7d7221b..41ab37c6f1cc 100644
--- a/sys/dev/usb/input/atp.c
+++ b/sys/dev/usb/input/atp.c
@@ -58,7 +58,6 @@
* giving me an opportunity to do this work.
*/
-#include <sys/cdefs.h>
#include <sys/stdint.h>
#include <sys/stddef.h>
#include <sys/param.h>
diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c
index 863e04f4e52b..a31081663f0c 100644
--- a/sys/dev/usb/input/uhid.c
+++ b/sys/dev/usb/input/uhid.c
@@ -4,7 +4,6 @@
* $NetBSD: uhid.c,v 1.54 2002/09/23 05:51:21 simonb Exp $
*/
-#include <sys/cdefs.h>
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
@@ -633,11 +632,13 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr,
default:
return (EINVAL);
}
+ size = imin(ugd->ugd_maxlen, size);
if (id != 0)
error = copyin(ugd->ugd_data, &id, 1);
if (error == 0)
error = uhid_get_report(sc, ugd->ugd_report_type, id,
- NULL, ugd->ugd_data, imin(ugd->ugd_maxlen, size));
+ NULL, ugd->ugd_data, size);
+ ugd->ugd_actlen = size;
break;
case USB_SET_REPORT:
diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c
index f33ae6e8a620..57e9beac34b6 100644
--- a/sys/dev/usb/input/ukbd.c
+++ b/sys/dev/usb/input/ukbd.c
@@ -1,4 +1,3 @@
-#include <sys/cdefs.h>
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
@@ -72,6 +71,8 @@
#include <dev/usb/quirk/usb_quirk.h>
+#include "usbdevs.h"
+
#ifdef EVDEV_SUPPORT
#include <dev/evdev/input.h>
#include <dev/evdev/evdev.h>
@@ -173,13 +174,19 @@ struct ukbd_softc {
#define UKBD_FLAG_ATTACHED 0x00000010
#define UKBD_FLAG_GONE 0x00000020
-#define UKBD_FLAG_HID_MASK 0x003fffc0
-#define UKBD_FLAG_APPLE_EJECT 0x00000040
-#define UKBD_FLAG_APPLE_FN 0x00000080
-#define UKBD_FLAG_APPLE_SWAP 0x00000100
+/* set in ukbd_attach */
+#define UKBD_FLAG_APPLE_SWAP 0x00000040
+/* set in ukbd_parse_hid */
+#define UKBD_FLAG_APPLE_EJECT 0x00000080
+#define UKBD_FLAG_APPLE_FN 0x00000100
#define UKBD_FLAG_NUMLOCK 0x00080000
#define UKBD_FLAG_CAPSLOCK 0x00100000
#define UKBD_FLAG_SCROLLLOCK 0x00200000
+#define UKBD_FLAG_HID_MASK UKBD_FLAG_APPLE_EJECT | \
+ UKBD_FLAG_APPLE_FN | \
+ UKBD_FLAG_NUMLOCK | \
+ UKBD_FLAG_CAPSLOCK | \
+ UKBD_FLAG_SCROLLLOCK
int sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
int sc_state; /* shift/lock key state */
@@ -296,6 +303,48 @@ static const uint8_t ukbd_boot_desc[] = {
0xff, 0x00, 0x81, 0x00, 0xc0
};
+static const STRUCT_USB_HOST_ID ukbd_apple_iso_models[] = {
+ /* PowerBooks Feb 2005, iBooks G4 */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_FOUNTAIN_ISO) },
+ /* PowerBooks Oct 2005 */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER_ISO) },
+ /* Core Duo MacBook & MacBook Pro */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER3_ISO) },
+ /* Core2 Duo MacBook & MacBook Pro */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER4_ISO) },
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_GEYSER4_HF_ISO) },
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ALU_MINI_ISO) },
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ALU_ISO) },
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_ALU_REVB_ISO) },
+ /* MacbookAir, aka wellspring */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING_ISO) },
+ /* MacbookProPenryn, aka wellspring2 */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING2_ISO) },
+ /* Macbook5,1 (unibody), aka wellspring3 */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING3_ISO) },
+ /* MacbookAir3,2 (unibody), aka wellspring4 */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4_ISO) },
+ /* MacbookAir3,1 (unibody), aka wellspring4 */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING4A_ISO) },
+ /* Macbook8 (unibody, March 2011) */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5_ISO) },
+ /* Macbook8,2 (unibody) */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING5A_ISO) },
+ /* MacbookAir4,2 (unibody, July 2011) */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6_ISO) },
+ /* MacbookAir4,1 (unibody, July 2011) */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING6A_ISO) },
+ /* MacbookPro10,1 (unibody, June 2012) */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7_ISO) },
+ /* MacbookPro10,2 (unibody, October 2012) */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING7A_ISO) },
+ /* MacbookAir6,2 (unibody, June 2013) */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING8_ISO) },
+ /* MacbookPro12,1 */
+ { USB_VP(USB_VENDOR_APPLE, USB_PRODUCT_APPLE_WELLSPRING9_ISO) },
+};
+
+
/* prototypes */
static void ukbd_timeout(void *);
static void ukbd_set_leds(struct ukbd_softc *, uint8_t);
@@ -1001,8 +1050,7 @@ ukbd_parse_hid(struct ukbd_softc *sc, const uint8_t *ptr, uint32_t len)
hid_input, 0, &sc->sc_loc_apple_eject, &flags,
&sc->sc_id_apple_eject)) {
if (flags & HIO_VARIABLE)
- sc->sc_flags |= UKBD_FLAG_APPLE_EJECT |
- UKBD_FLAG_APPLE_SWAP;
+ sc->sc_flags |= UKBD_FLAG_APPLE_EJECT;
DPRINTFN(1, "Found Apple eject-key\n");
}
if (hid_locate(ptr, len,
@@ -1138,6 +1186,17 @@ ukbd_attach(device_t dev)
sc->sc_fkeymap[n] = fkey_tab[n];
}
+ /* check if this is an Apple keyboard with swapped key codes
+ * apparently, these are the ISO layout models
+ */
+ DPRINTF("uaa vendor: 0x%04x, uaa product 0x%04x\n", uaa->info.idVendor, uaa->info.idProduct );
+ if (usbd_lookup_id_by_uaa(ukbd_apple_iso_models, sizeof(ukbd_apple_iso_models), uaa) == 0) {
+ sc->sc_flags |= UKBD_FLAG_APPLE_SWAP;
+ DPRINTF("UKBD_FLAG_APPLE_SWAP set\n");
+ } else {
+ DPRINTF("UKBD_FLAG_APPLE_SWAP not set\n");
+ }
+
kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap,
sc->sc_fkeymap, UKBD_NFKEY);
diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
index 8416be656f81..523ec4d05db9 100644
--- a/sys/dev/usb/input/ums.c
+++ b/sys/dev/usb/input/ums.c
@@ -30,7 +30,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
/*
* HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
*/
@@ -320,11 +319,12 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
if (++info != &sc->sc_info[UMS_INFO_MAX])
goto repeat;
+ /* keep old button value(s) for non-detected buttons */
+ buttons |= sc->sc_status.button & ~buttons_found;
+
#ifdef EVDEV_SUPPORT
buttons_reported = buttons;
#endif
- /* keep old button value(s) for non-detected buttons */
- buttons |= sc->sc_status.button & ~buttons_found;
if (dx || dy || dz || dt || dw ||
(buttons != sc->sc_status.button)) {
diff --git a/sys/dev/usb/input/usbhid.c b/sys/dev/usb/input/usbhid.c
index 0832d657e521..3bb7d5e594e3 100644
--- a/sys/dev/usb/input/usbhid.c
+++ b/sys/dev/usb/input/usbhid.c
@@ -30,7 +30,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
/*
* HID spec: https://www.usb.org/sites/default/files/documents/hid1_11.pdf
*/
@@ -834,7 +833,7 @@ usbhid_attach(device_t dev)
mtx_init(&sc->sc_mtx, "usbhid lock", NULL, MTX_DEF);
- child = device_add_child(dev, "hidbus", -1);
+ child = device_add_child(dev, "hidbus", DEVICE_UNIT_ANY);
if (child == NULL) {
device_printf(dev, "Could not add hidbus device\n");
usbhid_detach(dev);
@@ -842,12 +841,7 @@ usbhid_attach(device_t dev)
}
device_set_ivars(child, &sc->sc_hw);
- error = bus_generic_attach(dev);
- if (error) {
- device_printf(dev, "failed to attach child: %d\n", error);
- usbhid_detach(dev);
- return (error);
- }
+ bus_attach_children(dev);
return (0); /* success */
}
@@ -856,8 +850,12 @@ static int
usbhid_detach(device_t dev)
{
struct usbhid_softc *sc = device_get_softc(dev);
+ int error;
+
+ error = bus_generic_detach(dev);
+ if (error != 0)
+ return (error);
- device_delete_children(dev);
mtx_destroy(&sc->sc_mtx);
return (0);
diff --git a/sys/dev/usb/input/wmt.c b/sys/dev/usb/input/wmt.c
index 23692e77a0fa..03e4da35a9fe 100644
--- a/sys/dev/usb/input/wmt.c
+++ b/sys/dev/usb/input/wmt.c
@@ -24,7 +24,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
/*
* MS Windows 7/8/10 compatible USB HID Multi-touch Device driver.
* https://msdn.microsoft.com/en-us/library/windows/hardware/jj151569(v=vs.85).aspx
diff --git a/sys/dev/usb/input/wsp.c b/sys/dev/usb/input/wsp.c
index f1931c9e03c0..f78d64f69c08 100644
--- a/sys/dev/usb/input/wsp.c
+++ b/sys/dev/usb/input/wsp.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "opt_evdev.h"
#include <sys/param.h>
@@ -74,7 +73,7 @@
} while (0)
/* Tunables */
-static SYSCTL_NODE(_hw_usb, OID_AUTO, wsp, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+static SYSCTL_NODE(_hw_usb, OID_AUTO, wsp, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"USB wsp");
#ifdef USB_DEBUG
@@ -87,60 +86,101 @@ enum wsp_log_level {
static int wsp_debug = WSP_LLEVEL_ERROR;/* the default is to only log errors */
SYSCTL_INT(_hw_usb_wsp, OID_AUTO, debug, CTLFLAG_RWTUN,
- &wsp_debug, WSP_LLEVEL_ERROR, "WSP debug level");
+ &wsp_debug, WSP_LLEVEL_ERROR, "WSP debug level (0-3)");
#endif /* USB_DEBUG */
static struct wsp_tuning {
int scale_factor;
+ int scroll_finger_count;
+ int horizontal_swipe_finger_count;
int z_factor;
int z_invert;
+ int t_factor;
+ int t_invert;
int pressure_touch_threshold;
int pressure_untouch_threshold;
int pressure_tap_threshold;
- int scr_hor_threshold;
+ int scr_threshold;
+ int max_finger_diameter;
+ int max_scroll_finger_distance;
+ int max_double_tap_distance;
int enable_single_tap_clicks;
+ int enable_single_tap_movement;
}
wsp_tuning =
{
.scale_factor = 12,
+ .scroll_finger_count = 2,
+ .horizontal_swipe_finger_count = 3,
.z_factor = 5,
.z_invert = 0,
+ .t_factor = 0,
+ .t_invert = 0,
.pressure_touch_threshold = 50,
.pressure_untouch_threshold = 10,
.pressure_tap_threshold = 120,
- .scr_hor_threshold = 20,
+ .scr_threshold = 20,
+ .max_finger_diameter = 1900,
+ .max_scroll_finger_distance = 8192,
+ .max_double_tap_distance = 2500,
.enable_single_tap_clicks = 1,
+ .enable_single_tap_movement = 1,
};
static void
-wsp_runing_rangecheck(struct wsp_tuning *ptun)
+wsp_running_rangecheck(struct wsp_tuning *ptun)
{
WSP_CLAMP(ptun->scale_factor, 1, 63);
- WSP_CLAMP(ptun->z_factor, 1, 63);
+ WSP_CLAMP(ptun->scroll_finger_count, 0, 3);
+ WSP_CLAMP(ptun->horizontal_swipe_finger_count, 0, 3);
+ WSP_CLAMP(ptun->z_factor, 0, 63);
WSP_CLAMP(ptun->z_invert, 0, 1);
+ WSP_CLAMP(ptun->t_factor, 0, 63);
+ WSP_CLAMP(ptun->t_invert, 0, 1);
WSP_CLAMP(ptun->pressure_touch_threshold, 1, 255);
WSP_CLAMP(ptun->pressure_untouch_threshold, 1, 255);
WSP_CLAMP(ptun->pressure_tap_threshold, 1, 255);
- WSP_CLAMP(ptun->scr_hor_threshold, 1, 255);
+ WSP_CLAMP(ptun->max_finger_diameter, 1, 2400);
+ WSP_CLAMP(ptun->max_scroll_finger_distance, 1, 16384);
+ WSP_CLAMP(ptun->max_double_tap_distance, 1, 16384);
+ WSP_CLAMP(ptun->scr_threshold, 1, 255);
WSP_CLAMP(ptun->enable_single_tap_clicks, 0, 1);
+ WSP_CLAMP(ptun->enable_single_tap_movement, 0, 1);
}
SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scale_factor, CTLFLAG_RWTUN,
&wsp_tuning.scale_factor, 0, "movement scale factor");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scroll_finger_count, CTLFLAG_RWTUN,
+ &wsp_tuning.scroll_finger_count, 0, "amount of fingers to use scrolling gesture");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, horizontal_swipe_finger_count, CTLFLAG_RWTUN,
+ &wsp_tuning.horizontal_swipe_finger_count, 0, "amount of fingers to use horizontal swipe gesture");
SYSCTL_INT(_hw_usb_wsp, OID_AUTO, z_factor, CTLFLAG_RWTUN,
- &wsp_tuning.z_factor, 0, "Z-axis scale factor");
+ &wsp_tuning.z_factor, 0, "Z-axis (vertical) scale factor");
SYSCTL_INT(_hw_usb_wsp, OID_AUTO, z_invert, CTLFLAG_RWTUN,
- &wsp_tuning.z_invert, 0, "enable Z-axis inversion");
+ &wsp_tuning.z_invert, 0, "enable (vertical) Z-axis inversion");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, t_factor, CTLFLAG_RWTUN,
+ &wsp_tuning.t_factor, 0, "T-axis (horizontal) scale factor");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, t_invert, CTLFLAG_RWTUN,
+ &wsp_tuning.t_invert, 0, "enable T-axis (horizontal) inversion");
SYSCTL_INT(_hw_usb_wsp, OID_AUTO, pressure_touch_threshold, CTLFLAG_RWTUN,
&wsp_tuning.pressure_touch_threshold, 0, "touch pressure threshold");
SYSCTL_INT(_hw_usb_wsp, OID_AUTO, pressure_untouch_threshold, CTLFLAG_RWTUN,
&wsp_tuning.pressure_untouch_threshold, 0, "untouch pressure threshold");
SYSCTL_INT(_hw_usb_wsp, OID_AUTO, pressure_tap_threshold, CTLFLAG_RWTUN,
&wsp_tuning.pressure_tap_threshold, 0, "tap pressure threshold");
-SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scr_hor_threshold, CTLFLAG_RWTUN,
- &wsp_tuning.scr_hor_threshold, 0, "horizontal scrolling threshold");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, max_finger_diameter, CTLFLAG_RWTUN,
+ &wsp_tuning.max_finger_diameter, 0, "maximum finger diameter");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, max_scroll_finger_distance, CTLFLAG_RWTUN,
+ &wsp_tuning.max_scroll_finger_distance, 0, "maximum scroll finger distance");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, max_double_tap_distance, CTLFLAG_RWTUN,
+ &wsp_tuning.max_double_tap_distance, 0, "maximum double-finger click distance");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, scr_threshold, CTLFLAG_RWTUN,
+ &wsp_tuning.scr_threshold, 0, "scrolling threshold");
SYSCTL_INT(_hw_usb_wsp, OID_AUTO, enable_single_tap_clicks, CTLFLAG_RWTUN,
&wsp_tuning.enable_single_tap_clicks, 0, "enable single tap clicks");
+SYSCTL_INT(_hw_usb_wsp, OID_AUTO, enable_single_tap_movement, CTLFLAG_RWTUN,
+ &wsp_tuning.enable_single_tap_movement, 0, "enable single tap movement");
+
/*
* Some tables, structures, definitions and constant values for the
@@ -289,7 +329,7 @@ struct tp_finger {
int16_t unused[2]; /* zeros */
int16_t pressure; /* pressure on forcetouch touchpad */
int16_t multi; /* one finger: varies, more fingers:
- * constant */
+ * constant */
} __packed;
/* trackpad finger data size, empirically at least ten fingers */
@@ -567,13 +607,13 @@ struct wsp_softc {
struct tp_finger *index[MAX_FINGERS]; /* finger index data */
int16_t pos_x[MAX_FINGERS]; /* position array */
int16_t pos_y[MAX_FINGERS]; /* position array */
+ int16_t pre_pos_x[MAX_FINGERS]; /* previous position array */
+ int16_t pre_pos_y[MAX_FINGERS]; /* previous position array */
u_int sc_touch; /* touch status */
#define WSP_UNTOUCH 0x00
#define WSP_FIRST_TOUCH 0x01
#define WSP_SECOND_TOUCH 0x02
#define WSP_TOUCHING 0x04
- int16_t pre_pos_x; /* previous position array */
- int16_t pre_pos_y; /* previous position array */
int dx_sum; /* x axis cumulative movement */
int dy_sum; /* y axis cumulative movement */
int dz_sum; /* z axis cumulative movement */
@@ -590,7 +630,6 @@ struct wsp_softc {
#define WSP_TAP_THRESHOLD 3
#define WSP_TAP_MAX_COUNT 20
int distance; /* the distance of 2 fingers */
-#define MAX_DISTANCE 2500 /* the max allowed distance */
uint8_t ibtn; /* button status in tapping */
uint8_t ntaps; /* finger status in tapping */
uint8_t scr_mode; /* scroll status in movement */
@@ -858,10 +897,10 @@ wsp_attach(device_t dev)
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_POSITION_Y, sc->sc_params->y);
/* finger pressure */
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_PRESSURE, sc->sc_params->p);
- /* finger touch area */
+ /* finger major/minor axis */
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_TOUCH_MAJOR, sc->sc_params->w);
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_TOUCH_MINOR, sc->sc_params->w);
- /* finger approach area */
+ /* finger major/minor approach */
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_WIDTH_MAJOR, sc->sc_params->w);
WSP_SUPPORT_ABS(sc->sc_evdev, ABS_MT_WIDTH_MINOR, sc->sc_params->w);
/* finger orientation */
@@ -939,7 +978,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
int slot = 0;
#endif
- wsp_runing_rangecheck(&tun);
+ wsp_running_rangecheck(&tun);
if (sc->dz_count == 0)
sc->dz_count = WSP_DZ_MAX_COUNT;
@@ -994,7 +1033,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
f->pressure = le16toh((uint16_t)f->pressure);
f->multi = le16toh((uint16_t)f->multi);
}
- DPRINTFN(WSP_LLEVEL_INFO,
+ DPRINTFN(WSP_LLEVEL_INFO,
"[%d]ibt=%d, taps=%d, o=%4d, ax=%5d, ay=%5d, "
"rx=%5d, ry=%5d, tlmaj=%4d, tlmin=%4d, ot=%4x, "
"tchmaj=%4d, tchmin=%4d, presure=%4d, m=%4x\n",
@@ -1034,13 +1073,35 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
sc->sc_status.obutton = sc->sc_status.button;
sc->sc_status.button = 0;
+ if (ntouch == 2) {
+ sc->distance = max(sc->distance, max(
+ abs(sc->pos_x[0] - sc->pos_x[1]),
+ abs(sc->pos_y[0] - sc->pos_y[1])));
+ }
+
if (ibt != 0) {
- if ((params->tp->caps & HAS_INTEGRATED_BUTTON) && ntouch == 2)
- sc->sc_status.button |= MOUSE_BUTTON3DOWN;
- else if ((params->tp->caps & HAS_INTEGRATED_BUTTON) && ntouch == 3)
- sc->sc_status.button |= MOUSE_BUTTON2DOWN;
- else
+ if (params->tp->caps & HAS_INTEGRATED_BUTTON) {
+ switch (ntouch) {
+ case 1:
+ sc->sc_status.button |= MOUSE_BUTTON1DOWN;
+ break;
+ case 2:
+ if (sc->distance < tun.max_double_tap_distance && abs(sc->dx_sum) < 5 &&
+ abs(sc->dy_sum) < 5)
+ sc->sc_status.button |= MOUSE_BUTTON3DOWN;
+ else
+ sc->sc_status.button |= MOUSE_BUTTON1DOWN;
+ break;
+ case 3:
+ sc->sc_status.button |= MOUSE_BUTTON2DOWN;
+ break;
+ default:
+ break;
+ }
+ } else {
sc->sc_status.button |= MOUSE_BUTTON1DOWN;
+ }
+
sc->ibtn = 1;
}
sc->intr_count++;
@@ -1049,7 +1110,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
switch (ntouch) {
case 1:
if (sc->index[0]->touch_major > tun.pressure_tap_threshold &&
- sc->index[0]->tool_major <= 1200)
+ sc->index[0]->tool_major <= tun.max_finger_diameter)
sc->ntaps = 1;
break;
case 2:
@@ -1067,11 +1128,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
break;
}
}
- if (ntouch == 2) {
- sc->distance = max(sc->distance, max(
- abs(sc->pos_x[0] - sc->pos_x[1]),
- abs(sc->pos_y[0] - sc->pos_y[1])));
- }
+
if (sc->index[0]->touch_major < tun.pressure_untouch_threshold &&
sc->sc_status.button == 0) {
sc->sc_touch = WSP_UNTOUCH;
@@ -1092,7 +1149,7 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
case 2:
DPRINTFN(WSP_LLEVEL_INFO, "sum_x=%5d, sum_y=%5d\n",
sc->dx_sum, sc->dy_sum);
- if (sc->distance < MAX_DISTANCE && abs(sc->dx_sum) < 5 &&
+ if (sc->distance < tun.max_double_tap_distance && abs(sc->dx_sum) < 5 &&
abs(sc->dy_sum) < 5) {
wsp_add_to_queue(sc, 0, 0, 0, MOUSE_BUTTON3DOWN);
DPRINTFN(WSP_LLEVEL_INFO, "RIGHT CLICK!\n");
@@ -1107,17 +1164,19 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
}
wsp_add_to_queue(sc, 0, 0, 0, 0); /* button release */
}
- if ((sc->dt_sum / tun.scr_hor_threshold) != 0 &&
- sc->ntaps == 2 && sc->scr_mode == WSP_SCR_HOR) {
+
+ if (sc->scr_mode == WSP_SCR_HOR && sc->ntaps == tun.horizontal_swipe_finger_count
+ && tun.horizontal_swipe_finger_count > 0 && (sc->dt_sum / tun.scr_threshold) != 0) {
/*
- * translate T-axis into button presses
- * until further
+ * translate T-axis swipe into button
+ * presses 3 and 4 (forward/back)
*/
if (sc->dt_sum > 0)
wsp_add_to_queue(sc, 0, 0, 0, 1UL << 3);
else if (sc->dt_sum < 0)
wsp_add_to_queue(sc, 0, 0, 0, 1UL << 4);
}
+
sc->dz_count = WSP_DZ_MAX_COUNT;
sc->dz_sum = 0;
sc->intr_count = 0;
@@ -1138,38 +1197,38 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
} else if (sc->index[0]->touch_major >= tun.pressure_touch_threshold &&
sc->sc_touch == WSP_FIRST_TOUCH) { /* ignore second touch */
sc->sc_touch = WSP_SECOND_TOUCH;
- DPRINTFN(WSP_LLEVEL_INFO, "Fist pre_x=%5d, pre_y=%5d\n",
- sc->pre_pos_x, sc->pre_pos_y);
+ DPRINTFN(WSP_LLEVEL_INFO, "First pre_x[0]=%5d, pre_y[0]=%5d\n",
+ sc->pre_pos_x[0], sc->pre_pos_y[0]);
} else {
if (sc->sc_touch == WSP_SECOND_TOUCH)
sc->sc_touch = WSP_TOUCHING;
if (ntouch != 0 &&
sc->index[0]->touch_major >= tun.pressure_touch_threshold) {
- dx = sc->pos_x[0] - sc->pre_pos_x;
- dy = sc->pos_y[0] - sc->pre_pos_y;
+ dx = sc->pos_x[0] - sc->pre_pos_x[0];
+ dy = sc->pos_y[0] - sc->pre_pos_y[0];
- /* Ignore movement during button is releasing */
- if (sc->ibtn != 0 && sc->sc_status.button == 0)
+ /* Optionally ignore movement during button is releasing */
+ if (tun.enable_single_tap_movement != 1 && sc->ibtn != 0 && sc->sc_status.button == 0)
dx = dy = 0;
/* Ignore movement if ntouch changed */
if (sc->o_ntouch != ntouch)
dx = dy = 0;
- /* Ignore unexpeted movement when typing */
- if (ntouch == 1 && sc->index[0]->tool_major > 1200)
+ /* Ignore unexpected movement when typing (palm detection) */
+ if (ntouch == 1 && sc->index[0]->tool_major > tun.max_finger_diameter)
dx = dy = 0;
- if (sc->ibtn != 0 && ntouch == 1 &&
- sc->intr_count < WSP_TAP_MAX_COUNT &&
+ if (sc->ibtn != 0 && ntouch == 1 &&
+ sc->intr_count < WSP_TAP_MAX_COUNT &&
abs(sc->dx_sum) < 1 && abs(sc->dy_sum) < 1 )
dx = dy = 0;
if (ntouch == 2 && sc->sc_status.button != 0) {
- dx = sc->pos_x[sc->finger] - sc->pre_pos_x;
- dy = sc->pos_y[sc->finger] - sc->pre_pos_y;
-
+ dx = sc->pos_x[sc->finger] - sc->pre_pos_x[sc->finger];
+ dy = sc->pos_y[sc->finger] - sc->pre_pos_y[sc->finger];
+
/*
* Ignore movement of switch finger or
* movement from ibt=0 to ibt=1
@@ -1197,11 +1256,18 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
dx, dy, sc->finger);
}
if (sc->dz_count--) {
- rdz = (dy + sc->rdz) % tun.scale_factor;
- sc->dz_sum -= (dy + sc->rdz) / tun.scale_factor;
+ if (sc->scr_mode == WSP_SCR_HOR) {
+ rdz = (dx + sc->rdz) % tun.scale_factor;
+ sc->dz_sum -= (dx + sc->rdz) / tun.scale_factor;
+ } else if (sc->scr_mode == WSP_SCR_VER) {
+ rdz = (dy + sc->rdz) % tun.scale_factor;
+ sc->dz_sum -= (dy + sc->rdz) / tun.scale_factor;
+ }
sc->rdz = rdz;
}
- if ((sc->dz_sum / tun.z_factor) != 0)
+ if (sc->scr_mode == WSP_SCR_VER && (tun.z_factor == 0 || (sc->dz_sum / tun.z_factor) != 0))
+ sc->dz_count = 0;
+ else if (sc->scr_mode == WSP_SCR_HOR && (tun.t_factor == 0 || (sc->dz_sum / tun.t_factor) != 0))
sc->dz_count = 0;
}
rdx = (dx + sc->rdx) % tun.scale_factor;
@@ -1215,28 +1281,49 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
sc->dx_sum += dx;
sc->dy_sum += dy;
- if (ntouch == 2 && sc->sc_status.button == 0) {
- if (sc->scr_mode == WSP_SCR_NONE &&
- abs(sc->dx_sum) + abs(sc->dy_sum) > tun.scr_hor_threshold)
- sc->scr_mode = abs(sc->dx_sum) >
- abs(sc->dy_sum) * 2 ? WSP_SCR_HOR : WSP_SCR_VER;
- DPRINTFN(WSP_LLEVEL_INFO, "scr_mode=%5d, count=%d, dx_sum=%d, dy_sum=%d\n",
- sc->scr_mode, sc->intr_count, sc->dx_sum, sc->dy_sum);
- if (sc->scr_mode == WSP_SCR_HOR)
- sc->dt_sum += dx;
- else
- sc->dt_sum = 0;
+ if (sc->sc_status.button == 0 && ntouch > 0) {
+ if (ntouch == tun.scroll_finger_count || ntouch == tun.horizontal_swipe_finger_count) {
+ if (sc->scr_mode == WSP_SCR_NONE && abs(sc->dx_sum) + abs(sc->dy_sum) > tun.scr_threshold)
+ sc->scr_mode = abs(sc->dx_sum) > abs(sc->dy_sum) * 2 ? WSP_SCR_HOR : WSP_SCR_VER;
+
+ DPRINTFN(WSP_LLEVEL_INFO, "scr_mode=%5d, count=%d, dx_sum=%d, dy_sum=%d\n", sc->scr_mode, sc->intr_count, sc->dx_sum, sc->dy_sum);
+ }
- dx = dy = 0;
- if (sc->dz_count == 0)
- dz = (sc->dz_sum / tun.z_factor) * (tun.z_invert ? -1 : 1);
- if (sc->scr_mode == WSP_SCR_HOR ||
- abs(sc->pos_x[0] - sc->pos_x[1]) > MAX_DISTANCE ||
- abs(sc->pos_y[0] - sc->pos_y[1]) > MAX_DISTANCE)
+ if (ntouch == tun.scroll_finger_count) { /* preference scrolling over swipe if tun.scroll_finger_count == tun.horizontal_swipe_finger_count */
+ if (sc->scr_mode == WSP_SCR_HOR) {
+ sc->sc_status.button = 1 << 5;
+ }
+ dx = dy = dz = 0;
dz = 0;
+ sc->dt_sum = 0;
+ if (sc->distance <= tun.max_scroll_finger_distance && sc->dz_count == 0) {
+ if (sc->scr_mode == WSP_SCR_VER) {
+ if (tun.z_factor > 0)
+ dz = (sc->dz_sum / tun.z_factor) * (tun.z_invert ? -1 : 1);
+ } else if (sc->scr_mode == WSP_SCR_HOR) {
+ if (tun.t_factor > 0)
+ dz = (sc->dz_sum / tun.t_factor) * (tun.t_invert ? -1 : 1);
+ }
+ }
+ } else if (ntouch == tun.horizontal_swipe_finger_count) {
+ if (sc->scr_mode == WSP_SCR_HOR) {
+ sc->dt_sum += dx * (tun.t_invert ? -1 : 1);
+ } else {
+ sc->dt_sum = 0;
+ }
+ dx = dy = dz = 0;
+ }
}
+
if (ntouch == 3)
dx = dy = dz = 0;
+
+ if (ntouch != tun.horizontal_swipe_finger_count)
+ sc->dt_sum = 0;
+
+ if (ntouch == 0)
+ sc->scr_mode = WSP_SCR_NONE;
+
if (sc->intr_count < WSP_TAP_MAX_COUNT &&
abs(dx) < 3 && abs(dy) < 3 && abs(dz) < 3)
dx = dy = dz = 0;
@@ -1256,12 +1343,12 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error)
sc->rdz = 0;
}
}
- sc->pre_pos_x = sc->pos_x[0];
- sc->pre_pos_y = sc->pos_y[0];
+ sc->pre_pos_x[0] = sc->pos_x[0];
+ sc->pre_pos_y[0] = sc->pos_y[0];
if (ntouch == 2 && sc->sc_status.button != 0) {
- sc->pre_pos_x = sc->pos_x[sc->finger];
- sc->pre_pos_y = sc->pos_y[sc->finger];
+ sc->pre_pos_x[sc->finger] = sc->pos_x[sc->finger];
+ sc->pre_pos_y[sc->finger] = sc->pos_y[sc->finger];
}
sc->o_ntouch = ntouch;
@@ -1321,6 +1408,7 @@ wsp_add_to_queue(struct wsp_softc *sc, int dx, int dy, int dz,
buf[6] = dz - (dz >> 1);/* dz - (dz / 2) */
buf[7] = (((~buttons_in) >> 3) & MOUSE_SYS_EXTBUTTONS);
}
+
usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf,
sc->sc_mode.packetsize, 1);
}