Hi,

the diff below adds a new mouse type WSMOUSE_TYPE_APPLE which emulates Apples
touchpad behaviour.  Instead of mapping soft-buttons to an area on the pad,
the different mouse buttons are mapped to single-finger, two-finger and
three-finger clicks as is the default in macos.

The diff enables the new mode on apldcms(4) and aplms(4) which are the drivers
used by Apple silicon laptops.

Tested on an m2 air by me and an m1 by robert@.

ok?

diff --git sys/arch/arm64/dev/apldc.c sys/arch/arm64/dev/apldc.c
index 09a03c734da..f261c19b13b 100644
--- sys/arch/arm64/dev/apldc.c
+++ sys/arch/arm64/dev/apldc.c
@@ -1363,7 +1363,7 @@ apldcms_configure(struct apldcms_softc *sc)
        struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev);
 
        /* The values below are for the MacBookPro17,1 */
-       hw->type = WSMOUSE_TYPE_TOUCHPAD;
+       hw->type = WSMOUSE_TYPE_APPLE;
        hw->hw_type = WSMOUSEHW_CLICKPAD;
        hw->x_min = -6046;
        hw->x_max = 6536;
diff --git sys/arch/arm64/dev/aplhidev.c sys/arch/arm64/dev/aplhidev.c
index 2b00f7e217d..290520e85cb 100644
--- sys/arch/arm64/dev/aplhidev.c
+++ sys/arch/arm64/dev/aplhidev.c
@@ -654,7 +654,7 @@ aplms_configure(struct aplms_softc *sc)
        struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev);
 
        /* The values below are for the MacBookPro17,1 */
-       hw->type = WSMOUSE_TYPE_TOUCHPAD;
+       hw->type = WSMOUSE_TYPE_APPLE;
        hw->hw_type = WSMOUSEHW_CLICKPAD;
        hw->x_min = -6046;
        hw->x_max = 6536;
diff --git sys/dev/wscons/wsconsio.h sys/dev/wscons/wsconsio.h
index de483493360..67b46da8d1f 100644
--- sys/dev/wscons/wsconsio.h
+++ sys/dev/wscons/wsconsio.h
@@ -245,6 +245,7 @@ struct wskbd_encoding_data {
 #define                WSMOUSE_TYPE_ELANTECH   18      /* Elantech touchpad */
 #define                WSMOUSE_TYPE_SYNAP_SBTN 19      /* Synaptics soft 
buttons */
 #define                WSMOUSE_TYPE_TOUCHPAD   20      /* Generic touchpad */
+#define                WSMOUSE_TYPE_APPLE      21      /* Apple touchpad */
 
 /* Set resolution.  Not applicable to all mouse types. */
 #define        WSMOUSEIO_SRES          _IOW('W', 33, u_int)
@@ -313,6 +314,7 @@ enum wsmousecfg {
        WSMOUSECFG_SOFTBUTTONS = 64,    /* 2 soft-buttons at the bottom edge */
        WSMOUSECFG_SOFTMBTN,            /* add a middle-button area */
        WSMOUSECFG_TOPBUTTONS,          /* 3 soft-buttons at the top edge */
+       WSMOUSECFG_MTBUTTONS,           /* multi-finger buttons */
        WSMOUSECFG_TWOFINGERSCROLL,     /* enable two-finger scrolling */
        WSMOUSECFG_EDGESCROLL,          /* enable edge scrolling */
        WSMOUSECFG_HORIZSCROLL,         /* enable horizontal edge scrolling */
diff --git sys/dev/wscons/wstpad.c sys/dev/wscons/wstpad.c
index be074b89fb8..9a74fa65908 100644
--- sys/dev/wscons/wstpad.c
+++ sys/dev/wscons/wstpad.c
@@ -72,6 +72,7 @@
 enum tpad_handlers {
        SOFTBUTTON_HDLR,
        TOPBUTTON_HDLR,
+       MTBUTTON_HDLR,
        TAP_HDLR,
        F2SCROLL_HDLR,
        EDGESCROLL_HDLR,
@@ -149,6 +150,7 @@ struct tpad_touch {
 #define WSTPAD_HORIZSCROLL     (1 << 5)
 #define WSTPAD_SWAPSIDES       (1 << 6)
 #define WSTPAD_DISABLE         (1 << 7)
+#define WSTPAD_MTBUTTONS       (1 << 8)
 
 #define WSTPAD_MT              (1 << 31)
 
@@ -646,7 +648,23 @@ wstpad_softbuttons(struct wsmouseinput *input, u_int 
*cmds, int hdlr)
        }
 
        if (tp->softbutton == 0 && PRIMARYBTN_CLICKED(tp)) {
-               tp->softbutton = wstpad_get_sbtn(input, top);
+               if (hdlr == MTBUTTON_HDLR) {
+                       switch (tp->contacts) {
+                       case 2:
+                               tp->softbutton = RIGHTBTN;
+                               break;
+                       case 3:
+                               tp->softbutton = MIDDLEBTN;
+                               break;
+                       case 1:
+                               tp->softbutton = LEFTBTN;
+                               break;
+                       default:
+                               tp->softbutton = 0;
+                               break;
+                       }
+               } else
+                       tp->softbutton = wstpad_get_sbtn(input, top);
                if (tp->softbutton)
                        *cmds |= 1 << SOFTBUTTON_DOWN;
        }
@@ -1237,12 +1255,14 @@ wstpad_process_input(struct wsmouseinput *input, struct 
evq_access *evq)
        cmds = 0;
        handlers = tp->handlers;
        if (DISABLE(tp))
-               handlers &= ((1 << TOPBUTTON_HDLR) | (1 << SOFTBUTTON_HDLR));
+               handlers &= ((1 << TOPBUTTON_HDLR) | (1 << SOFTBUTTON_HDLR) |
+                   (1 << MTBUTTON_HDLR));
 
        FOREACHBIT(handlers, hdlr) {
                switch (hdlr) {
                case SOFTBUTTON_HDLR:
                case TOPBUTTON_HDLR:
+               case MTBUTTON_HDLR:
                        wstpad_softbuttons(input, &cmds, hdlr);
                        continue;
                case TAP_HDLR:
@@ -1578,6 +1598,8 @@ wstpad_configure(struct wsmouseinput *input)
                if (input->hw.hw_type == WSMOUSEHW_CLICKPAD) {
                        if (input->hw.type == WSMOUSE_TYPE_SYNAP_SBTN) {
                                tp->features |= WSTPAD_TOPBUTTONS;
+                       } else if (input->hw.type == WSMOUSE_TYPE_APPLE) {
+                               tp->features |= WSTPAD_MTBUTTONS;
                        } else {
                                tp->features |= WSTPAD_SOFTBUTTONS;
                                tp->features |= WSTPAD_SOFTMBTN;
@@ -1621,6 +1643,8 @@ wstpad_configure(struct wsmouseinput *input)
 
        tp->handlers = 0;
 
+       if (tp->features & WSTPAD_MTBUTTONS)
+               tp->handlers |= 1 << MTBUTTON_HDLR;
        if (tp->features & WSTPAD_SOFTBUTTONS)
                tp->handlers |= 1 << SOFTBUTTON_HDLR;
        if (tp->features & WSTPAD_TOPBUTTONS)
@@ -1702,6 +1726,9 @@ wstpad_set_param(struct wsmouseinput *input, int key, int 
val)
                case WSMOUSECFG_TOPBUTTONS:
                        flag = WSTPAD_TOPBUTTONS;
                        break;
+               case WSMOUSECFG_MTBUTTONS:
+                       flag = WSTPAD_MTBUTTONS;
+                       break;
                case WSMOUSECFG_TWOFINGERSCROLL:
                        flag = WSTPAD_TWOFINGERSCROLL;
                        break;
@@ -1796,6 +1823,9 @@ wstpad_get_param(struct wsmouseinput *input, int key, int 
*pval)
                case WSMOUSECFG_TOPBUTTONS:
                        flag = WSTPAD_TOPBUTTONS;
                        break;
+               case WSMOUSECFG_MTBUTTONS:
+                       flag = WSTPAD_MTBUTTONS;
+                       break;
                case WSMOUSECFG_TWOFINGERSCROLL:
                        flag = WSTPAD_TWOFINGERSCROLL;
                        break;

Reply via email to