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;