diff options
Diffstat (limited to 'sys/dev/usb/input')
-rw-r--r-- | sys/dev/usb/input/atp.c | 1 | ||||
-rw-r--r-- | sys/dev/usb/input/uhid.c | 5 | ||||
-rw-r--r-- | sys/dev/usb/input/ukbd.c | 73 | ||||
-rw-r--r-- | sys/dev/usb/input/ums.c | 6 | ||||
-rw-r--r-- | sys/dev/usb/input/usbhid.c | 16 | ||||
-rw-r--r-- | sys/dev/usb/input/wmt.c | 1 | ||||
-rw-r--r-- | sys/dev/usb/input/wsp.c | 234 |
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); } |