On Sun, Sep 18, 2022 at 02:21:06PM +0200, Tobias Heider wrote:
> 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?

Here's an updated version that does not add a new WSMOUSE_TYPE and as such does
not require any changes in X.  Instead I just pass the button configuration via
params in wsmouse_configure().

To make this work I had to fix a bug in wstpad where the CONFIGURE flag is not
set after initial configuration, which causes all values to be overwritten with
the defaults on each reconfigure triggered from wsmouse_set_params().

diff --git sys/arch/arm64/dev/apldc.c sys/arch/arm64/dev/apldc.c
index 09a03c734da..7962a3c645a 100644
--- sys/arch/arm64/dev/apldc.c
+++ sys/arch/arm64/dev/apldc.c
@@ -1317,6 +1317,11 @@ const struct wsmouse_accessops apldcms_accessops = {
        .ioctl = apldcms_ioctl,
 };
 
+static struct wsmouse_param apldcms_params[] = {
+       { WSMOUSECFG_SOFTBUTTONS, 0 },
+       { WSMOUSECFG_MTBUTTONS, 1 },
+};
+
 int     apldcms_match(struct device *, void *, void *);
 void    apldcms_attach(struct device *, struct device *, void *);
 
@@ -1372,7 +1377,7 @@ apldcms_configure(struct apldcms_softc *sc)
        hw->mt_slots = UBCMTP_MAX_FINGERS;
        hw->flags = WSMOUSEHW_MT_TRACKING;
 
-       return wsmouse_configure(sc->sc_wsmousedev, NULL, 0);
+       return wsmouse_configure(sc->sc_wsmousedev, apldcms_params, 2);
 }
 
 void
diff --git sys/arch/arm64/dev/aplhidev.c sys/arch/arm64/dev/aplhidev.c
index 2b00f7e217d..ecfb5b8f4eb 100644
--- sys/arch/arm64/dev/aplhidev.c
+++ sys/arch/arm64/dev/aplhidev.c
@@ -608,6 +608,11 @@ const struct wsmouse_accessops aplms_accessops = {
        .ioctl = aplms_ioctl,
 };
 
+static struct wsmouse_param aplms_params[] = {
+       { WSMOUSECFG_SOFTBUTTONS, 0 },
+       { WSMOUSECFG_MTBUTTONS, 1 },
+};
+
 int     aplms_match(struct device *, void *, void *);
 void    aplms_attach(struct device *, struct device *, void *);
 
@@ -663,7 +668,7 @@ aplms_configure(struct aplms_softc *sc)
        hw->mt_slots = UBCMTP_MAX_FINGERS;
        hw->flags = WSMOUSEHW_MT_TRACKING;
 
-       return wsmouse_configure(sc->sc_wsmousedev, NULL, 0);
+       return wsmouse_configure(sc->sc_wsmousedev, aplms_params, 2);
 }
 
 void
diff --git sys/dev/wscons/wsconsio.h sys/dev/wscons/wsconsio.h
index de483493360..497e9a32db7 100644
--- sys/dev/wscons/wsconsio.h
+++ sys/dev/wscons/wsconsio.h
@@ -313,6 +313,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..4384370545e 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:
@@ -1599,6 +1619,7 @@ wstpad_configure(struct wsmouseinput *input)
                tp->scroll.hdist = 4 * h_unit;
                tp->scroll.vdist = 4 * v_unit;
                tp->tap.maxdist = 4 * h_unit;
+               input->flags |= CONFIGURED;
        }
 
        /* A touch with a flag set in this mask does not move the pointer. */
@@ -1621,6 +1642,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 +1725,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 +1822,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