From nobody Fri Sep 06 18:35:22 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4X0lK71Tvpz5VS2C; Fri, 06 Sep 2024 18:35:23 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4X0lK62tqxz4Vsn; Fri, 6 Sep 2024 18:35:22 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1725647722; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HiI/DEk/tzzaRFm9KmAj849PtcDmzTa5GdB5Zu6Jz84=; b=dHqsjYTTU9lTjq0yu4honNwOZtrZbbZNV6Os2xkK1kcmZSkMOJvh8O+GUSphUKIYDOXU4Y pMHd5hEsV0+wCWu/ZlLef+n5MAhPiklDji/MfmRX59VqllKihopXjUaXUYStmKqAxmZSaP g6XXjQykHMRGKDtNC1CUy1LAsCzKjM6Cf2vpTHHgD9j9N5lJSZ669SuizdPZ3RbLySsWku ZWFnZQ1CiSIsIZN12oDsaoWbFJXL4KE/hySZ1eeAY53aIrswqvoP1/hy79Xzlod1TVaFdJ wuaxyzgqzMSAyLqHsNO1GgL9jrtS41e4KXEnfqiE27/bmQJ0SLzTZHn1U1LXGA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1725647722; a=rsa-sha256; cv=none; b=EN+KmzIr2nPHji2Di1COaBQGnH8ADyusUQHJSvScFl5CzgGvxPz7WOatSHGO+jOVcWbe6u k8J2Mm2LJKO6U5Qt2sCbLUjd17jBGMnDohOC0zUURWNrS70EKC+Ui8HG8CemYq59pTf0UW NHIJzyq2i0KF1LV0dxfuuTIHGwYVUYpwkP5CaP8g6nDdPmmx55o/B9i2QFe/IIE4ZOLyDh sCtWCQ1+oY75FVA3wLEy7MSKu8PuEakaGMH7iZi4YVahdOG/YE0azmARkHOsEfELC2cdMV AZ+qTBX8c+n7uEdhPpeHTpxecAeqAyAQi0b7zZkmNB0PKSm4sUZD5fPZuU05Ww== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1725647722; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=HiI/DEk/tzzaRFm9KmAj849PtcDmzTa5GdB5Zu6Jz84=; b=V4lKsE8ezA5wM0DPY67zOciTzB1ffFVx0XXZWhgr59lJzKNvxiwIDu/JVcgoK4y+miH0/z zxtQqBLH38LBNYoL28tazDr3xYleGRiAs+QQEN0bJ2EFRvyTdQrybhvBndFnhvrXsWTUnN RES/BipIUD/dRfjfpna9aGzKd+jp4biNOkkMqPepvC4v2pfGXK81hP8UtzoHFHYiE/6XMJ b0nbSx6Zrc+4PcutOHtU9E1oB8GF5qTQ9r2I0RIjDqmMR0PGFAoqr7vcql8f3CTcwWyU8n SVRZBsFdZ9mbRVPj6uT+BHH6XcszQ832uOtR0drTVYe/VESsfR5sDGvmeEVemg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4X0lK621jLz12nR; Fri, 6 Sep 2024 18:35:22 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 486IZMc3011254; Fri, 6 Sep 2024 18:35:22 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 486IZM4U011251; Fri, 6 Sep 2024 18:35:22 GMT (envelope-from git) Date: Fri, 6 Sep 2024 18:35:22 GMT Message-Id: <202409061835.486IZM4U011251@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Warner Losh Subject: git: 62cf43dda897 - main - wsp: Improve multi-finger touchpad usage and allow more configurations List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 62cf43dda897f33bb80a20630f34bfe204cb97ee Auto-Submitted: auto-generated The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=62cf43dda897f33bb80a20630f34bfe204cb97ee commit 62cf43dda897f33bb80a20630f34bfe204cb97ee Author: Joshua Rogers AuthorDate: 2024-05-28 00:20:19 +0000 Commit: Warner Losh CommitDate: 2024-09-06 18:34:31 +0000 wsp: Improve multi-finger touchpad usage and allow more configurations This patch allows scrolling with multiple fingers simultaneously, in line with how wsp trackpads function on MacOS. Two new tunables are added: hw.usb.wsp.max_finger_area and hw.usb.wsp.max_double_tap_distance. max_finger_area defines the maximum size which the driver registered an object on trackpad as a finger. Previously, this value was hardcoded as 1200, which was too low to register thumb-clicks. max_double_tap_distance defines the maximum distance between two fingers which will register as a double-click. Signed-off-by: Joshua Rogers Reviewed by: imp, wulf Pull Request: https://github.com/freebsd/freebsd-src/pull/1365 --- share/man/man4/wsp.4 | 6 ++++ sys/dev/usb/input/wsp.c | 85 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 29 deletions(-) diff --git a/share/man/man4/wsp.4 b/share/man/man4/wsp.4 index bcbbc1b8bb5d..83a4421fa2ff 100644 --- a/share/man/man4/wsp.4 +++ b/share/man/man4/wsp.4 @@ -70,6 +70,12 @@ controlled using the sysctl tunable .Nm hw.usb.wsp.enable_single_tap_movement , set to 0 to disable the movement on the trackpad until a full release or 1 to allow the continued movement (default). +.Nm hw.usb.wsp.max_finger_area +defines the maximum area on the trackpad which is registered as a +finger (lower for greater palm detection). +.Nm hw.usb.wsp.max_double_tap_distance +defines the maximum distance between two finger clicks or taps which may +register as a double-click. Z-Axis sensitivity can be controlled using the sysctl tunable .Nm hw.usb.wsp.z_factor . Z-Axis inversion can be controlled using the sysctl tunable diff --git a/sys/dev/usb/input/wsp.c b/sys/dev/usb/input/wsp.c index 4527278295ca..708a26498361 100644 --- a/sys/dev/usb/input/wsp.c +++ b/sys/dev/usb/input/wsp.c @@ -98,6 +98,8 @@ static struct wsp_tuning { int pressure_untouch_threshold; int pressure_tap_threshold; int scr_hor_threshold; + int max_finger_area; + int max_double_tap_distance; int enable_single_tap_clicks; int enable_single_tap_movement; } @@ -110,6 +112,8 @@ static struct wsp_tuning { .pressure_untouch_threshold = 10, .pressure_tap_threshold = 120, .scr_hor_threshold = 20, + .max_finger_area = 1900, + .max_double_tap_distance = 2500, .enable_single_tap_clicks = 1, .enable_single_tap_movement = 1, }; @@ -123,6 +127,8 @@ wsp_runing_rangecheck(struct wsp_tuning *ptun) 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->max_finger_area, 1, 2400); + WSP_CLAMP(ptun->max_double_tap_distance, 1, 16384); WSP_CLAMP(ptun->scr_hor_threshold, 1, 255); WSP_CLAMP(ptun->enable_single_tap_clicks, 0, 1); WSP_CLAMP(ptun->enable_single_tap_movement, 0, 1); @@ -140,6 +146,10 @@ 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, max_finger_area, CTLFLAG_RWTUN, + &wsp_tuning.max_finger_area, 0, "maximum finger area"); +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_hor_threshold, CTLFLAG_RWTUN, &wsp_tuning.scr_hor_threshold, 0, "horizontal scrolling threshold"); SYSCTL_INT(_hw_usb_wsp, OID_AUTO, enable_single_tap_clicks, CTLFLAG_RWTUN, @@ -573,13 +583,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 */ @@ -596,7 +606,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 */ @@ -1040,13 +1049,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++; @@ -1055,7 +1086,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_area) sc->ntaps = 1; break; case 2: @@ -1073,11 +1104,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; @@ -1098,7 +1125,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"); @@ -1144,16 +1171,16 @@ 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]; /* Optionally ignore movement during button is releasing */ if (tun.enable_single_tap_movement != 1 && sc->ibtn != 0 && sc->sc_status.button == 0) @@ -1163,8 +1190,8 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) 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_area) dx = dy = 0; if (sc->ibtn != 0 && ntouch == 1 && @@ -1173,8 +1200,8 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) 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 @@ -1237,8 +1264,8 @@ wsp_intr_callback(struct usb_xfer *xfer, usb_error_t error) 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) + abs(sc->pos_x[0] - sc->pos_x[1]) > tun.max_finger_area || + abs(sc->pos_y[0] - sc->pos_y[1]) > tun.max_finger_area) dz = 0; } if (ntouch == 3) @@ -1262,12 +1289,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;