Re: wsmouse(4): multi-touch buttons again
This version of the diff adds a wsconsctl field, named "mouse.tp. mtbuttons", and an update to the wsmouse.4 page. Apart from that, it contains only stylistic changes. The new wsconsctl field is just a boolean, I don't think that it would make sense to include the distance filter in the configuration options. However, if a default value is derived from the length of the touchpad diagonal, it might be too high for over-sized touchpads. If that turns out to be a problem, the proper place to fix it is the hardware driver. OK? On 2/21/23 20:10, Ulf Brosziewski wrote: > This diff is an extension of Tobias Heider's proposal, which aims at > providing "Apple-like" button inputs on clickpads. I have added some > things in order to approximate the behaviour of other input drivers. > > [...]> > The feature won't work decently on small touchpads, and it cannot work > on touchpads without MT-support in our kernel. wsmouse checks whether > a touchpad > 1) has MT support, > 2) is a clickpad, > 3) its resolution is reported to wsmouse, > 4) it reports a horizontal size greater than 100mm, and > 5) a vertical size greater than 60mm. > > If these conditions aren't met, wsmouse sets the distance limit to -1, > which blocks the MTBUTTONS feature. I think only imt(4) touchpads can > meet these criteria; however, the value can be overridden manually or > programmatically, and ubcmtp and aplms do this on initialization. > These drivers don't report resolution values; the distance limit will > be set to a fourth of the length of the touchpad diagonal. That's a > workaround based on a wild guess, and I couldn't test it with Apple > hardware. If you want to apply it to an Elantech-v4 touchpad run by > pms(4), try > > # wsconsctl mouse.param=143:0,72:1 > > (A change from -1 to 0 will trigger the workaround.) > > > [...] Index: src/sbin/wsconsctl/mouse.c === RCS file: /cvs/src/sbin/wsconsctl/mouse.c,v retrieving revision 1.20 diff -u -p -r1.20 mouse.c --- src/sbin/wsconsctl/mouse.c 19 Aug 2019 21:42:33 - 1.20 +++ src/sbin/wsconsctl/mouse.c 27 Jun 2023 18:54:31 - @@ -57,6 +57,7 @@ struct field mouse_field_tab[] = { { "reverse_scrolling", _revscroll, FMT_CFG,FLG_NORDBACK }, /* touchpad-specific options: */ { "tp.tapping",_tapping, FMT_CFG,FLG_NORDBACK }, +{ "tp.mtbuttons", _mtbuttons, FMT_CFG,FLG_NORDBACK }, { "tp.scaling",_scaling, FMT_CFG,FLG_NORDBACK }, { "tp.swapsides", _swapsides, FMT_CFG,FLG_NORDBACK }, { "tp.disable",_disable, FMT_CFG,FLG_NORDBACK }, @@ -69,6 +70,10 @@ struct field mouse_field_tab[] = { static int dev_index = -1; +static struct wsmouse_parameters mtbtn_maxdist = { +(struct wsmouse_param[]) { { WSMOUSECFG_MTBTN_MAXDIST, 0 } }, 1 +}; + void mouse_init(int devfd, int devidx) { @@ -91,6 +96,12 @@ mouse_init(int devfd, int devidx) { if (f->format == FMT_CFG) { f->flags &= ~FLG_DEAD; } + /* Hide the 'mtbuttons' field if the feature is unavailable. */ + if (mousecfg_get_field(_maxdist) || + mtbtn_maxdist.params[0].value < 0) { + f = field_by_value(mouse_field_tab, _mtbuttons); + f->flags |= FLG_DEAD; + } } else { for (f = mouse_field_tab; f->name != NULL; f++) if (f->format == FMT_CFG) { Index: src/sbin/wsconsctl/mousecfg.c === RCS file: /cvs/src/sbin/wsconsctl/mousecfg.c,v retrieving revision 1.9 diff -u -p -r1.9 mousecfg.c --- src/sbin/wsconsctl/mousecfg.c 3 Mar 2021 19:44:37 - 1.9 +++ src/sbin/wsconsctl/mousecfg.c 27 Jun 2023 18:54:31 - @@ -35,30 +35,15 @@ #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) #endif -#define BASE_FIRST WSMOUSECFG_DX_SCALE -#define BASE_LAST WSMOUSECFG_REVERSE_SCROLLING -#define TP_FILTER_FIRSTWSMOUSECFG_DX_MAX -#define TP_FILTER_LAST WSMOUSECFG_SMOOTHING -#define TP_FEATURES_FIRST WSMOUSECFG_SOFTBUTTONS -#define TP_FEATURES_LAST WSMOUSECFG_DISABLE -#define TP_SETUP_FIRST WSMOUSECFG_LEFT_EDGE -#define TP_SETUP_LAST WSMOUSECFG_TAP_THREE_BTNMAP -#define LOG_FIRST WSMOUSECFG_LOG_INPUT -#define LOG_LAST WSMOUSECFG_LOG_EVENTS - -#define BASESIZE ((BASE_LAST - BASE_FIRST + 1) + (LOG_LAST - LOG_FIRST + 1)) - -#define BUFSIZE (BASESIZE \ -+ (TP_FILTER_LAST - TP_FILTER_FIRST + 1) \ -+ (TP_FEAT
Re: synaptics touchpad with no multifinger support
Sorry for being so late with my reply. Checking SYNAPTICS_CAP_MULTIFINGER is not sufficient. There are Synaptics touchpads that don't report this capability but do provide contact counts (and that's not a rare case). Adding a test for AGM support seems to be a viable workaround, see https://github.com/torvalds/linux/blob/v6.3/drivers/input/mouse/synaptics.c#L1051 So the code should look like: Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.97 diff -u -p -r1.97 pms.c --- dev/pckbc/pms.c 23 Jul 2022 05:55:16 - 1.97 +++ dev/pckbc/pms.c 22 May 2023 18:03:30 - @@ -1075,7 +1075,11 @@ synaptics_get_hwinfo(struct pms_softc *s hw->y_max = (max_coords ? SYNAPTICS_Y_LIMIT(max_coords) : SYNAPTICS_YMAX_BEZEL); - hw->contacts_max = SYNAPTICS_MAX_FINGERS; + if ((syn->capabilities & SYNAPTICS_CAP_MULTIFINGER) || + SYNAPTICS_SUPPORTS_AGM(syn->ext_capabilities)) + hw->contacts_max = SYNAPTICS_MAX_FINGERS; + else + hw->contacts_max = 1; syn->sec_buttons = 0; --- Tests and OKs would be welcome. On 4/18/23 23:41, la ninpre wrote: > Hello, tech@ > > So I installed OpenBSD on old Compaq laptop and noticed that scrolling > with touchpad is not working. I started investigating to see why it > is the case and found out a few odd things in wscons(4) and pckbc(4) > drivers. > > Basically, the laptop's touchpad lacks multifinger support (see dmesg > below), but nevertheless, wscons(4) sets it to two-finger mode, which > doesn't work, obviously. Initially, I thought about adding something > like mouse.tp.edgescroll to wsconsctl(8). I then found out that there > is already undocumented mouse.tp.param option, that can be used to > force the edgescroll mode by setting 67 (WSMOUSECFG_TWOFINGERSCROLL) > to 0 and 68 (WSMOUSECFG_EDGESCROLL) to 1, but I don't think it is > very convenient and readable. > > Later I continued to investigate, why wscons(4) defaults to two-finger > mode and found that it does so by examining a field of a touchpad data > structure called 'contacts_max' [1], which, I assumed, represents > a number of maximum simultaneous touches. But when I grepped for > this name to see where this value is set, I found that it is set > in pckbc(4). It is done in a very simple way, so it sets it to 3 > (well, actually SYNAPTICS_MAX_FINGERS, but it is defined to be 3 > only there and nowhere else) if the device in question is a synaptics > touchpad (!) [2], even though the touchpad has a capabilities field > and it is recognized correctly (SYNAPTICS_CAP_MULTIFINGER is set > to 0 in my case). So I think a solution would be at least checking > SYNAPTIC_CAP_MULTIFINGER and setting contacts_max depending on that > (3 if true, 1 if false). Maybe it is a bodge, but it works. > > Index: pms.c > === > RCS file: /cvs/src/sys/dev/pckbc/pms.c,v > retrieving revision 1.97 > diff -u -p -r1.97 pms.c > --- pms.c 23 Jul 2022 05:55:16 - 1.97 > +++ pms.c 18 Apr 2023 21:36:10 - > @@ -1075,7 +1075,10 @@ synaptics_get_hwinfo(struct pms_softc *s > hw->y_max = (max_coords ? > SYNAPTICS_Y_LIMIT(max_coords) : SYNAPTICS_YMAX_BEZEL); > > - hw->contacts_max = SYNAPTICS_MAX_FINGERS; > + if(syn->capabilities & SYNAPTICS_CAP_MULTIFINGER) > + hw->contacts_max = SYNAPTICS_MAX_FINGERS; > + else > + hw->contacts_max = 1; > > syn->sec_buttons = 0; > > > > [1]: /sys/dev/wscons/wstpad.c:1573 > [2]: /sys/dev/pckbc/psm.c:1078 > > Here are relevant lines from dmesg(8): > > pms0 at pckbc0 (aux slot) > wsmouse0 at pms0 mux 0 > pms0: Synaptics touchpad, firmware 6.5, 0x1c0b1 0xa0 0x0 0xa04751 0x0 > > So I'm looking forward for comments on this. Has anybody experienced > something similar? >
Re: wsmouse(4): multi-touch buttons again
I do not expect users to find that field, or play around with it if they don't know what they do. It's "hidden" in wsconsctl for a reason. And plainly, I had no time for the wsconsctl part. On 2/23/23 17:25, joshua stein wrote: > On Thu, 23 Feb 2023 at 17:05:53 +0100, Tobias Heider wrote: >> Wow, thank you for looking into this! I've used your version for a few days >> now and it works really well for me (on a m2 macbook air). I actually think >> the default works so well that we can default to 0 for param 143. >> >> IMO we can add it to the tree at this point to give others the change to >> test it before the diff gets even bigger. > > But please add properly named knobs to wsconsctl for this first, and > preferably for all of the other hidden settings that were added with > wstpad. Expecting users to enable, let alone find, > "mouse.tp.param=72:1" is ridiculous. > > On one of my laptops I wanted to disable the middle soft button and > had to dig through the code to figure out that I had to use > "wsconsctl mouse.tp.param=65:0". >
wsmouse(4): multi-touch buttons again
This diff is an extension of Tobias Heider's proposal, which aims at providing "Apple-like" button inputs on clickpads. I have added some things in order to approximate the behaviour of other input drivers. It's a quick shot, and I have no idea whether it is sufficient in practice, it certainly needs thorough testing. The wsconsctl part doesn't provide a named field yet. With a recompiled wsconsctl and kernel, the command # wsconsctl mouse.param=72:1 activates the feature, if it is available (see below). The patch contains a simple filter for distinguishing the two-finger inputs that should trigger right-button events from the ones that shouldn't: If the distance between two contacts is small, the driver generates a right-button event; if it is greater than some threshold value, the second contact will be ignored. When a touch is resting in the bottom area, it will be ignored, and no further filtering applies to the other touches. You can inspect the threshold value with # wsconsctl mouse.param=143 and change it with # wsconsctl mouse.param=143: The value is given in device units. If the driver for your touchpad is imt(4), the default should correspond, roughly, to a distance of 35mm. The threshold is reduced by one third if a two-finger click involves a touch in the bottom area. (On medium-sized touchpads, this may be necessary to leave enough room for left-button clicks performed by the thumb while the pointer-controlling touch remains on the touchpad.) The feature won't work decently on small touchpads, and it cannot work on touchpads without MT-support in our kernel. wsmouse checks whether a touchpad 1) has MT support, 2) is a clickpad, 3) its resolution is reported to wsmouse, 4) it reports a horizontal size greater than 100mm, and 5) a vertical size greater than 60mm. If these conditions aren't met, wsmouse sets the distance limit to -1, which blocks the MTBUTTONS feature. I think only imt(4) touchpads can meet these criteria; however, the value can be overridden manually or programmatically, and ubcmtp and aplms do this on initialization. These drivers don't report resolution values; the distance limit will be set to a fourth of the length of the touchpad diagonal. That's a workaround based on a wild guess, and I couldn't test it with Apple hardware. If you want to apply it to an Elantech-v4 touchpad run by pms(4), try # wsconsctl mouse.param=143:0,72:1 (A change from -1 to 0 will trigger the workaround.) diff --git a/sbin/wsconsctl/mousecfg.c b/sbin/wsconsctl/mousecfg.c index 76a9984bd86..d6609218372 100644 --- a/sbin/wsconsctl/mousecfg.c +++ b/sbin/wsconsctl/mousecfg.c @@ -40,9 +40,9 @@ #define TP_FILTER_FIRSTWSMOUSECFG_DX_MAX #define TP_FILTER_LAST WSMOUSECFG_SMOOTHING #define TP_FEATURES_FIRST WSMOUSECFG_SOFTBUTTONS -#define TP_FEATURES_LAST WSMOUSECFG_DISABLE +#define TP_FEATURES_LAST WSMOUSECFG_MTBUTTONS #define TP_SETUP_FIRST WSMOUSECFG_LEFT_EDGE -#define TP_SETUP_LAST WSMOUSECFG_TAP_THREE_BTNMAP +#define TP_SETUP_LAST WSMOUSECFG_MTBTN_MAXDIST #define LOG_FIRST WSMOUSECFG_LOG_INPUT #define LOG_LAST WSMOUSECFG_LOG_EVENTS diff --git a/sys/arch/arm64/dev/aplhidev.c b/sys/arch/arm64/dev/aplhidev.c index 265c5196168..b3bf4838fe8 100644 --- a/sys/arch/arm64/dev/aplhidev.c +++ b/sys/arch/arm64/dev/aplhidev.c @@ -680,6 +680,10 @@ struct ubcmtp_finger { /* Use a constant, synaptics-compatible pressure value for now. */ #define DEFAULT_PRESSURE 40 +static struct wsmouse_param aplms_wsmousecfg[] = { + { WSMOUSECFG_MTBTN_MAXDIST, 0 }, /* 0: Compute a default value. */ +}; + struct aplms_softc { struct device sc_dev; struct device *sc_wsmousedev; @@ -759,7 +763,8 @@ 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_wsmousecfg, nitems(aplms_wsmousecfg)); } void diff --git a/sys/dev/hid/hidmt.c b/sys/dev/hid/hidmt.c index 62b500a4f44..9e01fe597bf 100644 --- a/sys/dev/hid/hidmt.c +++ b/sys/dev/hid/hidmt.c @@ -103,7 +103,7 @@ hidmt_get_resolution(struct hid_item *h) phy_extent *= 10; } - return (log_extent / phy_extent); + return ((log_extent + phy_extent / 2) / phy_extent); } int diff --git a/sys/dev/usb/ubcmtp.c b/sys/dev/usb/ubcmtp.c index d86883bd6c2..b5acdadef46 100644 --- a/sys/dev/usb/ubcmtp.c +++ b/sys/dev/usb/ubcmtp.c @@ -309,6 +309,10 @@ static const struct ubcmtp_dev ubcmtp_devices[] = { }, }; +static struct wsmouse_param ubcmtp_wsmousecfg[] = { + { WSMOUSECFG_MTBTN_MAXDIST, 0 }, /* 0: Compute a default value. */ +}; + struct ubcmtp_softc { struct device sc_dev; /* base device */ @@ -529,7 +533,8 @@
Re: wsmouse(4): Apple-like multi-touch buttons
If we consider it as a work in progress, is it a good idea then to "publish" it via wsconsctl immediately? Shouldn't we leave wsconsctl as it is until we have figured out what to do, or at least hide that new field? And, speaking of hiding, it is for a feature that's only useful for a subset of touchpads: MT-clickpads with MT-support in our kernel. How do you want to handle the cases where it is useless? And MT-clickpads without MT-support? It may raise wrong expectations. Without MT-data reasonable filtering won't be possible. On 2/8/23 00:48, Patrick Wildt wrote: > On Tue, Feb 07, 2023 at 10:07:56PM +0100, Ulf Brosziewski wrote: >> I wouldn't mind seeing such a feature in the driver, but I think there's more >> to do than counting contacts. The start of a click-and-drag gesture may >> involve >> two contacts and a button-press event, or people who place a thumb in the >> lower >> clickpad area and use it for pressing the clickpad button might leave the >> index >> finger in the main area. In both cases you probably shouldn't generate a >> middle- >> button event, and I guess it doesn't happen on MacOS, or does it? >> >> There may be various means to distinguish the gestures. The driver might >> check >> the positions and the distance of the contacts, or identify their duration, >> their initial position or the current direction and speed of movement, etc. >> >> I don't know which strategies work well and can be implemented with >> reasonable >> effort, it might not be easy to figure that out. It seems that libinput uses >> distances (see >> >> https://wayland.freedesktop.org/libinput/doc/1.22.0/clickpad-softbuttons.html >> ) as well as additional means for identifying "thumbs", but I'm not familiar >> with the details. > > Sounds like this good be something one could improve upon in-tree? The > diff already feels much better than the current default. > > Cheers, > Patrick >
Re: wsmouse(4): Apple-like multi-touch buttons
I wouldn't mind seeing such a feature in the driver, but I think there's more to do than counting contacts. The start of a click-and-drag gesture may involve two contacts and a button-press event, or people who place a thumb in the lower clickpad area and use it for pressing the clickpad button might leave the index finger in the main area. In both cases you probably shouldn't generate a middle- button event, and I guess it doesn't happen on MacOS, or does it? There may be various means to distinguish the gestures. The driver might check the positions and the distance of the contacts, or identify their duration, their initial position or the current direction and speed of movement, etc. I don't know which strategies work well and can be implemented with reasonable effort, it might not be easy to figure that out. It seems that libinput uses distances (see https://wayland.freedesktop.org/libinput/doc/1.22.0/clickpad-softbuttons.html ) as well as additional means for identifying "thumbs", but I'm not familiar with the details. On 2/7/23 14:12, Tobias Heider wrote: > On Mon, Sep 19, 2022 at 11:16:51AM +0200, Ulf Brosziewski wrote: >> Is there enough interest in this feature among OpenBSD users? I haven't >> seen many requests for it, if any. Moreover, is it a good idea to configure >> different input methods on this or that hardware just because another OS >> has different defaults? >> >> Just in case the answer to these questions turns out to be "yes", here are >> some remarks on the diff. > > I do still believe that there is interest in this feature based on the > feedback > I got from other devs. Having it available as a non-default option as > kettenis@ > said would be good enough. > > Below is a revised version of the diff that adds a new mouse.tp.mtbuttons > config > option. It can either be enabled via wsconsctl mouse.tp.mtbuttons=1 or by > adding mouse.tp.mtbuttons=1 to your /etc/wsconsctl.conf. > > ok? > > Index: sys/dev/wscons/wsconsio.h > === > RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v > retrieving revision 1.98 > diff -u -p -r1.98 wsconsio.h > --- sys/dev/wscons/wsconsio.h 15 Jul 2022 17:57:27 - 1.98 > +++ sys/dev/wscons/wsconsio.h 5 Feb 2023 15:35:39 - > @@ -319,6 +319,7 @@ enum wsmousecfg { > WSMOUSECFG_SWAPSIDES, /* invert soft-button/scroll areas */ > WSMOUSECFG_DISABLE, /* disable all output except for > clicks in the top-button area */ > + WSMOUSECFG_MTBUTTONS, /* multi-touch buttons */ > > /* >* Touchpad options > Index: sys/dev/wscons/wstpad.c > === > RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v > retrieving revision 1.31 > diff -u -p -r1.31 wstpad.c > --- sys/dev/wscons/wstpad.c 9 Jun 2022 22:17:18 - 1.31 > +++ sys/dev/wscons/wstpad.c 5 Feb 2023 15:35:39 - > @@ -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,17 @@ wstpad_softbuttons(struct wsmouseinput * > } > > 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; > + } > + } else > + tp->softbutton = wstpad_get_sbtn(input, top); > if (tp->softbutton) > *cmds |= 1 << SOFTBUTTON_DOWN; > } > @@ -1237,12 +1249,14 @@ wstpad_process_input(struct wsmouseinput > 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)); > >
Re: wsmouse(4): Apple-like multi-touch buttons
Is there enough interest in this feature among OpenBSD users? I haven't seen many requests for it, if any. Moreover, is it a good idea to configure different input methods on this or that hardware just because another OS has different defaults? Just in case the answer to these questions turns out to be "yes", here are some remarks on the diff. First, I think the initialization bug should be fixed at its origin. Currently, passing parameters to wsmouse_configure() only works with the general wsmouse parameters (WSMOUSECFG_DX_SCALE .. WSMOUSECFG_REVERSE_ SCROLLING), and a subset of the touchpad-specific ones. Changing wsmouse.c as follows will make it work with all of them: diff --git a/sys/dev/wscons/wsmouse.c b/sys/dev/wscons/wsmouse.c index c786af18208..0feae6824bb 100644 --- a/sys/dev/wscons/wsmouse.c +++ b/sys/dev/wscons/wsmouse.c @@ -1662,11 +1662,11 @@ wsmouse_configure(struct device *sc, "Initialization failed.\n"); return (-1); } + input->flags |= CONFIGURED; if (params != NULL) { if ((error = wsmouse_set_params(sc, params, nparams))) return (error); } - input->flags |= CONFIGURED; } if (IS_TOUCHPAD(input)) wsmouse_set_mode(sc, WSMOUSE_COMPAT); (We might as well remove the 'params' arguments from wsmouse_configure, and leave the call to wsmouse_set_params() to the hardware drivers; up to now, only pms changes default configurations.) Two more remarks are inline. On 9/18/22 16:42, Tobias Heider wrote: > 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 */ Even though it requires updating a line of wsconsctl code, I think the MTBUTTONS entry should be placed at
hidmt: clickpad detection
The diff below improves the way hidmt identifies clickpads, and addresses the problems described in https://marc.info/?l=openbsd-tech=165296530618617=2 and https://marc.info/?l=openbsd-tech=165980534415586=2 If devices don't report a HUD_BUTTON_TYPE property, the driver checks whether they claim to have an external left button, and if they do, hidmt doesn't treat them as clickpads. I think this part of the logic should be turned around: hidmt should treat everything as clickpad except if there is no "clickpad button" (HUP_BUTTON 1) *and* both an external left and an external right button (HUP BUTTON 2 and 3) are being reported. Touchpads without the internal button are still usable with the clickpad configuration, it does less harm to err on this side. Tests and OKs would be welcome. Index: dev/hid/hidmt.c === RCS file: /cvs/src/sys/dev/hid/hidmt.c,v retrieving revision 1.12 diff -u -p -r1.12 hidmt.c --- dev/hid/hidmt.c 9 Jul 2020 21:01:08 - 1.12 +++ dev/hid/hidmt.c 13 Sep 2022 19:31:38 - @@ -154,11 +154,13 @@ hidmt_setup(struct device *self, struct mt->sc_rep_cap, hid_feature, , NULL)) { d = hid_get_udata(rep, capsize, ); mt->sc_clickpad = (d == 0); - } else { - /* if there's not a 2nd button, this is probably a clickpad */ - if (!hid_locate(desc, dlen, HID_USAGE2(HUP_BUTTON, 2), - mt->sc_rep_input, hid_input, , NULL)) - mt->sc_clickpad = 1; + } else if (hid_locate(desc, dlen, HID_USAGE2(HUP_BUTTON, 1), + mt->sc_rep_input, hid_input, , NULL) + || !hid_locate(desc, dlen, HID_USAGE2(HUP_BUTTON, 2), + mt->sc_rep_input, hid_input, , NULL) + || !hid_locate(desc, dlen, HID_USAGE2(HUP_BUTTON, 3), + mt->sc_rep_input, hid_input, , NULL)) { + mt->sc_clickpad = 1; } /*
Re: hidmt: default to clickpad unless report says otherwise
Shouldn't the check of the button page remain in place, for identifying plain old touchpads with external buttons? Looking for the "Pad Type" feature (HUD_BUTTON_TYPE in hid.h) doesn't make much sense for these devices because the feature report is optional: "If the device has a non-button reporting digitizer surface and relies instead on external buttons only for mouse clicks, then this usage can be optionally reported." ( https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/touchpad-windows-precision-touchpad-collection ) It seems that we have, once more, a specification mess here. My quote is from the current web page, which describes the Pad Type as a three-valued feature, with value 2 indicating a "Non-Clickable" touchpad. HUT1_3_0.pdf ("HID Usage Tables") just states that "When set, the touchpad is non-depressible (pressure-pad); when clear, the touchpad is depressible (click-pad)." (p. 177) A pad type and the HUP_BUTTON 1 feature (the "clickpad button") aren't reported by the Synaptics touchpad on my Clevo N151CU, it correctly reports only HUP_BUTTON 2 (the external left button) and 3 (the external right button). On 5/19/22 15:01, joshua stein wrote: > Most Windows Precision Touchpad-style touchpads will be clickpads, > with no-button "pressure pad" style devices being the outlier. Make > clickpad the default unless the report says otherwise. > > This fixes the Framework laptop which has a PixArt touchpad with a > weird HID descriptor report which puts the button type on its own > report (so this heuristic doesn't find it) but also claims to have 3 > buttons, failing the second heuristic. If it's not setup as a > clickpad, wstpad doesn't do left/center/right button emulation > properly. > > I'm curious if this breaks anyone's laptop, especially those ones > with a touchpad that also have a separate row of buttons like some > Dells. > > > diff --git sys/dev/hid/hidmt.c sys/dev/hid/hidmt.c > index 5ca26899e50..0baf724a9da 100644 > --- sys/dev/hid/hidmt.c > +++ sys/dev/hid/hidmt.c > @@ -149,16 +149,13 @@ hidmt_setup(struct device *self, struct hidmt *mt, void > *desc, int dlen) > mt->sc_num_contacts = d; > } > > - /* find whether this is a clickpad or not */ > + /* a "pressure pad" has no buttons, so wstpad needs to know */ > + mt->sc_clickpad = 1; > if (hid_locate(desc, dlen, HID_USAGE2(HUP_DIGITIZERS, HUD_BUTTON_TYPE), > mt->sc_rep_cap, hid_feature, , NULL)) { > d = hid_get_udata(rep, capsize, ); > - mt->sc_clickpad = (d == 0); > - } else { > - /* if there's not a 2nd button, this is probably a clickpad */ > - if (!hid_locate(desc, dlen, HID_USAGE2(HUP_BUTTON, 2), > - mt->sc_rep_input, hid_input, , NULL)) > - mt->sc_clickpad = 1; > + if (d == 0x1) > + mt->sc_clickpad = 0; > } > > /* >
Re: wsmouse(4): tapping
On 5/3/22 10:03, Ulf Brosziewski wrote: > The implementation of the tapping mechanism in wsmouse(4) has a bug > concerning the transitions into the hold/drag state, see > https://marc.info/... > for details. The patch proposed in that message is obsolete. I've > been made aware that there is another problem, the transition only > works with left-button taps. > > This patch merges tap detection and the handling of hold/drag states, > which is a cleaner and more generic approach. It fixes the problems > mentioned above, and it permits a better synchronization of button > states when tap inputs and the use of hardware buttons are mixed. > > OK? > > > Index: dev/wscons/wstpad.c > === > RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v > retrieving revision 1.30 > [...] This version of the patch extends the synchronization of button states to the tapping timeouts. With this extension, even quite exotic combinations of button and tapping inputs will produce proper pairs of button-up and button-down events. OK? Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.30 diff -u -p -r1.30 wstpad.c --- dev/wscons/wstpad.c 24 Mar 2021 18:28:24 - 1.30 +++ dev/wscons/wstpad.c 6 May 2022 08:39:21 - @@ -82,18 +82,17 @@ enum tap_state { TAP_DETECT, TAP_IGNORE, TAP_LIFTED, - TAP_2ND_TOUCH, TAP_LOCKED, - TAP_NTH_TOUCH, + TAP_LOCKED_DRAG, }; enum tpad_cmd { CLEAR_MOTION_DELTAS, SOFTBUTTON_DOWN, SOFTBUTTON_UP, + TAPBUTTON_SYNC, TAPBUTTON_DOWN, TAPBUTTON_UP, - TAPBUTTON_DOUBLECLK, VSCROLL, HSCROLL, }; @@ -212,8 +211,10 @@ struct wstpad { struct { enum tap_state state; int contacts; - int centered; + int valid; + u_int pending; u_int button; + int masked; int maxdist; struct timeout to; /* parameters: */ @@ -651,6 +652,7 @@ wstpad_softbuttons(struct wsmouseinput * } } +/* Check whether the duration of t is within the tap limit. */ int wstpad_is_tap(struct wstpad *tp, struct tpad_touch *t) { @@ -675,7 +677,7 @@ wstpad_tap_filter(struct wstpad *tp, str dy = abs(t->y - t->orig.y) * tp->ratio; dist = (dx >= dy ? dx + 3 * dy / 8 : dy + 3 * dx / 8); } - tp->tap.centered = (CENTERED(t) && dist <= (tp->tap.maxdist << 12)); + tp->tap.valid = (CENTERED(t) && dist <= (tp->tap.maxdist << 12)); } @@ -694,7 +696,7 @@ wstpad_tap_touch(struct wsmouseinput *in lifted = (input->mt.sync[MTS_TOUCH] & ~input->mt.touches); FOREACHBIT(lifted, slot) { s = >tpad_touches[slot]; - if (tp->tap.state == TAP_DETECT && !tp->tap.centered) + if (tp->tap.state == TAP_DETECT && !tp->tap.valid) wstpad_tap_filter(tp, s); if (t == NULL || timespeccmp(>orig.time, >orig.time, >)) @@ -703,7 +705,7 @@ wstpad_tap_touch(struct wsmouseinput *in } else { if (tp->t->state == TOUCH_END) { t = tp->t; - if (tp->tap.state == TAP_DETECT && !tp->tap.centered) + if (tp->tap.state == TAP_DETECT && !tp->tap.valid) wstpad_tap_filter(tp, t); } } @@ -711,30 +713,31 @@ wstpad_tap_touch(struct wsmouseinput *in return (t); } +/* Determine the "tap button", keep track of whether a touch is masked. */ +u_int +wstpad_tap_button(struct wstpad *tp) +{ + int n = tp->tap.contacts - tp->contacts - 1; + + tp->tap.masked = tp->contacts; + + return (n >= 0 && n < TAP_BTNMAP_SIZE ? tp->tap.btnmap[n] : 0); +} + /* - * If each contact in a sequence of contacts that overlap in time - * is a tap, a button event may be generated when the number of - * contacts drops to zero, or to one if there is a masked touch. + * In the hold/drag state, do not mask touches if no masking was involved + * in the preceding tap gesture. */ static inline int -tap_finished(struct wstpad *tp, int nmasked) +tap_unmask(struct wstpad *tp) { - return (tp->contacts == nmasked - && (nmasked == 0 || !wstpad_is_tap(tp, tp->t))); -} - -static inline u_int -tap_btn(struct wstpad *tp, int nmasked) -{ - int n = tp->tap.contacts - nmasked; - - return (n <= TA
Re: wsmouse(4): tapping
... and this is the complete link: https://marc.info/?l=openbsd-tech=165006255922269=2 On 5/3/22 10:03, Ulf Brosziewski wrote: > The implementation of the tapping mechanism in wsmouse(4) has a bug > concerning the transitions into the hold/drag state, see > https://marc.info/... > for details. The patch proposed in that message is obsolete. I've > been made aware that there is another problem, the transition only > works with left-button taps. > > This patch merges tap detection and the handling of hold/drag states, > which is a cleaner and more generic approach. It fixes the problems > mentioned above, and it permits a better synchronization of button > states when tap inputs and the use of hardware buttons are mixed. > > OK? > > > Index: dev/wscons/wstpad.c > === > RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v > retrieving revision 1.30 > diff -u -p -r1.30 wstpad.c > --- dev/wscons/wstpad.c 24 Mar 2021 18:28:24 - 1.30 > +++ dev/wscons/wstpad.c 2 May 2022 22:17:57 - > @@ -82,18 +82,17 @@ enum tap_state { > TAP_DETECT, > TAP_IGNORE, > TAP_LIFTED, > - TAP_2ND_TOUCH, > TAP_LOCKED, > - TAP_NTH_TOUCH, > + TAP_LOCKED_DRAG, > }; > > enum tpad_cmd { > CLEAR_MOTION_DELTAS, > SOFTBUTTON_DOWN, > SOFTBUTTON_UP, > + TAPBUTTON_SYNC, > TAPBUTTON_DOWN, > TAPBUTTON_UP, > - TAPBUTTON_DOUBLECLK, > VSCROLL, > HSCROLL, > }; > @@ -212,8 +211,10 @@ struct wstpad { > struct { > enum tap_state state; > int contacts; > - int centered; > + int valid; > + u_int pending; > u_int button; > + int masked; > int maxdist; > struct timeout to; > /* parameters: */ > @@ -651,6 +652,7 @@ wstpad_softbuttons(struct wsmouseinput * > } > } > > +/* Check whether the duration of t is within the tap limit. */ > int > wstpad_is_tap(struct wstpad *tp, struct tpad_touch *t) > { > @@ -675,7 +677,7 @@ wstpad_tap_filter(struct wstpad *tp, str > dy = abs(t->y - t->orig.y) * tp->ratio; > dist = (dx >= dy ? dx + 3 * dy / 8 : dy + 3 * dx / 8); > } > - tp->tap.centered = (CENTERED(t) && dist <= (tp->tap.maxdist << 12)); > + tp->tap.valid = (CENTERED(t) && dist <= (tp->tap.maxdist << 12)); > } > > > @@ -694,7 +696,7 @@ wstpad_tap_touch(struct wsmouseinput *in > lifted = (input->mt.sync[MTS_TOUCH] & ~input->mt.touches); > FOREACHBIT(lifted, slot) { > s = >tpad_touches[slot]; > - if (tp->tap.state == TAP_DETECT && !tp->tap.centered) > + if (tp->tap.state == TAP_DETECT && !tp->tap.valid) > wstpad_tap_filter(tp, s); > if (t == NULL || timespeccmp(>orig.time, > >orig.time, >)) > @@ -703,7 +705,7 @@ wstpad_tap_touch(struct wsmouseinput *in > } else { > if (tp->t->state == TOUCH_END) { > t = tp->t; > - if (tp->tap.state == TAP_DETECT && !tp->tap.centered) > + if (tp->tap.state == TAP_DETECT && !tp->tap.valid) > wstpad_tap_filter(tp, t); > } > } > @@ -711,30 +713,31 @@ wstpad_tap_touch(struct wsmouseinput *in > return (t); > } > > -/* > - * If each contact in a sequence of contacts that overlap in time > - * is a tap, a button event may be generated when the number of > - * contacts drops to zero, or to one if there is a masked touch. > - */ > -static inline int > -tap_finished(struct wstpad *tp, int nmasked) > +/* Determine the "tap button", keep track of whether a touch is masked. */ > +static inline u_int > +tap_button(struct wstpad *tp) > { > - return (tp->contacts == nmasked > - && (nmasked == 0 || !wstpad_is_tap(tp, tp->t))); > + int n = tp->tap.contacts - tp->contacts - 1; > + > + tp->tap.masked = tp->contacts; > + > + return (n >= 0 && n < TAP_BTNMAP_SIZE ? tp->tap.btnmap[n] : 0); > } > > -static inline u_int > -tap_btn(struct wstpad *tp, int nmasked) > +/* > + * In the hold/drag state, do not mask touches if no masking was involved > + * in the preceding tap gesture. > + */ > +static inline int >
wsmouse(4): tapping
The implementation of the tapping mechanism in wsmouse(4) has a bug concerning the transitions into the hold/drag state, see https://marc.info/... for details. The patch proposed in that message is obsolete. I've been made aware that there is another problem, the transition only works with left-button taps. This patch merges tap detection and the handling of hold/drag states, which is a cleaner and more generic approach. It fixes the problems mentioned above, and it permits a better synchronization of button states when tap inputs and the use of hardware buttons are mixed. OK? Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.30 diff -u -p -r1.30 wstpad.c --- dev/wscons/wstpad.c 24 Mar 2021 18:28:24 - 1.30 +++ dev/wscons/wstpad.c 2 May 2022 22:17:57 - @@ -82,18 +82,17 @@ enum tap_state { TAP_DETECT, TAP_IGNORE, TAP_LIFTED, - TAP_2ND_TOUCH, TAP_LOCKED, - TAP_NTH_TOUCH, + TAP_LOCKED_DRAG, }; enum tpad_cmd { CLEAR_MOTION_DELTAS, SOFTBUTTON_DOWN, SOFTBUTTON_UP, + TAPBUTTON_SYNC, TAPBUTTON_DOWN, TAPBUTTON_UP, - TAPBUTTON_DOUBLECLK, VSCROLL, HSCROLL, }; @@ -212,8 +211,10 @@ struct wstpad { struct { enum tap_state state; int contacts; - int centered; + int valid; + u_int pending; u_int button; + int masked; int maxdist; struct timeout to; /* parameters: */ @@ -651,6 +652,7 @@ wstpad_softbuttons(struct wsmouseinput * } } +/* Check whether the duration of t is within the tap limit. */ int wstpad_is_tap(struct wstpad *tp, struct tpad_touch *t) { @@ -675,7 +677,7 @@ wstpad_tap_filter(struct wstpad *tp, str dy = abs(t->y - t->orig.y) * tp->ratio; dist = (dx >= dy ? dx + 3 * dy / 8 : dy + 3 * dx / 8); } - tp->tap.centered = (CENTERED(t) && dist <= (tp->tap.maxdist << 12)); + tp->tap.valid = (CENTERED(t) && dist <= (tp->tap.maxdist << 12)); } @@ -694,7 +696,7 @@ wstpad_tap_touch(struct wsmouseinput *in lifted = (input->mt.sync[MTS_TOUCH] & ~input->mt.touches); FOREACHBIT(lifted, slot) { s = >tpad_touches[slot]; - if (tp->tap.state == TAP_DETECT && !tp->tap.centered) + if (tp->tap.state == TAP_DETECT && !tp->tap.valid) wstpad_tap_filter(tp, s); if (t == NULL || timespeccmp(>orig.time, >orig.time, >)) @@ -703,7 +705,7 @@ wstpad_tap_touch(struct wsmouseinput *in } else { if (tp->t->state == TOUCH_END) { t = tp->t; - if (tp->tap.state == TAP_DETECT && !tp->tap.centered) + if (tp->tap.state == TAP_DETECT && !tp->tap.valid) wstpad_tap_filter(tp, t); } } @@ -711,30 +713,31 @@ wstpad_tap_touch(struct wsmouseinput *in return (t); } -/* - * If each contact in a sequence of contacts that overlap in time - * is a tap, a button event may be generated when the number of - * contacts drops to zero, or to one if there is a masked touch. - */ -static inline int -tap_finished(struct wstpad *tp, int nmasked) +/* Determine the "tap button", keep track of whether a touch is masked. */ +static inline u_int +tap_button(struct wstpad *tp) { - return (tp->contacts == nmasked - && (nmasked == 0 || !wstpad_is_tap(tp, tp->t))); + int n = tp->tap.contacts - tp->contacts - 1; + + tp->tap.masked = tp->contacts; + + return (n >= 0 && n < TAP_BTNMAP_SIZE ? tp->tap.btnmap[n] : 0); } -static inline u_int -tap_btn(struct wstpad *tp, int nmasked) +/* + * In the hold/drag state, do not mask touches if no masking was involved + * in the preceding tap gesture. + */ +static inline int +tap_unmask(struct wstpad *tp) { - int n = tp->tap.contacts - nmasked; - - return (n <= TAP_BTNMAP_SIZE ? tp->tap.btnmap[n - 1] : 0); + return ((tp->tap.button || tp->tap.pending) && tp->tap.masked == 0); } /* - * This handler supports one-, two-, and three-finger-taps, which - * are mapped to left-button, right-button and middle-button events, - * respectively; moreover, it supports tap-and-drag operations with + * In the default configuration, this handler maps one-, two-, and + * three-finger taps to left-button, right-button, and middle-button + * events, respectively. Setting the LOCKTIME parameter enables * "locked drags", which are finished by a timeout or a tap-to-end * gesture. */ @@ -743,140 +746,111 @@ wstpad_tap(struct wsmouseinput *input, u { struct wstpad *tp = input->tp;
wsmouse(4): tap-and-drag inputs with multiple taps
The touchpad input driver of wsmouse(4) uses a flawed shortcut for handling double taps, which has the effect that tap-and-drag inputs with multiple taps before the final contact almost never work correctly when the number of the taps is even: https://marc.info/?l=openbsd-misc=164986426617019=2 After each second tap, the driver generates a button-up and a button-down event at once, and issues a second button-up event almost immediately afterwards in order to make that work. It doesn't wait for another touch within the proper wait interval (WSMOUSECG_TAP_CLICKTIME). With this patch, the driver serializes the events properly - with an additional timeout, if necessary. A new "tap state" keeps the input handler and the timeout function in sync. Tests and OKs would be welcome. Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.30 diff -u -p -r1.30 wstpad.c --- dev/wscons/wstpad.c 24 Mar 2021 18:28:24 - 1.30 +++ dev/wscons/wstpad.c 15 Apr 2022 17:27:35 - @@ -61,7 +61,7 @@ #define TAP_LOCKTIME_DEFAULT 0 #define TAP_BTNMAP_SIZE3 -#define CLICKDELAY_MS 20 +#define CLICKDELAY_MS 10 #define FREEZE_MS 100 #define MATCHINTERVAL_MS 45 #define STOPINTERVAL_MS55 @@ -83,6 +83,7 @@ enum tap_state { TAP_IGNORE, TAP_LIFTED, TAP_2ND_TOUCH, + TAP_REPEATED, TAP_LOCKED, TAP_NTH_TOUCH, }; @@ -93,7 +94,6 @@ enum tpad_cmd { SOFTBUTTON_UP, TAPBUTTON_DOWN, TAPBUTTON_UP, - TAPBUTTON_DOUBLECLK, VSCROLL, HSCROLL, }; @@ -828,8 +828,8 @@ wstpad_tap(struct wsmouseinput *input, u case TAP_2ND_TOUCH: if (t) { if (wstpad_is_tap(tp, t)) { - *cmds |= 1 << TAPBUTTON_DOUBLECLK; - tp->tap.state = TAP_LIFTED; + *cmds |= 1 << TAPBUTTON_UP; + tp->tap.state = TAP_REPEATED; err = !timeout_add_msec(>tap.to, CLICKDELAY_MS); } else if (tp->contacts == nmasked) { @@ -847,6 +847,14 @@ wstpad_tap(struct wsmouseinput *input, u tp->tap.state = TAP_DETECT; } break; + case TAP_REPEATED: + if (tp->contacts > nmasked) { + timeout_del(>tap.to); + tp->tap.state = TAP_2ND_TOUCH; + if ((input->sbtn.buttons & tp->tap.button) == 0) + *cmds |= 1 << TAPBUTTON_DOWN; + } + break; case TAP_LOCKED: if (tp->contacts > nmasked) { timeout_del(>tap.to); @@ -888,19 +896,28 @@ wstpad_tap_timeout(void *p) struct wstpad *tp = input->tp; struct evq_access evq; u_int btn; - int s; + int s, ev; s = spltty(); evq.evar = *input->evar; - if (evq.evar != NULL && tp != NULL && - (tp->tap.state == TAP_LIFTED || tp->tap.state == TAP_LOCKED)) { - tp->tap.state = TAP_DETECT; - input->sbtn.buttons &= ~tp->tap.button; + if (evq.evar != NULL && tp != NULL && (tp->tap.state == TAP_LIFTED + || tp->tap.state == TAP_REPEATED || tp->tap.state == TAP_LOCKED)) { + + if (tp->tap.state != TAP_REPEATED + || (input->sbtn.buttons & tp->tap.button)) { + ev = BTN_UP_EV; + input->sbtn.buttons &= ~tp->tap.button; + tp->tap.state = TAP_DETECT; + } else { + ev = BTN_DOWN_EV; + input->sbtn.buttons |= tp->tap.button; + timeout_add_msec(>tap.to, tp->tap.clicktime); + } btn = ffs(tp->tap.button) - 1; evq.put = evq.evar->put; evq.result = EVQ_RESULT_NONE; getnanotime(); - wsmouse_evq_put(, BTN_UP_EV, btn); + wsmouse_evq_put(, ev, btn); wsmouse_evq_put(, SYNC_EV, 0); if (evq.result == EVQ_RESULT_SUCCESS) { if (input->flags & LOG_EVENTS) { @@ -928,15 +945,12 @@ wstpad_click(struct wsmouseinput *input) set_freeze_ts(tp, 0, FREEZE_MS); } -/* - * Translate the "command" bits into the sync-state of wsmouse, or into - * wscons events. - */ +/* Translate the "command" bits into the sync-state of wsmouse. */ void -wstpad_cmds(struct wsmouseinput *input, struct evq_access *evq, u_int cmds) +wstpad_cmds(struct wsmouseinput *input, u_int cmds) { struct wstpad *tp = input->tp; - u_int btn, sbtns_dn = 0, sbtns_up = 0; + u_int sbtns_dn = 0, sbtns_up = 0;
Re: wsmouse(4): make tap detection less restrictive
On 3/23/21 10:39 PM, Klemens Nanni wrote: > On Tue, Mar 23, 2021 at 09:29:09PM +0100, Ulf Brosziewski wrote: >> In order to distinguish tap gestures from short movements, the touchpad >> input driver in wsmouse checks whether the distance between the initial >> and the last position of a touch exceeds the 'maxdist' limit. Some >> touchpads provide unreliable coordinates when more than one contact is >> being made simultaneously, and in this case the filter may be too strong >> - and superfluous, because only one-finger contacts should trigger pointer >> movement; it should be safe to skip the test for multi-finger contacts >> (with Non-MT-touchpads, it isn't possible anyway). > This fixes it for me on the ThinkPad X230 but it seems to have no > effect on the Pinebook Pro where double and triple taps are barely^Wnot > recognised at all. This means we have two distinct issues here. On the Thinkpad, it's coordinates, on the Pinebook, it's the timing - as your logs have shown, there are either overlong delays between some reports, or the clock is irregular. Some events are missing. I'm afraid that there is no quick solution for the Pinebook problem. A quick web search suggests that it is not rare with this hardware; however, I haven't looked at any details yet. > > Do you want me to provide the same logs with this diff? > Anything specific order/test/action/whatever I can carry out? > I think a new log isn't necessary at present. I'll try to find out more, and if I can come up with new insights or ideas, you'll hear from me.
Re: wsconsctl.conf: mention mouse.tp.tapping in example
On 3/23/21 8:31 PM, Klemens Nanni wrote: > On Tue, Mar 23, 2021 at 05:52:10PM +0100, Ulf Brosziewski wrote: >> Thanks for the report. The logging shows that the contacts are recognized, >> so we have indeed to look at the filters of the driver. Two filters are >> relevant here: The first and essential one checks whether the duration of >> a contact exceeds the "tapping timeout" (180ms by default). The second >> one discards contacts which are "too far" away from their initial position >> (in order to distinguish a short movement sequence from a tap gesture). >> >> Could you test whether the patch below helps, at least on the Thinkpad? >> It makes the second filter less restrictive (plainly, it won't apply to >> multi-finger taps). > That diff makes double and triple taps work reliably on the Thinkpad! The patch is waiting for an OK ;-) As to the parameter number, it's 137, not 173. Sorry for that misinformation. > No idea if relevant but two finger scroll also still works, regardless > of the `moues.tp.tapping' value. > > Will try the Pinebook later. > >> As to the timeout, the "timestamp" values in the Pinebook output show some >> large gaps. Are the sequences complete? > In what sense? I copied the text as-is from `tail -f /var/log/messages' > explicitly hitting enter between each tap exercise to separate them. > > So each paste should be as they came out of the driver, without > intermangled lines from previous or next tap exercises. > >> Do you have the habit of tapping very slowly? > I'd say those are fast taps, I can hardly do them any faster; > certainly no resting on the touchpad. > > Have you observed timing-related problems on that machine? > Yes, but only with playing audio: it's too fast and high pitched, > kettenis said there might be a clock or rkiis(4) related problem. > > I couldn't come up with anything in that regard so far. > >> The four-digit numbers in the log lines represent the current low-precision >> time in milliseconds modulo 1. For example, this sequence >> [wsmouse0-in][4275] abs:636,444 mt:0x01:0 >> [wsmouse0-in][4556] mt:0x00:-1 >> would indicate that the duration of the contact was about 4556-4275 >> milliseconds, which exceeds the default timeout by far. If this happens >> often, there might be some hardware problem. >> >> You could try to mitigate a timeout problem by increasing the threshold >> to, e.g., 250ms by issuing the command >> $ doas wsconsctl mouse.param=173:250 >> but I would recommend to keep it within reasonable limits. > > $ doas wsconsctl mouse.param=173:250 > wsconsctl: invalid input (param) > >> Index: dev/wscons/wstpad.c >> === >> RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v >> retrieving revision 1.28 >> diff -u -p -r1.28 wstpad.c >> --- dev/wscons/wstpad.c 21 Mar 2021 16:20:49 - 1.28 >> +++ dev/wscons/wstpad.c 23 Mar 2021 09:09:42 - >> @@ -657,14 +657,8 @@ wstpad_is_tap(struct wstpad *tp, struct >> struct timespec ts; >> int dx, dy, dist = 0; >> >> -/* >> - * No distance limit applies if there has been more than one contact >> - * on a single-touch device. We cannot use (t->x - t->orig.x) in this >> - * case. Accumulated deltas might be an alternative, but some >> - * touchpads provide unreliable coordinates at the start or end of a >> - * multi-finger touch. >> - */ >> -if (IS_MT(tp) || tp->tap.contacts < 2) { >> +/* Try to distinguish one-finger taps from short movements. */ >> +if (tp->tap.contacts == (tp->ignore ? 2 : 1)) { >> dx = abs(t->x - t->orig.x) << 12; >> dy = abs(t->y - t->orig.y) * tp->ratio; >> dist = (dx >= dy ? dx + 3 * dy / 8 : dy + 3 * dx / 8); >>
wsmouse(4): make tap detection less restrictive
In order to distinguish tap gestures from short movements, the touchpad input driver in wsmouse checks whether the distance between the initial and the last position of a touch exceeds the 'maxdist' limit. Some touchpads provide unreliable coordinates when more than one contact is being made simultaneously, and in this case the filter may be too strong - and superfluous, because only one-finger contacts should trigger pointer movement; it should be safe to skip the test for multi-finger contacts (with Non-MT-touchpads, it isn't possible anyway). OK? Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.28 diff -u -p -r1.28 wstpad.c --- dev/wscons/wstpad.c 21 Mar 2021 16:20:49 - 1.28 +++ dev/wscons/wstpad.c 23 Mar 2021 09:09:42 - @@ -657,14 +657,8 @@ wstpad_is_tap(struct wstpad *tp, struct struct timespec ts; int dx, dy, dist = 0; - /* -* No distance limit applies if there has been more than one contact -* on a single-touch device. We cannot use (t->x - t->orig.x) in this -* case. Accumulated deltas might be an alternative, but some -* touchpads provide unreliable coordinates at the start or end of a -* multi-finger touch. -*/ - if (IS_MT(tp) || tp->tap.contacts < 2) { + /* Try to distinguish one-finger taps from short movements. */ + if (tp->tap.contacts == (tp->ignore ? 2 : 1)) { dx = abs(t->x - t->orig.x) << 12; dy = abs(t->y - t->orig.y) * tp->ratio; dist = (dx >= dy ? dx + 3 * dy / 8 : dy + 3 * dx / 8);
Re: wsconsctl.conf: mention mouse.tp.tapping in example
Thanks for the report. The logging shows that the contacts are recognized, so we have indeed to look at the filters of the driver. Two filters are relevant here: The first and essential one checks whether the duration of a contact exceeds the "tapping timeout" (180ms by default). The second one discards contacts which are "too far" away from their initial position (in order to distinguish a short movement sequence from a tap gesture). Could you test whether the patch below helps, at least on the Thinkpad? It makes the second filter less restrictive (plainly, it won't apply to multi-finger taps). As to the timeout, the "timestamp" values in the Pinebook output show some large gaps. Are the sequences complete? Do you have the habit of tapping very slowly? Have you observed timing-related problems on that machine? The four-digit numbers in the log lines represent the current low-precision time in milliseconds modulo 1. For example, this sequence [wsmouse0-in][4275] abs:636,444 mt:0x01:0 [wsmouse0-in][4556] mt:0x00:-1 would indicate that the duration of the contact was about 4556-4275 milliseconds, which exceeds the default timeout by far. If this happens often, there might be some hardware problem. You could try to mitigate a timeout problem by increasing the threshold to, e.g., 250ms by issuing the command $ doas wsconsctl mouse.param=173:250 but I would recommend to keep it within reasonable limits. On 3/23/21 12:26 PM, Klemens Nanni wrote: > On Tue, Mar 23, 2021 at 02:00:43AM +0100, Ulf Brosziewski wrote: >> On 3/22/21 10:19 PM, Klemens Nanni wrote: >>> On Mon, Mar 22, 2021 at 08:18:45PM +0100, Klemens Nanni wrote: >>>> I was too stupid to look at `wsconsctl' output (which needs root) and >>>> only looked here. >>>> >>>> Mailing the diff for my lack of better wording, plus the knob atually >>>> takes three values which I have yet to decode by reading wsconsctl(8) >>>> code. >>> The reason I had to look is because the (default) functionality does not >>> work reliably at all: >>> >>> $ doas wsconsctl mouse.tp.tapping=1 >>> mouse.tp.tapping -> 1,3,2 >>> >>> Single taps are always detected reliably and deliver left mouse button >>> clicks, but tripple and double taps for middle and right mouse button >>> clicks work are recognised so poorly that I first though multitouch >>> support wasn't there at all. >> >> Can you tell whether that's a hardware or a driver problem? > I'd assume it's a driver a problem since I get the exact same behaviour > on both a Pinebook Pro and a Thinkpad X230. > >> wsmouse logging might be helpful here. You could enable it by >> $ doas wsconsctl mouse.param=256:1,257:1 >> , make a few two-finger taps, and deactivate it with >> $ doas wsconsctl mouse.param=256:0,257:0 >> For the output: >> $ grep 'wsmouse0-' /var/log/messages > Thanks! Here goes the Pinebook Pro: > > One-finger tap: > [wsmouse0-in][4275] abs:636,444 mt:0x01:0 > [wsmouse0-in][4556] mt:0x00:-1 > > Two-finger tap: > [wsmouse0-in][0319] abs:786,516 mt:0x01:0 > [wsmouse0-in][0329] mt:0x03:0 > [wsmouse0-in][0772] abs:652,270 mt:0x02:1 > > Three-finger tap: > [wsmouse0-in][8821] abs:942,561 mt:0x01:0 > [wsmouse0-in][8831] mt:0x03:0 > [wsmouse0-in][8842] mt:0x07:0 > [wsmouse0-in][8852] abs:942,563 > [wsmouse0-in][9434] mt:0x05:0 > [wsmouse0-in][9455] abs:539,210 mt:0x04:2 > > Only the one-finger tap does a left click, the others do nothing. > > Double two-finger tap: > [wsmouse0-in][1894] abs:740,312 mt:0x01:0 > [wsmouse0-in][1894] mt:0x03:0 > [wsmouse0-in][2035] abs:554,44 mt:0x02:1 > [wsmouse0-in][2045] mt:0x00:-1 > [wsmouse0-ev][2045] 5:2 18:0 > [wsmouse0-in][2055] abs:744,344 mt:0x01:0 > [wsmouse0-ev][2055] 4:2 18:0 > [wsmouse0-in][2065] mt:0x03:0 > [wsmouse0-in][2497] abs:555,67 mt:0x02:1 > > This delivers a right-click in almost all attempts (this is the log of a > successful one). > > Touble three-finger tap: > > [wsmouse0-in][7276] abs:1114,734 mt:0x01:0 > [wsmouse0-in][7286] mt:0x03:0 > [wsmouse0-in][7296] mt:0x07:0 > [wsmouse0-in][7427] abs:769,543 mt:0x06:1 > [wsmouse0-in][7437] abs:468,284 mt:0x04:2 > [wsmouse0-in][7437] mt:0x00:-1 > [wsmouse0-ev][7437] 5:1 18:0 > [wsmouse0-in][7447] abs:476,238 mt:0x01:0 > [wsmouse0-ev][7447] 4:1 18:0 > [wsmouse0-in][7457] abs:476,239 > [wsmouse0-in][7467] mt:0x03:0 > [wsmouse0-in][7477] mt:0x07:0 > [wsmo
Re: wsconsctl.conf: mention mouse.tp.tapping in example
On 3/22/21 10:19 PM, Klemens Nanni wrote: > On Mon, Mar 22, 2021 at 08:18:45PM +0100, Klemens Nanni wrote: >> I was too stupid to look at `wsconsctl' output (which needs root) and >> only looked here. >> >> Mailing the diff for my lack of better wording, plus the knob atually >> takes three values which I have yet to decode by reading wsconsctl(8) >> code. > The reason I had to look is because the (default) functionality does not > work reliably at all: > > $ doas wsconsctl mouse.tp.tapping=1 > mouse.tp.tapping -> 1,3,2 > > Single taps are always detected reliably and deliver left mouse button > clicks, but tripple and double taps for middle and right mouse button > clicks work are recognised so poorly that I first though multitouch > support wasn't there at all. Can you tell whether that's a hardware or a driver problem? wsmouse logging might be helpful here. You could enable it by $ doas wsconsctl mouse.param=256:1,257:1 , make a few two-finger taps, and deactivate it with $ doas wsconsctl mouse.param=256:0,257:0 For the output: $ grep 'wsmouse0-' /var/log/messages > > That's not the case though: two-finger srolling just works smoothly and > pondering the touchpad with repeated double or tripple taps does > deliver respective clicks eventually - so it's really just the tap > support needing some love. > >> Anyone with a better text for the example so grepping "mouse" or "tap" >> shows me what I'm looking for? > Here's a better one. > > Feedback? OK? > > > Index: etc/examples/wsconsctl.conf > === > RCS file: /cvs/src/etc/examples/wsconsctl.conf,v > retrieving revision 1.1 > diff -u -p -r1.1 wsconsctl.conf > --- etc/examples/wsconsctl.conf 16 Jul 2014 13:21:33 - 1.1 > +++ etc/examples/wsconsctl.conf 22 Mar 2021 21:18:35 - > @@ -9,3 +9,5 @@ > #display.vblank=on # enable vertical sync blank for screen burner > #display.screen_off=6# set screen burner timeout to 60 seconds > #display.msact=off # disable screen unburn w/ mouse > +#mouse.tp.tapping=0 # 1,3,2=interpret one/three/two (simultaneous) > + # tap(s) as left/middle/right mouse button click >
wsmouse(4): release wstpad resources
wsmouse(4) doesn't free the memory allocated for the wstpad state when an external touchpad is being unplugged. This patch fixes the leak. OK? Index: wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.66 diff -u -p -r1.66 wsmouse.c --- wsmouse.c 29 Jul 2020 05:53:52 - 1.66 +++ wsmouse.c 20 Mar 2021 22:23:35 - @@ -1712,5 +1712,8 @@ wsmouse_input_reset(struct wsmouseinput void wsmouse_input_cleanup(struct wsmouseinput *input) { + if (input->tp != NULL) + wstpad_cleanup(input); + free_mt_slots(input); } Index: wsmouseinput.h === RCS file: /cvs/src/sys/dev/wscons/wsmouseinput.h,v retrieving revision 1.14 diff -u -p -r1.14 wsmouseinput.h --- wsmouseinput.h 19 Aug 2019 21:19:38 - 1.14 +++ wsmouseinput.h 20 Mar 2021 22:23:35 - @@ -193,6 +193,7 @@ void wstpad_compat_convert(struct wsmous void wstpad_init_deceleration(struct wsmouseinput *); int wstpad_configure(struct wsmouseinput *); void wstpad_reset(struct wsmouseinput *); +void wstpad_cleanup(struct wsmouseinput *); int wstpad_get_param(struct wsmouseinput *, int, int *); int wstpad_set_param(struct wsmouseinput *, int, int); Index: wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.27 diff -u -p -r1.27 wstpad.c --- wstpad.c3 Mar 2021 19:44:37 - 1.27 +++ wstpad.c20 Mar 2021 22:23:35 - @@ -1670,6 +1670,19 @@ wstpad_reset(struct wsmouseinput *input) } } +void +wstpad_cleanup(struct wsmouseinput *input) +{ + struct wstpad *tp = input->tp; + int slots; + + timeout_del(>tap.to); + slots = imax(input->mt.num_slots, 1); + free(tp->tpad_touches, M_DEVBUF, slots * sizeof(struct tpad_touch)); + free(tp, M_DEVBUF, sizeof(struct wstpad)); + input->tp = NULL; +} + int wstpad_set_param(struct wsmouseinput *input, int key, int val) {
wsconsctl(8) and ims(4): touchpad types
wsconsctl treats it as an error if a wsmouse device reports a touchpad type in the WSMOUSEIO_GTYPE call but doesn't provide touchpad configuration data. With revision 1.3 of ims.c, committed in January, ims devices show this behaviour. This patch splits the GETPARAMS call into two parts. If reading general parameters is successful but reading touchpad parameters is not, wsconsctl will silently clear the touchpad flag and continue without an error message. OK? Index: sbin/wsconsctl/mousecfg.c === RCS file: /cvs/src/sbin/wsconsctl/mousecfg.c,v retrieving revision 1.7 diff -u -p -r1.7 mousecfg.c --- mousecfg.c 2 Apr 2020 17:17:04 - 1.7 +++ mousecfg.c 2 Mar 2021 00:14:40 - @@ -162,10 +162,16 @@ mousecfg_init(int dev_fd, const char **e } parameters.params = cfg_buffer; - parameters.nparams = (cfg_touchpad ? BUFSIZE : BASESIZE); + parameters.nparams = BASESIZE; if ((err = ioctl(dev_fd, WSMOUSEIO_GETPARAMS, ))) { *errstr = "WSMOUSEIO_GETPARAMS"; return (err); + } + if (cfg_touchpad) { + parameters.params = cfg_buffer + BASESIZE; + parameters.nparams = BUFSIZE - BASESIZE; + if (ioctl(dev_fd, WSMOUSEIO_GETPARAMS, )) + cfg_touchpad = 0; } return (0);
Re: wsmouse(4): user-defined touchpad tap button map
Thanks for the good work! I think this can and should go in, OK? On 2/28/21 11:03 PM, RJ Johnson wrote: > I recently posted a patch which allowed enabling/disabling touchpad tap > gestures [1]. After a lot of back and forth with bru@, I am now ready > to submit an updated version. > > This version allows the user to map a tap gesture to a mouse button. > For mouse.tp.tapping, wsconsctl has been updated to accept a triple of > mouse buttons which corresponds to one-, two-, and three-finger tap > gestures, respectively. A tap gesture can be disabled by giving a value > of 0 for its mouse button. To not break existing configurations, > mouse.tp.tapping still accepts a single value and traslates it into a > button map which simulates the current mouse.tp.tapping behavior. > > [1] https://marc.info/?l=openbsd-tech=161310033523558=2 > > Index: sbin/wsconsctl/mousecfg.c > === > RCS file: /cvs/src/sbin/wsconsctl/mousecfg.c,v > retrieving revision 1.7 > diff -u -p -u -p -r1.7 mousecfg.c > --- sbin/wsconsctl/mousecfg.c 2 Apr 2020 17:17:04 - 1.7 > +++ sbin/wsconsctl/mousecfg.c 26 Feb 2021 07:03:47 - > @@ -40,9 +40,9 @@ > #define TP_FILTER_FIRST WSMOUSECFG_DX_MAX > #define TP_FILTER_LAST WSMOUSECFG_SMOOTHING > #define TP_FEATURES_FIRSTWSMOUSECFG_SOFTBUTTONS > -#define TP_FEATURES_LAST WSMOUSECFG_TAPPING > +#define TP_FEATURES_LAST WSMOUSECFG_DISABLE > #define TP_SETUP_FIRST WSMOUSECFG_LEFT_EDGE > -#define TP_SETUP_LASTWSMOUSECFG_TAP_LOCKTIME > +#define TP_SETUP_LASTWSMOUSECFG_TAP_THREE_BTNMAP > #define LOG_FIRSTWSMOUSECFG_LOG_INPUT > #define LOG_LAST WSMOUSECFG_LOG_EVENTS > > @@ -71,8 +71,10 @@ static const int touchpad_types[] = { > > struct wsmouse_parameters cfg_tapping = { > (struct wsmouse_param[]) { > - { WSMOUSECFG_TAPPING, 0 }, }, > - 1 > + { WSMOUSECFG_TAP_ONE_BTNMAP, 0 }, > + { WSMOUSECFG_TAP_TWO_BTNMAP, 0 }, > + { WSMOUSECFG_TAP_THREE_BTNMAP, 0 }, }, > + 3 > }; > > struct wsmouse_parameters cfg_scaling = { > @@ -262,6 +264,30 @@ set_percent(struct wsmouse_parameters *f > } > > static int > +set_tapping(struct wsmouse_parameters *field, char *tapping) > +{ > + int i1, i2, i3; > + > + switch (sscanf(tapping, "%d,%d,%d", , , )) { > + case 1: > + if (i1 == 0) /* Disable */ > + i2 = i3 = i1; > + else { /* Enable with defaults */ > + i1 = 1; /* Left click */ > + i2 = 3; /* Right click */ > + i3 = 2; /* Middle click */ > + } > + /* FALLTHROUGH */ > + case 3: > + set_value(field, WSMOUSECFG_TAP_ONE_BTNMAP, i1); > + set_value(field, WSMOUSECFG_TAP_TWO_BTNMAP, i2); > + set_value(field, WSMOUSECFG_TAP_THREE_BTNMAP, i3); > + return (0); > + } > + return (-1); > +} > + > +static int > set_edges(struct wsmouse_parameters *field, char *edges) > { > float f1, f2, f3, f4; > @@ -359,6 +385,12 @@ mousecfg_rd_field(struct wsmouse_paramet > if (field == _param) { > if (read_param(field, val)) > errx(1, "invalid input (param)"); > + return; > + } > + > + if (field == _tapping) { > + if (set_tapping(field, val)) > + errx(1, "invalid input (tapping)"); > return; > } > > Index: share/man/man4/wsmouse.4 > === > RCS file: /cvs/src/share/man/man4/wsmouse.4,v > retrieving revision 1.20 > diff -u -p -u -p -r1.20 wsmouse.4 > --- share/man/man4/wsmouse.4 4 Feb 2018 20:29:59 - 1.20 > +++ share/man/man4/wsmouse.4 26 Feb 2021 07:03:46 - > @@ -26,7 +26,7 @@ > .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > .\" SUCH DAMAGE. > .\" > -.Dd $Mdocdate: February 4 2018 $ > +.Dd $Mdocdate: February 23 2021 $ > .Dt WSMOUSE 4 > .Os > .Sh NAME > @@ -87,13 +87,24 @@ is omitted, commands apply to > .Pa /dev/wsmouse0 . > .Bl -tag -width Ds > .It Cm mouse.tp.tapping > -Setting this parameter to a non-zero value enables tap gestures. > -Contacts on the touchpad that are immediately released again > -trigger click events. > -One-finger, two-finger, and three-finger taps generate left-button, > -right-button, and middle-button clicks, respectively. > -If, within a short time interval, a second touch follows a one-finger > -tap, the button-up event is not issued until that touch ends > +Contacts on the touchpad that are immediately released again can > +be mapped to mouse button clicks. This list of three parameters > +configures these mappings, in the order: > +.Bd -literal -offset indent > +.Sm off > +.Ar one-finger , two-finger , three-finger > +.Sm on > +.Ed > +.Pp >
Re: wsmouse(4): allow independent touchpad tap gesture configuration
Hi, I wouldn't mind to see such a feature in wsmouse, but there are two things that I don't like about the patch in this form: 1) It breaks existing configurations, and 2) it may bother the users who don't care about such an extension - probably the majority of those who enable tapping. A better approach might be to extend wsconsctl in such a way that it accepts both a single value as well as a triple of values as input, and prints them in alternating formats, depending on whether all values are the same or not. (Moreover, if we add special handlers for the 'tapping' field in wsconsctrl, then it's possible to use the WSMOUSECFG_TAPPING parameter as a bit field, which might be more adequate here.) On 2/12/21 4:22 AM, RJ Johnson wrote: > Right now, there is a single master toggle for enabling all touchpad tap > gestures (mouse.tp.tapping). This patch splits this parameter into three > for independent control of one-finger, two-finger, and three-finger tap > gestures. This allows users to mix and match which gestures they prefer > for the ideal touchpad experience. > > Index: sbin/wsconsctl/mousecfg.c > === > RCS file: /cvs/src/sbin/wsconsctl/mousecfg.c,v > retrieving revision 1.7 > diff -u -p -u -p -r1.7 mousecfg.c > --- sbin/wsconsctl/mousecfg.c 2 Apr 2020 17:17:04 - 1.7 > +++ sbin/wsconsctl/mousecfg.c 9 Feb 2021 00:17:14 - > @@ -40,7 +40,7 @@ > #define TP_FILTER_FIRST WSMOUSECFG_DX_MAX > #define TP_FILTER_LAST WSMOUSECFG_SMOOTHING > #define TP_FEATURES_FIRSTWSMOUSECFG_SOFTBUTTONS > -#define TP_FEATURES_LAST WSMOUSECFG_TAPPING > +#define TP_FEATURES_LAST WSMOUSECFG_THREEFINGERTAPPING > #define TP_SETUP_FIRST WSMOUSECFG_LEFT_EDGE > #define TP_SETUP_LASTWSMOUSECFG_TAP_LOCKTIME > #define LOG_FIRSTWSMOUSECFG_LOG_INPUT > @@ -71,8 +71,10 @@ static const int touchpad_types[] = { > > struct wsmouse_parameters cfg_tapping = { > (struct wsmouse_param[]) { > - { WSMOUSECFG_TAPPING, 0 }, }, > - 1 > + { WSMOUSECFG_ONEFINGERTAPPING, 0 }, > + { WSMOUSECFG_TWOFINGERTAPPING, 0 }, > + { WSMOUSECFG_THREEFINGERTAPPING, 0 }, }, > + 3 > }; > > struct wsmouse_parameters cfg_scaling = { > Index: share/man/man4/wsmouse.4 > === > RCS file: /cvs/src/share/man/man4/wsmouse.4,v > retrieving revision 1.20 > diff -u -p -u -p -r1.20 wsmouse.4 > --- share/man/man4/wsmouse.4 4 Feb 2018 20:29:59 - 1.20 > +++ share/man/man4/wsmouse.4 9 Feb 2021 00:17:14 - > @@ -26,7 +26,7 @@ > .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > .\" SUCH DAMAGE. > .\" > -.Dd $Mdocdate: February 4 2018 $ > +.Dd $Mdocdate: February 8 2021 $ > .Dt WSMOUSE 4 > .Os > .Sh NAME > @@ -87,14 +87,22 @@ is omitted, commands apply to > .Pa /dev/wsmouse0 . > .Bl -tag -width Ds > .It Cm mouse.tp.tapping > -Setting this parameter to a non-zero value enables tap gestures. > +This list of three parameters sets the enabled tap gestures, in the order: > +.Bd -literal -offset indent > +.Sm off > +.Ar one-finger , two-finger , three-finger > +.Sm on > +.Ed > +.Pp > +Setting a parameter to a non-zero value enables that tap gesture. > Contacts on the touchpad that are immediately released again > -trigger click events. > +trigger click events only if the corresponding tap gesture is enabled. > One-finger, two-finger, and three-finger taps generate left-button, > right-button, and middle-button clicks, respectively. > If, within a short time interval, a second touch follows a one-finger > tap, the button-up event is not issued until that touch ends > .Pq Dq tap-and-drag . > +This requires the one-finger tap gesture to be enabled. > .It Cm mouse.tp.scaling > The value is a scale coefficient that is applied to the relative > coordinates. > Index: sys/dev/wscons/wsconsio.h > === > RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v > retrieving revision 1.95 > diff -u -p -u -p -r1.95 wsconsio.h > --- sys/dev/wscons/wsconsio.h 1 Oct 2020 17:28:14 - 1.95 > +++ sys/dev/wscons/wsconsio.h 9 Feb 2021 00:17:17 - > @@ -319,7 +319,9 @@ enum wsmousecfg { > WSMOUSECFG_SWAPSIDES, /* invert soft-button/scroll areas */ > WSMOUSECFG_DISABLE, /* disable all output except for > clicks in the top-button area */ > - WSMOUSECFG_TAPPING, /* enable tapping */ > + WSMOUSECFG_ONEFINGERTAPPING,/* enable one-finger tapping */ > + WSMOUSECFG_TWOFINGERTAPPING,/* enable two-finger tapping */ > + WSMOUSECFG_THREEFINGERTAPPING, /* enable three-finger tapping */ > > /* >* Touchpad options > @@ -345,7 +347,7 @@ enum wsmousecfg { > WSMOUSECFG_LOG_INPUT = 256, >
Re: Expose touchpad sensitivity in wsconsctl
Thanks for these hints. I will consider reducing the default threshold for deceleration. The current default is a compromise that is several years old, it might well be that is not ideal for the average touchpad of today. On 10/14/20 11:24 PM, Brennan Vincent wrote: > People who prefer flatter profiles are not as rare as one might think, cf > similar discussions on Libinput: > https://bugs.freedesktop.org/show_bug.cgi?id=89485 > > I found setting it to 4 gives best results (it was 16 by default) so I > wouldn't want to totally remove it either. > > Feel free to not merge this patch if you don't want it; I will not be > offended. As long as I have things working how I like on my own system :) > > On 10/14/20 5:16 PM, Ulf Brosziewski wrote: >> I'm not convinced that this makes sense. While there are still a lot of >> touchpads around that need deceleration, modern ones tend to be larger and >> more precise, so maybe we want to drop it at some point in the future? >> Given that up to now, nobody else reported a problem with it, I'd prefer >> to leave it in the set of "inofficial" configuration options. >> >> On 10/14/20 9:13 PM, Brennan Vincent wrote: >>> Oops, the subject should be "Expose touchpad _decleration threshold_ in >>> wsconsctl". Not sure why I wrote "sensitivity". >>> >>> On Wed, 14 Oct 2020, Brennan Vincent wrote: >>> >>>> diff --git sbin/wsconsctl/mouse.c sbin/wsconsctl/mouse.c >>>> index e04642dacbc..0f1594e17e0 100644 >>>> --- sbin/wsconsctl/mouse.c >>>> +++ sbin/wsconsctl/mouse.c >>>> @@ -61,6 +61,7 @@ struct field mouse_field_tab[] = { >>>> { "tp.swapsides", _swapsides, FMT_CFG, FLG_NORDBACK >>>> }, >>>> { "tp.disable", _disable, FMT_CFG, FLG_NORDBACK }, >>>> { "tp.edges", _edges, FMT_CFG, FLG_NORDBACK }, >>>> + { "tp.deceleration", _decel, FMT_CFG, FLG_NORDBACK }, >>>> { "tp.param", _param, FMT_CFG, FLG_WRONLY }, >>>> /* Add an alias. This field is valid for all wsmouse devices. */ >>>> { "param", _param, FMT_CFG, FLG_WRONLY }, >>>> diff --git sbin/wsconsctl/mousecfg.c sbin/wsconsctl/mousecfg.c >>>> index 6d52bcbfc9c..6162df5c229 100644 >>>> --- sbin/wsconsctl/mousecfg.c >>>> +++ sbin/wsconsctl/mousecfg.c >>>> @@ -109,6 +109,12 @@ struct wsmouse_parameters cfg_revscroll = { >>>> 1 >>>> }; >>>> +struct wsmouse_parameters cfg_decel = { >>>> + (struct wsmouse_param[]) { >>>> + { WSMOUSECFG_DECELERATION, 0 }, }, >>>> + 1 >>>> +}; >>>> + >>>> struct wsmouse_parameters cfg_param = { >>>> (struct wsmouse_param[]) { >>>> { -1, 0 }, >>>> diff --git sbin/wsconsctl/mousecfg.h sbin/wsconsctl/mousecfg.h >>>> index 8e99139d280..97ef153fcb3 100644 >>>> --- sbin/wsconsctl/mousecfg.h >>>> +++ sbin/wsconsctl/mousecfg.h >>>> @@ -22,6 +22,7 @@ extern struct wsmouse_parameters cfg_edges; >>>> extern struct wsmouse_parameters cfg_swapsides; >>>> extern struct wsmouse_parameters cfg_disable; >>>> extern struct wsmouse_parameters cfg_revscroll; >>>> +extern struct wsmouse_parameters cfg_decel; >>>> extern struct wsmouse_parameters cfg_param; >>>> extern int cfg_touchpad; >>>> >
Re: Expose touchpad sensitivity in wsconsctl
I'm not convinced that this makes sense. While there are still a lot of touchpads around that need deceleration, modern ones tend to be larger and more precise, so maybe we want to drop it at some point in the future? Given that up to now, nobody else reported a problem with it, I'd prefer to leave it in the set of "inofficial" configuration options. On 10/14/20 9:13 PM, Brennan Vincent wrote: > Oops, the subject should be "Expose touchpad _decleration threshold_ in > wsconsctl". Not sure why I wrote "sensitivity". > > On Wed, 14 Oct 2020, Brennan Vincent wrote: > >> >> diff --git sbin/wsconsctl/mouse.c sbin/wsconsctl/mouse.c >> index e04642dacbc..0f1594e17e0 100644 >> --- sbin/wsconsctl/mouse.c >> +++ sbin/wsconsctl/mouse.c >> @@ -61,6 +61,7 @@ struct field mouse_field_tab[] = { >> { "tp.swapsides", _swapsides, FMT_CFG, >> FLG_NORDBACK }, >> { "tp.disable", _disable, FMT_CFG,FLG_NORDBACK }, >> { "tp.edges", _edges, FMT_CFG,FLG_NORDBACK }, >> +{ "tp.deceleration",_decel, FMT_CFG,FLG_NORDBACK }, >> { "tp.param", _param, FMT_CFG,FLG_WRONLY }, >> /* Add an alias. This field is valid for all wsmouse devices. */ >> { "param", _param, FMT_CFG, >> FLG_WRONLY }, >> diff --git sbin/wsconsctl/mousecfg.c sbin/wsconsctl/mousecfg.c >> index 6d52bcbfc9c..6162df5c229 100644 >> --- sbin/wsconsctl/mousecfg.c >> +++ sbin/wsconsctl/mousecfg.c >> @@ -109,6 +109,12 @@ struct wsmouse_parameters cfg_revscroll = { >> 1 >> }; >> >> +struct wsmouse_parameters cfg_decel = { >> +(struct wsmouse_param[]) { >> +{ WSMOUSECFG_DECELERATION, 0 }, }, >> +1 >> +}; >> + >> struct wsmouse_parameters cfg_param = { >> (struct wsmouse_param[]) { >> { -1, 0 }, >> diff --git sbin/wsconsctl/mousecfg.h sbin/wsconsctl/mousecfg.h >> index 8e99139d280..97ef153fcb3 100644 >> --- sbin/wsconsctl/mousecfg.h >> +++ sbin/wsconsctl/mousecfg.h >> @@ -22,6 +22,7 @@ extern struct wsmouse_parameters cfg_edges; >> extern struct wsmouse_parameters cfg_swapsides; >> extern struct wsmouse_parameters cfg_disable; >> extern struct wsmouse_parameters cfg_revscroll; >> +extern struct wsmouse_parameters cfg_decel; >> extern struct wsmouse_parameters cfg_param; >> extern int cfg_touchpad; >> >> >
pms: ignore invalid elantech-v1 packets
This patch addresses a bug in certain Elantech-V1 touchpads, which report invalid position data at the start of single-finger touches. The patch is derived from this proposal https://marc.info/?l=openbsd-tech=159957752322249=2 This version also removes two bits of obsolete code. wsmouse ignores coordinate values when a driver signals that a contact has been released (reporting any coordinates just avoids a branch in the caller code). Sorry for coupling these issues, but opportunities for tests with v1- or v2-models are rare. OK? Index: pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.94 diff -u -p -r1.94 pms.c --- pms.c 10 Aug 2020 21:55:59 - 1.94 +++ pms.c 12 Sep 2020 21:09:03 - @@ -142,6 +142,7 @@ struct elantech_softc { int max_x, max_y; int old_x, old_y; + int initial_pkt; }; #define ELANTECH_IS_CLICKPAD(sc) (((sc)->elantech->fw_version & 0x1000) != 0) @@ -2443,15 +2444,29 @@ pms_proc_elantech_v1(struct pms_softc *s else w = (sc->packet[0] & 0xc0) >> 6; + /* +* Firmwares 0x20022 and 0x20600 have a bug, position data in the +* first two reports for single-touch contacts may be corrupt. +*/ + if (elantech->fw_version == 0x20022 || + elantech->fw_version == 0x20600) { + if (w == 1) { + if (elantech->initial_pkt < 2) { + elantech->initial_pkt++; + return; + } + } else if (elantech->initial_pkt) { + elantech->initial_pkt = 0; + } + } + /* Hardware version 1 doesn't report pressure. */ if (w) { x = ((sc->packet[1] & 0x0c) << 6) | sc->packet[2]; y = ((sc->packet[1] & 0x03) << 8) | sc->packet[3]; z = SYNAPTICS_PRESSURE; } else { - x = elantech->old_x; - y = elantech->old_y; - z = 0; + x = y = z = 0; } WSMOUSE_TOUCH(sc->sc_wsmousedev, buttons, x, y, z, w); @@ -2488,9 +2503,7 @@ pms_proc_elantech_v2(struct pms_softc *s y = (((sc->packet[0] & 0x20) << 3) | sc->packet[2]) << 2; z = SYNAPTICS_PRESSURE; } else { - x = elantech->old_x; - y = elantech->old_y; - z = 0; + x = y = z = 0; } WSMOUSE_TOUCH(sc->sc_wsmousedev, buttons, x, y, z, w);
Re: pckbc: extend the PS/2 interface tests
Meanwhile, I think this patch is not a good idea, at least not in this form. While it may correctly establish whether there is an auxiliary interface or not, it may lead to conflicts in cases where a touchpad isn't "meant" to be run in the legacy PS/2 mode. Until now, I have thought that the lack of support for the AUXECHO command is just a flaw of the firmware, but maybe it's the manufacturer's idea of "phasing out" the legacy interface? Many modern touchpads have dual connections to the system. And if they are recognized and initialized on another bus, then pckbc shouldn't attach pms in the aux slot. (Perhaps it would be nice to have some mechanism to control that, but I don't know what it should look like.) Since this weekend, I have a Clevo laptop here, and with this commit from yesterday - which adds support for newer i2c controllers - the touchpad is recognized and works well with imt(4): https://marc.info/?l=openbsd-cvs=160131811230169=2 My patch isn't necessary in this setup, on the contrary: The PS/2 interface of the touchpad is dead, and if we added that code to the kernel now, it would lead to a void pms and wsmouse node (and to timeouts when attempts are made to enable or disable pms). On 9/13/20 13:14, Ulf Brosziewski wrote: > Not all PS/2-like controllers accept the AUXECHO command, and the test that > pckbc applies in order to check for the presence of the auxiliary interface > may yield false negatives, even on newer hardware (see > https://marc.info/?l=openbsd-misc=158413132831425=2 > ). > > This patch adds an alternative test. It is applied if AUXECHO fails, and > attempts to toggle and reset the KC8_MDISABLE flag by issuing an AUXDISABLE > and AUXENABLE command, which should only succeed if there's an AUX interface. > > (The test has a branch which makes it work regardless of the initial state > of the flag; that's unnecessary at present but might be useful in a future > version.) > > OK? > > > Index: pckbc.c > === > RCS file: /cvs/src/sys/dev/ic/pckbc.c,v > retrieving revision 1.53 > diff -u -p -r1.53 pckbc.c > --- pckbc.c 30 Nov 2019 18:18:34 - 1.53 > +++ pckbc.c 13 Sep 2020 09:27:10 - > @@ -295,6 +295,32 @@ pckbc_attach_slot(struct pckbc_softc *sc > return (found); > } > > +int > +pckbc_auxcheck(struct pckbc_internal *t) > +{ > + bus_space_tag_t iot = t->t_iot; > + bus_space_handle_t ioh_c = t->t_ioh_c; > + int res = -1; > + > + if ((t->t_cmdbyte & KC8_MDISABLE) == 0) { > + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXDISABLE) > + && pckbc_get8042cmd(t)) > + res = (t->t_cmdbyte & KC8_MDISABLE); > + pckbc_send_cmd(iot, ioh_c, KBC_AUXENABLE); > + } else { > + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXENABLE) > + && pckbc_get8042cmd(t)) > + res = (~t->t_cmdbyte & KC8_MDISABLE); > + pckbc_send_cmd(iot, ioh_c, KBC_AUXDISABLE); > + } > + if (res == -1) > + printf("kbc: auxcheck: error\n"); > + else > + printf("kbc: auxcheck: %d\n", (res > 0)); > + pckbc_get8042cmd(t); > + return (res > 0); > +} > + > void > pckbc_attach(struct pckbc_softc *sc, int flags) > { > @@ -410,13 +436,17 @@ pckbc_attach(struct pckbc_softc *sc, int >*/ > DPRINTF("kbc: aux echo: %x\n", res); > t->t_haveaux = 1; > - if (pckbc_attach_slot(sc, PCKBC_AUX_SLOT, 0)) > - cmdbits |= KC8_MENABLE; > } > #ifdef PCKBCDEBUG > else > printf("kbc: aux echo test failed\n"); > #endif > + > + if (res == -1) > + t->t_haveaux = pckbc_auxcheck(t); > + > + if (t->t_haveaux && pckbc_attach_slot(sc, PCKBC_AUX_SLOT, 0)) > + cmdbits |= KC8_MENABLE; > > #if defined(__i386__) || defined(__amd64__) > if (haskbd == 0 && !ISSET(flags, PCKBCF_FORCE_KEYBOARD_PRESENT)) { >
pckbc: extend the PS/2 interface tests
Not all PS/2-like controllers accept the AUXECHO command, and the test that pckbc applies in order to check for the presence of the auxiliary interface may yield false negatives, even on newer hardware (see https://marc.info/?l=openbsd-misc=158413132831425=2 ). This patch adds an alternative test. It is applied if AUXECHO fails, and attempts to toggle and reset the KC8_MDISABLE flag by issuing an AUXDISABLE and AUXENABLE command, which should only succeed if there's an AUX interface. (The test has a branch which makes it work regardless of the initial state of the flag; that's unnecessary at present but might be useful in a future version.) OK? Index: pckbc.c === RCS file: /cvs/src/sys/dev/ic/pckbc.c,v retrieving revision 1.53 diff -u -p -r1.53 pckbc.c --- pckbc.c 30 Nov 2019 18:18:34 - 1.53 +++ pckbc.c 13 Sep 2020 09:27:10 - @@ -295,6 +295,32 @@ pckbc_attach_slot(struct pckbc_softc *sc return (found); } +int +pckbc_auxcheck(struct pckbc_internal *t) +{ + bus_space_tag_t iot = t->t_iot; + bus_space_handle_t ioh_c = t->t_ioh_c; + int res = -1; + + if ((t->t_cmdbyte & KC8_MDISABLE) == 0) { + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXDISABLE) + && pckbc_get8042cmd(t)) + res = (t->t_cmdbyte & KC8_MDISABLE); + pckbc_send_cmd(iot, ioh_c, KBC_AUXENABLE); + } else { + if (pckbc_send_cmd(iot, ioh_c, KBC_AUXENABLE) + && pckbc_get8042cmd(t)) + res = (~t->t_cmdbyte & KC8_MDISABLE); + pckbc_send_cmd(iot, ioh_c, KBC_AUXDISABLE); + } + if (res == -1) + printf("kbc: auxcheck: error\n"); + else + printf("kbc: auxcheck: %d\n", (res > 0)); + pckbc_get8042cmd(t); + return (res > 0); +} + void pckbc_attach(struct pckbc_softc *sc, int flags) { @@ -410,13 +436,17 @@ pckbc_attach(struct pckbc_softc *sc, int */ DPRINTF("kbc: aux echo: %x\n", res); t->t_haveaux = 1; - if (pckbc_attach_slot(sc, PCKBC_AUX_SLOT, 0)) - cmdbits |= KC8_MENABLE; } #ifdef PCKBCDEBUG else printf("kbc: aux echo test failed\n"); #endif + + if (res == -1) + t->t_haveaux = pckbc_auxcheck(t); + + if (t->t_haveaux && pckbc_attach_slot(sc, PCKBC_AUX_SLOT, 0)) + cmdbits |= KC8_MENABLE; #if defined(__i386__) || defined(__amd64__) if (haskbd == 0 && !ISSET(flags, PCKBCF_FORCE_KEYBOARD_PRESENT)) {
Re: Mouse movement speed
Hi John, you can slow down mice via wsconsctl, but this possibility is "hidden" in a debug and testing interface. You have seen the WSMOUSECFG_D*_SCALE parameters, two parameters in *.12 fixed-point format that determine the scaling of DX- and DY-deltas. You can read the values with $ wsconsctl mouse.param=0,1 and change them by issuing, for example, $ wsconsctl mouse.param=0:401,1:401 This should reduce the speed to 10% of its "raw" value. (You don't need the device number in the commands if they apply to wsmouse0.) wsmouse tracks remainders when scaling, and slow movements shouldn't cause noticeable rounding errors at this layer. The effects, however, will also depend on what the receiving drivers make of the coordinates. On 5/18/20 01:17, jo...@armadilloaerospace.com wrote: > I enabled wsmoused for console mouse support, but the cursor was > unusably fast. This is a high resolution, high update rate USB gaming > mouse, but it was off by well over an order of magnitude. > > I searched for a global mouse speed setting, but the only thing I > found was a "mouse.scale=0,0,0,0,0,0,0" in wsconsctl, and I couldn't > figure out how to use it even after reading all the source. > > There is an ioctl for mouse resolution, but it only applies to PS/2 > mice: > > /* Set resolution. Not applicable to all mouse types. */ > #define WSMOUSEIO_SRES _IOW('W', 33, u_int) > > The wsmousecfg values for WSMOUSECFG_DX_SCALE and WSMOUSECFG_DY_SCALE > are only used for touchpads, and are zero for mice. > > The USB mouse driver can apply scaling to mouse delta movements if it > is taken out of raw mode and the wsmouse_calibcoords are set to > reasonable values, but the comments don't seem to be correct: > > /* Set/get sample coordinates for calibration */ > #define WSMOUSE_CALIBCOORDS_MAX 16 > #define WSMOUSE_CALIBCOORDS_RESET -1 > struct wsmouse_calibcoords { > int minx, miny; /* minimum value of X/Y */ > int maxx, maxy; /* maximum value of X/Y */ > int swapxy; /* swap X/Y axis */ > int resx, resy; /* X/Y resolution */ > int samplelen; /* number of samples available or > WSMOUSE_CALIBCOORDS_RESET for raw mode */ > struct wsmouse_calibcoord { > int rawx, rawy; /* raw coordinate */ > int x, y; /* translated coordinate */ > } samples[WSMOUSE_CALIBCOORDS_MAX]; /* sample coordinates */ > }; > > No kernel code uses the samples[] array, and the samplelen field is > interpreted as raw mode when non-0, and scaled by the other values > when it is 0. > > This explains wsconsctl's mouse.rawmode and mouse.scale[7] values, > but I still couldn't set them, getting > WSMOUSEIO_SCALIBCOORDS: Invalid argument for everything I tried. > > If I called the ioctl with my own code, I could clear raw mode and > scale the mouse speed down by 10x. > > That slows the mouse down, but the behavior is terrible. > > The scaling applied in hidms_input() would be reasonable for an > absolute referenced touch screen, but it isn't for integer valued > relative motion, because information is permanently lost in the > scaling -- you can slowly move the mouse an arbitrary distance > without the pointer moving at all, as the deltas are rounded to > zero, and it is done per-axis, so slight angles turn into strictly > axial motion. > > Mouse scaling needs to maintain a fractional residual for each axis. > > The user visible behavior I want to see is: > > wsconsctl mouse.speed=0.6 > > This could overload the existing DX_SCALE value, but that may still > need to be used independently for touchpad configuration, so I > think it would be better to define a new WSMOUSECFG_SPEED > parameter with the same *.12 fixed point format as > WSMOUSECFG_DX_SCALE. > > If this sounds reasonable, I will go ahead and make a diff for the > kernel and wsconsctl to implement it that with proper residuals. > > For additional cleanup to make it net-negative-LoC, could everything > relating to struct wsmouse_calibcoords go away completely? It looks > like all the fields are now replicated as wsmousecfg parms and > handled at the wsmouse level for the touchpad case, so doing it at > the usb device or other level is redundant, as well as being broken > for relative moves. > > It would be nice to use parms for everything, also getting rid of > WSMOUSEIO_GTYPE and WSMOUSEIO_SRES. > >
pms/synaptics: use plain W-mode
This patch makes two changes in the way pms(4) handles Synaptics touchpads. It addresses problems that lead to this bug report: https://marc.info/?l=openbsd-bugs=158278943515495=2 Tests for regressions and OKs would be welcome. 1) The patched version doesn't enable the so-called "extended W-mode" (EW) anymore. In EW-mode, the touchpad sends additional packets when there is more than one contact on the device, but our driver just drops these packets, so the setup doesn't make sense. (Properly supporting EW-mode would require substantial changes in the synaptics code, and I think it's debatable whether it would be worth the trouble.) For the reason mentioned in the comment below, the "advanced gesture mode" (AGM) will be enabled as before. 2) Some touchpads that support AGM don't report it in the SYNAPTICS_EXT_CAP_ADV_GESTURE bit. Another flag must be checked for these cases, and the test has been extended accordingly. OK? Index: sys/dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.91 diff -u -p -r1.91 pms.c --- sys/dev/pckbc/pms.c 22 Jan 2020 14:52:14 - 1.91 +++ sys/dev/pckbc/pms.c 12 Mar 2020 16:28:17 - @@ -1186,25 +1186,32 @@ pms_enable_synaptics(struct pms_softc *s nitems(synaptics_params))) goto err; - printf("%s: Synaptics %s, firmware %d.%d, 0x%x 0x%x\n", + printf("%s: Synaptics %s, firmware %d.%d, " + "0x%x 0x%x 0x%x 0x%x 0x%x\n", DEVNAME(sc), (syn->ext_capabilities & SYNAPTICS_EXT_CAP_CLICKPAD ? "clickpad" : "touchpad"), SYNAPTICS_ID_MAJOR(syn->identify), SYNAPTICS_ID_MINOR(syn->identify), - syn->model, syn->ext_model); + syn->model, syn->ext_model, syn->modes, + syn->capabilities, syn->ext_capabilities); } + /* +* Enable absolute mode, plain W-mode and "advanced gesture mode" +* (AGM), if possible. AGM, which seems to be a prerequisite for the +* extended W-mode, might not always be necessary here, but at least +* some older Synaptics models do not report finger counts without it. +*/ mode = SYNAPTICS_ABSOLUTE_MODE | SYNAPTICS_HIGH_RATE; - if (SYNAPTICS_ID_MAJOR(syn->identify) >= 4) - mode |= SYNAPTICS_DISABLE_GESTURE; if (syn->capabilities & SYNAPTICS_CAP_EXTENDED) mode |= SYNAPTICS_W_MODE; + else if (SYNAPTICS_ID_MAJOR(syn->identify) >= 4) + mode |= SYNAPTICS_DISABLE_GESTURE; if (synaptics_set_mode(sc, mode)) goto err; - /* enable advanced gesture mode if supported */ - if ((syn->ext_capabilities & SYNAPTICS_EXT_CAP_ADV_GESTURE) && + if (SYNAPTICS_SUPPORTS_AGM(syn->ext_capabilities) && (pms_spec_cmd(sc, SYNAPTICS_QUE_MODEL) || pms_set_rate(sc, SYNAPTICS_CMD_SET_ADV_GESTURE_MODE))) goto err; @@ -1294,17 +1301,17 @@ pms_proc_synaptics(struct pms_softc *sc) } - if ((syn->capabilities & SYNAPTICS_CAP_PASSTHROUGH) && w == 3) { - synaptics_sec_proc(sc); + if (w == 3) { + if (syn->capabilities & SYNAPTICS_CAP_PASSTHROUGH) + synaptics_sec_proc(sc); return; } if ((sc->sc_dev_enable & PMS_DEV_PRIMARY) == 0) return; - /* XXX ignore advanced gesture packet, not yet supported */ - if ((syn->ext_capabilities & SYNAPTICS_EXT_CAP_ADV_GESTURE) && w == 2) - return; + if (w == 2) + return; /* EW-mode packets are not expected here. */ x = ((sc->packet[3] & 0x10) << 8) | ((sc->packet[1] & 0x0f) << 8) | sc->packet[4]; Index: sys/dev/pckbc/pmsreg.h === RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v retrieving revision 1.17 diff -u -p -r1.17 pmsreg.h --- sys/dev/pckbc/pmsreg.h 20 Sep 2019 21:21:47 - 1.17 +++ sys/dev/pckbc/pmsreg.h 12 Mar 2020 16:28:17 - @@ -140,7 +140,11 @@ #define SYNAPTICS_EXT_CAP_ADV_GESTURE (1 << 19) #define SYNAPTICS_EXT_CAP_MAX_COORDS (1 << 17) #define SYNAPTICS_EXT_CAP_MIN_COORDS (1 << 13) +#define SYNAPTICS_EXT_CAP_REPORTS_V(1 << 11) #define SYNAPTICS_EXT_CAP_CLICKPAD_2BTN(1 << 8) + +#define SYNAPTICS_SUPPORTS_AGM(extcaps) (extcaps & \ +(SYNAPTICS_EXT_CAP_ADV_GESTURE | SYNAPTICS_EXT_CAP_REPORTS_V)) /* Coordinate Limits */ #define SYNAPTICS_X_LIMIT(d) d) & 0xff) >> 11) | \
pms(4): disabling extended protocols
This patch adds a device configuration flag to pms. It disables the protocol lookup - which leaves touchpads in mouse emulation mode and may be useful for diagnostic purposes and as a workaround for protocol errors. OK? Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.89 diff -u -p -r1.89 pms.c --- dev/pckbc/pms.c 19 Aug 2019 21:08:26 - 1.89 +++ dev/pckbc/pms.c 16 Sep 2019 14:03:59 - @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -543,16 +544,19 @@ pms_dev_disable(struct pms_softc *sc) void pms_protocol_lookup(struct pms_softc *sc) { - int i; + int i, cf_flags; sc->protocol = _protocols[0]; - for (i = 1; i < nitems(pms_protocols); i++) { - pms_reset(sc); - if (pms_protocols[i].enable(sc)) { - sc->protocol = _protocols[i]; - break; + + cf_flags = sc->sc_dev.dv_cfdata->cf_flags; + if ((cf_flags & PMSCF_DISABLE_EXTENDED_PROTOCOLS) == 0) + for (i = 1; i < nitems(pms_protocols); i++) { + pms_reset(sc); + if (pms_protocols[i].enable(sc)) { + sc->protocol = _protocols[i]; + break; + } } - } DPRINTF("%s: protocol type %d\n", DEVNAME(sc), sc->protocol->type); } Index: dev/pckbc/pmsvar.h === RCS file: dev/pckbc/pmsvar.h diff -N dev/pckbc/pmsvar.h --- /dev/null 1 Jan 1970 00:00:00 - +++ dev/pckbc/pmsvar.h 16 Sep 2019 14:03:59 - @@ -0,0 +1,3 @@ +/* $OpenBSD$ */ + +#define PMSCF_DISABLE_EXTENDED_PROTOCOLS 0x01
wsmouse(4): reverse scroll directions
With the introduction of precision scrolling, it is no longer possible to reverse scroll directions for touchpads by means of button mappings in X. This patch adds a configuration option to wsmouse and a boolean field named wsmouse*.reverse_scrolling to wsconsctl. The option is valid for both mice and touchpads; if it has a non-zero value, wsmouse inverts the sign of the values of wheel events and of the scroll events generated by touchpads. Apple has made the inverted mapping popular as "natural scrolling", and some people may even attribute the opposite meaning to the field name. However, I couldn't persuade myself to declare that the classical way of scrolling is less "natural". OK? Index: sys/dev/wscons/wsconsio.h === RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v retrieving revision 1.91 diff -u -p -r1.91 wsconsio.h --- sys/dev/wscons/wsconsio.h 24 Mar 2019 17:55:39 - 1.91 +++ sys/dev/wscons/wsconsio.h 18 Aug 2019 17:47:39 - @@ -292,6 +292,8 @@ enum wsmousecfg { WSMOUSECFG_SWAPXY, /* swap X- and Y-axis */ WSMOUSECFG_X_INV, /* map absolute coordinate X to (INV - X) */ WSMOUSECFG_Y_INV, /* map absolute coordinate Y to (INV - Y) */ + WSMOUSECFG_REVERSE_SCROLLING, + /* reverse scroll directions */ /* * Coordinate handling, applying only in WSMOUSE_COMPAT mode. @@ -343,7 +345,7 @@ enum wsmousecfg { WSMOUSECFG_LOG_INPUT = 256, WSMOUSECFG_LOG_EVENTS, }; -#define WSMOUSECFG_MAX 38 /* max size of param array per ioctl */ +#define WSMOUSECFG_MAX 39 /* max size of param array per ioctl */ struct wsmouse_param { enum wsmousecfg key; Index: sys/dev/wscons/wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.55 diff -u -p -r1.55 wsmouse.c --- sys/dev/wscons/wsmouse.c24 May 2019 06:05:38 - 1.55 +++ sys/dev/wscons/wsmouse.c18 Aug 2019 17:47:39 - @@ -1018,7 +1018,7 @@ wsmouse_motion_sync(struct wsmouseinput struct motion_state *motion = >motion; struct axis_filter *h = >filter.h; struct axis_filter *v = >filter.v; - int x, y, dx, dy; + int x, y, dx, dy, dz, dw; if (motion->sync & SYNC_DELTAS) { dx = h->inv ? -motion->dx : motion->dx; @@ -1032,16 +1032,20 @@ wsmouse_motion_sync(struct wsmouseinput if (dy) wsmouse_evq_put(evq, DELTA_Y_EV(input), dy); if (motion->dz) { + dz = (input->flags & REVERSE_SCROLLING) + ? -motion->dz : motion->dz; if (IS_TOUCHPAD(input)) - wsmouse_evq_put(evq, VSCROLL_EV, motion->dz); + wsmouse_evq_put(evq, VSCROLL_EV, dz); else - wsmouse_evq_put(evq, DELTA_Z_EV, motion->dz); + wsmouse_evq_put(evq, DELTA_Z_EV, dz); } if (motion->dw) { + dw = (input->flags & REVERSE_SCROLLING) + ? -motion->dw : motion->dw; if (IS_TOUCHPAD(input)) - wsmouse_evq_put(evq, HSCROLL_EV, motion->dw); + wsmouse_evq_put(evq, HSCROLL_EV, dw); else - wsmouse_evq_put(evq, DELTA_W_EV, motion->dw); + wsmouse_evq_put(evq, DELTA_W_EV, dw); } } if (motion->sync & SYNC_POSITION) { @@ -1471,6 +1475,9 @@ wsmouse_get_params(struct device *sc, case WSMOUSECFG_Y_INV: params[i].value = input->filter.v.inv; break; + case WSMOUSECFG_REVERSE_SCROLLING: + params[i].value = !!(input->flags & REVERSE_SCROLLING); + break; case WSMOUSECFG_DX_MAX: params[i].value = input->filter.h.dmax; break; @@ -1560,6 +1567,12 @@ wsmouse_set_params(struct device *sc, break; case WSMOUSECFG_Y_INV: input->filter.v.inv = val; + break; + case WSMOUSECFG_REVERSE_SCROLLING: + if (val) + input->flags |= REVERSE_SCROLLING; + else + input->flags &= ~REVERSE_SCROLLING; break; case WSMOUSECFG_DX_MAX: input->filter.h.dmax = val; Index: sys/dev/wscons/wsmouseinput.h === RCS file: /cvs/src/sys/dev/wscons/wsmouseinput.h,v
pms(4): elantech-v4 detection
With this patch, pms recognizes all elantech-v4 touchpads (see https://marc.info/?l=openbsd-tech=156554256223597=2 ). Some models may have external hardware buttons, they are identified by checking a flag in the firmware version number. OK? Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.88 diff -u -p -r1.88 pms.c --- dev/pckbc/pms.c 26 Jan 2019 11:57:21 - 1.88 +++ dev/pckbc/pms.c 13 Aug 2019 21:46:49 - @@ -143,6 +143,7 @@ struct elantech_softc { int max_x, max_y; int old_x, old_y; }; +#define ELANTECH_IS_CLICKPAD(sc) (((sc)->elantech->fw_version & 0x1000) != 0) struct pms_softc { /* driver status information */ struct device sc_dev; @@ -1945,9 +1946,7 @@ elantech_get_hwinfo_v4(struct pms_softc if (synaptics_query(sc, ELANTECH_QUE_FW_VER, _version)) return (-1); - if ((fw_version & 0x0f) >> 16 != 6 - && (fw_version & 0x0f) >> 16 != 8 - && (fw_version & 0x0f) >> 16 != 15) + if ((fw_version & 0x0f) >> 16 < 6) return (-1); elantech->fw_version = fw_version; @@ -1975,7 +1974,8 @@ elantech_get_hwinfo_v4(struct pms_softc elantech->flags |= ELANTECH_F_TRACKPOINT; hw->type = WSMOUSE_TYPE_ELANTECH; - hw->hw_type = WSMOUSEHW_CLICKPAD; + hw->hw_type = (ELANTECH_IS_CLICKPAD(sc) + ? WSMOUSEHW_CLICKPAD : WSMOUSEHW_TOUCHPAD); hw->mt_slots = ELANTECH_MAX_FINGERS; elantech->width = hw->x_max / (capabilities[1] - 1); @@ -2179,8 +2179,9 @@ pms_enable_elantech_v4(struct pms_softc goto err; } - printf("%s: Elantech Clickpad, version %d, firmware 0x%x\n", - DEVNAME(sc), 4, sc->elantech->fw_version); + printf("%s: Elantech %s, version 4, firmware 0x%x\n", + DEVNAME(sc), (ELANTECH_IS_CLICKPAD(sc) ? "Clickpad" + : "Touchpad"), sc->elantech->fw_version); if (sc->elantech->flags & ELANTECH_F_TRACKPOINT) { a.accessops = _sec_accessops;
Re: pms: add extra ic type for elantech ps/2 touchpads
Hi Alexander, thanks for these hints and the diff. I think if we add those ic types, pms should also identify the models with hardware buttons properly (not all v4 models are clickpads). This looks like a trivial extension, I will propose a patch soon. On 8/11/19 6:55 PM, Alexander Cronheim wrote: > A little more information after looking around a bit. > > The linux [1] and freebsd [2] drivers accept all elantech touchpads > with ic types from 6 up to 15 as using the v4 protocol. > > The following patch extends the accepted ic types to that > range (from the current set consisting of 6, 8, and 15). > > I cannot, however, test touchpads with ic types other than 13. > > 1. > https://github.com/torvalds/linux/commit/10d900303f1c3a821eb0bef4e7b7ece16768fba4#diff-e91bc4802c6797fe9acbdca0ed240be9 > 2. > https://github.com/freebsd/freebsd/commit/8b5fc46c359e276d4545b531a3d3eb15762d1783#diff-fac99891d1c5da0f566dbcc68ba62b22 > > Index: pms.c > === > RCS file: /cvs/src/sys/dev/pckbc/pms.c,v > retrieving revision 1.88 > diff -u -p -r1.88 pms.c > --- pms.c 26 Jan 2019 11:57:21 - 1.88 > +++ pms.c 11 Aug 2019 16:36:30 - > @@ -1945,9 +1945,7 @@ elantech_get_hwinfo_v4(struct pms_softc > if (synaptics_query(sc, ELANTECH_QUE_FW_VER, _version)) > return (-1); > > - if ((fw_version & 0x0f) >> 16 != 6 > - && (fw_version & 0x0f) >> 16 != 8 > - && (fw_version & 0x0f) >> 16 != 15) > + if ((fw_version & 0x0f) >> 16 < 6) > return (-1); > > elantech->fw_version = fw_version; > >
precision scrolling again
This is an updated version of the diff for precision scrolling. It fixes a bug of the first one (which didn't check the synchronization state properly), and it improves the filtering (when a scroll gesture stops and the fingers remain on the touchpad, the first version could too easily generate events for the wrong axis). OK? Or should we wait until 6.5 is through? Index: dev/wscons/wsconsio.h === RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v retrieving revision 1.90 diff -u -p -r1.90 wsconsio.h --- dev/wscons/wsconsio.h 10 Nov 2018 14:27:51 - 1.90 +++ dev/wscons/wsconsio.h 22 Mar 2019 22:02:14 - @@ -112,6 +112,12 @@ struct wscons_event { #defineWSCONS_EVENT_TOUCH_RESET25 /* (no value) */ /* + * Precision Scrolling + */ +#define WSCONS_EVENT_HSCROLL 26 /* dx * 4096 / scroll_unit */ +#define WSCONS_EVENT_VSCROLL 27 /* dy * 4096 / scroll_unit */ + +/* * Keyboard ioctls (0 - 31) */ Index: dev/wscons/wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.51 diff -u -p -r1.51 wsmouse.c --- dev/wscons/wsmouse.c19 Feb 2019 07:01:02 - 1.51 +++ dev/wscons/wsmouse.c22 Mar 2019 22:02:14 - @@ -1034,10 +1034,18 @@ wsmouse_motion_sync(struct wsmouseinput wsmouse_evq_put(evq, DELTA_X_EV(input), dx); if (dy) wsmouse_evq_put(evq, DELTA_Y_EV(input), dy); - if (motion->dz) - wsmouse_evq_put(evq, DELTA_Z_EV, motion->dz); - if (motion->dw) - wsmouse_evq_put(evq, DELTA_W_EV, motion->dw); + if (motion->dz) { + if (IS_TOUCHPAD(input)) + wsmouse_evq_put(evq, VSCROLL_EV, motion->dz); + else + wsmouse_evq_put(evq, DELTA_Z_EV, motion->dz); + } + if (motion->dw) { + if (IS_TOUCHPAD(input)) + wsmouse_evq_put(evq, HSCROLL_EV, motion->dw); + else + wsmouse_evq_put(evq, DELTA_W_EV, motion->dw); + } } if (motion->sync & SYNC_POSITION) { if (motion->sync & SYNC_X) { Index: dev/wscons/wsmouseinput.h === RCS file: /cvs/src/sys/dev/wscons/wsmouseinput.h,v retrieving revision 1.12 diff -u -p -r1.12 wsmouseinput.h --- dev/wscons/wsmouseinput.h 10 Nov 2018 14:27:51 - 1.12 +++ dev/wscons/wsmouseinput.h 22 Mar 2019 22:02:14 - @@ -210,6 +210,8 @@ int wstpad_set_param(struct wsmouseinput WSCONS_EVENT_MOUSE_ABSOLUTE_X : WSCONS_EVENT_MOUSE_ABSOLUTE_Y) #define DELTA_Z_EV WSCONS_EVENT_MOUSE_DELTA_Z #define DELTA_W_EV WSCONS_EVENT_MOUSE_DELTA_W +#define VSCROLL_EV WSCONS_EVENT_VSCROLL +#define HSCROLL_EV WSCONS_EVENT_HSCROLL #define ABS_Z_EV WSCONS_EVENT_TOUCH_PRESSURE #define ABS_W_EV WSCONS_EVENT_TOUCH_CONTACTS #define BTN_DOWN_EVWSCONS_EVENT_MOUSE_DOWN Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.22 diff -u -p -r1.22 wstpad.c --- dev/wscons/wstpad.c 29 Dec 2018 21:03:58 - 1.22 +++ dev/wscons/wstpad.c 22 Mar 2019 22:02:15 - @@ -167,8 +167,6 @@ struct wstpad { u_int mtcycle; u_int ignore; - int dx; - int dy; int contacts; int prev_contacts; u_int btns; @@ -223,12 +221,11 @@ struct wstpad { } tap; struct { - int acc_dx; - int acc_dy; int dz; int dw; int hdist; int vdist; + int mag; } scroll; }; @@ -435,8 +432,8 @@ set_freeze_ts(struct wstpad *tp, int sec /* Return TRUE if two-finger- or edge-scrolling would be valid. */ -static inline int -chk_scroll_state(struct wsmouseinput *input) +int +wstpad_scroll_coords(struct wsmouseinput *input, int *dx, int *dy) { struct wstpad *tp = input->tp; @@ -445,44 +442,68 @@ chk_scroll_state(struct wsmouseinput *in tp->scroll.dw = 0; return (0); } + if ((input->motion.sync & SYNC_POSITION) == 0) + return (0); /* * Try to exclude accidental scroll events by checking whether the * pointer-controlling touch is stable. The check, which may cause * a short delay, is only applied initially, a touch that stops and * resumes scrolling is not affected. */ - if (tp->scroll.dz || tp->scroll.dw || wstpad_is_stable(input, tp->t)) - return (tp->dx || tp->dy); +
Re: wscons: precision scrolling
Hi Joshua, could you make a test with the updated diff below and check whether the scroll speed is normal? (There are no changes in ws, it's just the kernel part). On 3/16/19 4:16 PM, joshua stein wrote: > On Thu, 14 Mar 2019 at 00:48:33 +0100, Ulf Brosziewski wrote: >> Much too fast? I'm a bit surprised. In my tests, the new method was >> generally somewhat slower than the old one (and I haven't changed the >> "scroll units"). How did you test it? Which hardware and which applications >> did you use? > > This is with an imt touchpad: > >ihidev0 at iic1 addr 0x15 irq 109 (polling), vendor 0x4f3 product > 0x3056, ELAN2201 >ihidev0: 93 report ids >imt0 at ihidev0: clickpad, 5 contacts >wsmouse0 at imt0 mux 0 > > I tested with two-finger scrolling in Firefox and Chrome with a new > user and fresh browser profiles. I loaded the same webpages with > the old wstpad code and the new, and the two-finger scrolling with > the new setup scrolls much too fast for even small finger movements > (~0.5"). > > A movement with the previous code that would trigger the > mousewheel-style scrolling of just a handful of lines causes the new > code to scroll nearly an entire screen-height of the page. > > Index: dev/wscons/wsconsio.h === RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v retrieving revision 1.90 diff -u -p -r1.90 wsconsio.h --- dev/wscons/wsconsio.h 10 Nov 2018 14:27:51 - 1.90 +++ dev/wscons/wsconsio.h 17 Mar 2019 18:23:14 - @@ -112,6 +112,12 @@ struct wscons_event { #defineWSCONS_EVENT_TOUCH_RESET25 /* (no value) */ /* + * Precision Scrolling + */ +#define WSCONS_EVENT_HSCROLL 26 /* dx * 4096 / scroll_unit */ +#define WSCONS_EVENT_VSCROLL 27 /* dy * 4096 / scroll_unit */ + +/* * Keyboard ioctls (0 - 31) */ Index: dev/wscons/wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.51 diff -u -p -r1.51 wsmouse.c --- dev/wscons/wsmouse.c19 Feb 2019 07:01:02 - 1.51 +++ dev/wscons/wsmouse.c17 Mar 2019 18:23:14 - @@ -1034,10 +1034,18 @@ wsmouse_motion_sync(struct wsmouseinput wsmouse_evq_put(evq, DELTA_X_EV(input), dx); if (dy) wsmouse_evq_put(evq, DELTA_Y_EV(input), dy); - if (motion->dz) - wsmouse_evq_put(evq, DELTA_Z_EV, motion->dz); - if (motion->dw) - wsmouse_evq_put(evq, DELTA_W_EV, motion->dw); + if (motion->dz) { + if (IS_TOUCHPAD(input)) + wsmouse_evq_put(evq, VSCROLL_EV, motion->dz); + else + wsmouse_evq_put(evq, DELTA_Z_EV, motion->dz); + } + if (motion->dw) { + if (IS_TOUCHPAD(input)) + wsmouse_evq_put(evq, HSCROLL_EV, motion->dw); + else + wsmouse_evq_put(evq, DELTA_W_EV, motion->dw); + } } if (motion->sync & SYNC_POSITION) { if (motion->sync & SYNC_X) { Index: dev/wscons/wsmouseinput.h === RCS file: /cvs/src/sys/dev/wscons/wsmouseinput.h,v retrieving revision 1.12 diff -u -p -r1.12 wsmouseinput.h --- dev/wscons/wsmouseinput.h 10 Nov 2018 14:27:51 - 1.12 +++ dev/wscons/wsmouseinput.h 17 Mar 2019 18:23:14 - @@ -210,6 +210,8 @@ int wstpad_set_param(struct wsmouseinput WSCONS_EVENT_MOUSE_ABSOLUTE_X : WSCONS_EVENT_MOUSE_ABSOLUTE_Y) #define DELTA_Z_EV WSCONS_EVENT_MOUSE_DELTA_Z #define DELTA_W_EV WSCONS_EVENT_MOUSE_DELTA_W +#define VSCROLL_EV WSCONS_EVENT_VSCROLL +#define HSCROLL_EV WSCONS_EVENT_HSCROLL #define ABS_Z_EV WSCONS_EVENT_TOUCH_PRESSURE #define ABS_W_EV WSCONS_EVENT_TOUCH_CONTACTS #define BTN_DOWN_EVWSCONS_EVENT_MOUSE_DOWN Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.22 diff -u -p -r1.22 wstpad.c --- dev/wscons/wstpad.c 29 Dec 2018 21:03:58 - 1.22 +++ dev/wscons/wstpad.c 17 Mar 2019 18:23:14 - @@ -167,8 +167,6 @@ struct wstpad { u_int mtcycle; u_int ignore; - int dx; - int dy; int contacts; int prev_contacts; u_int btns; @@ -223,12 +221,11 @@ struct wstpad { } tap; struct { - int acc_dx; - int acc_dy; int dz; int dw; int hdist;
Re: wscons: precision scrolling
On 3/13/19 4:49 PM, Martin Pieuchot wrote: > On 13/03/19(Wed) 00:41, Ulf Brosziewski wrote: >> The standard method of scrolling in X is tailored to mouse wheels and >> proceeds in coarse steps. Wheel events are mapped to button events, and on >> receiving such an event, an application moves the view of its data by some >> fixed distance - usually the height of a line of text, or of a couple of >> lines. >> >> Version 2.1 of the X Input Protocol has introduced a more precise >> alternative. It defines additional types of motion events. In essence, >> their values represent fractions of a complete scroll unit, and newer >> applications may move their views by distances that are proportional to the >> event values. For applications that don't support this, X generates the >> standard button events whenever the values add up to the complete unit. >> >> synaptics(4) supports the newer method since long. >> >> The diffs below add the feature to ws and wstpad. The kernel part defines >> two new event types in wsconsio.h, and it adapts the scrolling functions of >> the touchpad input driver. The xenocara part adds the new "axes" and event >> handlers to ws. >> >> There is a little twist to the implementation. While synaptics(4) >> initializes the scroll axes with the scroll distance in device units, the >> constant 4096 is used in the new ws code, and event values represent the >> fraction (motion_delta / scroll_unit) in [*.12] fixed-point format. That >> way, no queries for the device- and configuration-dependent scroll unit >> are necessary. >> >> The X Input Protocol calls the method "smooth scrolling", but it seems >> that nowadays, this term is used exclusively for the rendering technique >> that displays a little animation when the document position changes, so >> "precision scrolling" might be a better choice. >> >> Tests, comments, and OKs would be welcome. > > I like it. Implementation is nice. I find the *_EV defines confusing. > Why not use the WSCONS_* defines directly, it would make easier for the > reader to find which code generates which event in a single grep. But > that's not new ;) Some of the WSCONS_EVENT_* names are very long, and too many capital letters in a C function can make me nervous ;-) Initially, I thought that more *_EV definitions would become macros. > > Do you know if it would make sense to get rid of the standard scrolling > method? Could we generate such events for all input devices? Does > other X drivers do that already or plan to do it? > I wouldn't know of any obstacle, at least, but I haven't checked that. Whether the kernel sends a DELTA_Z event or a VSCROLL event with a multiple of the base unit shouldn't make a difference in the outcome. It might even be possible to apply an acceleration scheme to wheel input (I believe Mac OS does that), but I have no idea whether that would be useful. Anyway, first we should make sure that the mechanism is sound; I'm a bit puzzled by Joshua's report and hope there will be more tests. >> Index: dev/wscons/wsconsio.h >> === >> RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v >> retrieving revision 1.90 >> diff -u -p -r1.90 wsconsio.h >> --- dev/wscons/wsconsio.h10 Nov 2018 14:27:51 - 1.90 >> +++ dev/wscons/wsconsio.h12 Mar 2019 21:55:11 - >> @@ -112,6 +112,12 @@ struct wscons_event { >> #define WSCONS_EVENT_TOUCH_RESET25 /* (no value) */ >> >> /* >> + * Precision Scrolling >> + */ >> +#define WSCONS_EVENT_HSCROLL26 /* dx * 4096 / >> scroll_unit */ >> +#define WSCONS_EVENT_VSCROLL27 /* dy * 4096 / >> scroll_unit */ >> + >> +/* >> * Keyboard ioctls (0 - 31) >> */ >> >> Index: dev/wscons/wsmouse.c >> === >> RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v >> retrieving revision 1.51 >> diff -u -p -r1.51 wsmouse.c >> --- dev/wscons/wsmouse.c 19 Feb 2019 07:01:02 - 1.51 >> +++ dev/wscons/wsmouse.c 12 Mar 2019 21:55:11 - >> @@ -1034,10 +1034,18 @@ wsmouse_motion_sync(struct wsmouseinput >> wsmouse_evq_put(evq, DELTA_X_EV(input), dx); >> if (dy) >> wsmouse_evq_put(evq, DELTA_Y_EV(input), dy); >> -if (motion->dz) >> -wsmouse_evq_put(evq, DELTA_Z_EV, motion->dz); >> -if (motion->dw) >> -
Re: wscons: precision scrolling
On 3/13/19 5:27 PM, joshua stein wrote: > On Wed, 13 Mar 2019 at 00:41:12 +0100, Ulf Brosziewski wrote: >> The standard method of scrolling in X is tailored to mouse wheels and >> proceeds in coarse steps. Wheel events are mapped to button events, and on >> receiving such an event, an application moves the view of its data by some >> fixed distance - usually the height of a line of text, or of a couple of >> lines. >> >> Version 2.1 of the X Input Protocol has introduced a more precise >> alternative. It defines additional types of motion events. In essence, >> their values represent fractions of a complete scroll unit, and newer >> applications may move their views by distances that are proportional to the >> event values. For applications that don't support this, X generates the >> standard button events whenever the values add up to the complete unit. >> >> synaptics(4) supports the newer method since long. >> >> The diffs below add the feature to ws and wstpad. The kernel part defines >> two new event types in wsconsio.h, and it adapts the scrolling functions of >> the touchpad input driver. The xenocara part adds the new "axes" and event >> handlers to ws. >> >> There is a little twist to the implementation. While synaptics(4) >> initializes the scroll axes with the scroll distance in device units, the >> constant 4096 is used in the new ws code, and event values represent the >> fraction (motion_delta / scroll_unit) in [*.12] fixed-point format. That >> way, no queries for the device- and configuration-dependent scroll unit >> are necessary. >> >> The X Input Protocol calls the method "smooth scrolling", but it seems >> that nowadays, this term is used exclusively for the rendering technique >> that displays a little animation when the document position changes, so >> "precision scrolling" might be a better choice. >> >> Tests, comments, and OKs would be welcome. > > Well done! It works on my touchpad and retains the old "chunky" > style scrolling from the mouse wheel on my external mouse. > > My only quibble is that this new style scrolling seems much too fast > by default with the default X and wscons mouse acceleration > settings. > > Much too fast? I'm a bit surprised. In my tests, the new method was generally somewhat slower than the old one (and I haven't changed the "scroll units"). How did you test it? Which hardware and which applications did you use?
wscons: precision scrolling
The standard method of scrolling in X is tailored to mouse wheels and proceeds in coarse steps. Wheel events are mapped to button events, and on receiving such an event, an application moves the view of its data by some fixed distance - usually the height of a line of text, or of a couple of lines. Version 2.1 of the X Input Protocol has introduced a more precise alternative. It defines additional types of motion events. In essence, their values represent fractions of a complete scroll unit, and newer applications may move their views by distances that are proportional to the event values. For applications that don't support this, X generates the standard button events whenever the values add up to the complete unit. synaptics(4) supports the newer method since long. The diffs below add the feature to ws and wstpad. The kernel part defines two new event types in wsconsio.h, and it adapts the scrolling functions of the touchpad input driver. The xenocara part adds the new "axes" and event handlers to ws. There is a little twist to the implementation. While synaptics(4) initializes the scroll axes with the scroll distance in device units, the constant 4096 is used in the new ws code, and event values represent the fraction (motion_delta / scroll_unit) in [*.12] fixed-point format. That way, no queries for the device- and configuration-dependent scroll unit are necessary. The X Input Protocol calls the method "smooth scrolling", but it seems that nowadays, this term is used exclusively for the rendering technique that displays a little animation when the document position changes, so "precision scrolling" might be a better choice. Tests, comments, and OKs would be welcome. Index: dev/wscons/wsconsio.h === RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v retrieving revision 1.90 diff -u -p -r1.90 wsconsio.h --- dev/wscons/wsconsio.h 10 Nov 2018 14:27:51 - 1.90 +++ dev/wscons/wsconsio.h 12 Mar 2019 21:55:11 - @@ -112,6 +112,12 @@ struct wscons_event { #defineWSCONS_EVENT_TOUCH_RESET25 /* (no value) */ /* + * Precision Scrolling + */ +#define WSCONS_EVENT_HSCROLL 26 /* dx * 4096 / scroll_unit */ +#define WSCONS_EVENT_VSCROLL 27 /* dy * 4096 / scroll_unit */ + +/* * Keyboard ioctls (0 - 31) */ Index: dev/wscons/wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.51 diff -u -p -r1.51 wsmouse.c --- dev/wscons/wsmouse.c19 Feb 2019 07:01:02 - 1.51 +++ dev/wscons/wsmouse.c12 Mar 2019 21:55:11 - @@ -1034,10 +1034,18 @@ wsmouse_motion_sync(struct wsmouseinput wsmouse_evq_put(evq, DELTA_X_EV(input), dx); if (dy) wsmouse_evq_put(evq, DELTA_Y_EV(input), dy); - if (motion->dz) - wsmouse_evq_put(evq, DELTA_Z_EV, motion->dz); - if (motion->dw) - wsmouse_evq_put(evq, DELTA_W_EV, motion->dw); + if (motion->dz) { + if (IS_TOUCHPAD(input)) + wsmouse_evq_put(evq, VSCROLL_EV, motion->dz); + else + wsmouse_evq_put(evq, DELTA_Z_EV, motion->dz); + } + if (motion->dw) { + if (IS_TOUCHPAD(input)) + wsmouse_evq_put(evq, HSCROLL_EV, motion->dw); + else + wsmouse_evq_put(evq, DELTA_W_EV, motion->dw); + } } if (motion->sync & SYNC_POSITION) { if (motion->sync & SYNC_X) { Index: dev/wscons/wsmouseinput.h === RCS file: /cvs/src/sys/dev/wscons/wsmouseinput.h,v retrieving revision 1.12 diff -u -p -r1.12 wsmouseinput.h --- dev/wscons/wsmouseinput.h 10 Nov 2018 14:27:51 - 1.12 +++ dev/wscons/wsmouseinput.h 12 Mar 2019 21:55:12 - @@ -210,6 +210,8 @@ int wstpad_set_param(struct wsmouseinput WSCONS_EVENT_MOUSE_ABSOLUTE_X : WSCONS_EVENT_MOUSE_ABSOLUTE_Y) #define DELTA_Z_EV WSCONS_EVENT_MOUSE_DELTA_Z #define DELTA_W_EV WSCONS_EVENT_MOUSE_DELTA_W +#define VSCROLL_EV WSCONS_EVENT_VSCROLL +#define HSCROLL_EV WSCONS_EVENT_HSCROLL #define ABS_Z_EV WSCONS_EVENT_TOUCH_PRESSURE #define ABS_W_EV WSCONS_EVENT_TOUCH_CONTACTS #define BTN_DOWN_EVWSCONS_EVENT_MOUSE_DOWN Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.22 diff -u -p -r1.22 wstpad.c --- dev/wscons/wstpad.c 29 Dec 2018 21:03:58 - 1.22 +++ dev/wscons/wstpad.c 12 Mar 2019 21:55:12 - @@ -167,8 +167,6 @@ struct wstpad { u_int mtcycle; u_int
Re: reverse scroll direction wstpad
On 3/5/19 7:40 PM, Ted Unangst wrote: > Ulf Brosziewski wrote: >> BTW, reverting the scroll direction is also possible by configuring >> a "ZAxisMapping" in ws(4), with an xorg.conf like this one: >> >> Section "InputClass" >> Identifier "touchpad_scroll_buttons" >> MatchIsTouchPad "true" >> Option "ZAxisMapping" "5 4" >> EndSection > > I used something like this (with xinput) a few years ago, but it stopped > working because chrome uses the new xinput extension instead of buttons. Does > that make sense? I'm not sure how wstpad would handle this. > >> As it happens, I'm just testing patches that add "precision >> scrolling" to wscons. If they make it into the tree, it would make >> sense to defer other changes in this area. > > Is that smaller jumps? As it happens, I went back to synatpics because I like > scrolling one pixel at a time. [...] Yes, it's what the X Input Protocol calls "smooth scrolling" - terminology isn't stable here - and it's the method that is also applied by synaptics(4).
Re: reverse scroll direction wstpad
Adding these options - switching the scroll direction and a customizable button map for tapping - to wsmouse and wstpad would not be a big deal. If there is interest, I could prepare a patch. I doubt, however, that both should be included in the named and visible wsmouse options of wsconsctl. While the so-called "natural scrolling" seems to be popular, customizing the tap events is a somewhat rare requirement. BTW, reverting the scroll direction is also possible by configuring a "ZAxisMapping" in ws(4), with an xorg.conf like this one: Section "InputClass" Identifier "touchpad_scroll_buttons" MatchIsTouchPad "true" Option "ZAxisMapping" "5 4" EndSection As it happens, I'm just testing patches that add "precision scrolling" to wscons. If they make it into the tree, it would make sense to defer other changes in this area. On 3/2/19 7:29 PM, Ted Unangst wrote: > One more quick hack. I have become accustomed to scroll going in the reverse > direction. Previously set a negative delta with synclient. > > Again, not sure how to connect this to wsconsctl, but here's what I'm running. > > Index: wstpad.c > === > RCS file: /home/cvs/src/sys/dev/wscons/wstpad.c,v > retrieving revision 1.22 > diff -u -p -r1.22 wstpad.c > --- wstpad.c 29 Dec 2018 21:03:58 - 1.22 > +++ wstpad.c 2 Mar 2019 07:23:43 - > @@ -935,7 +939,7 @@ wstpad_cmds(struct wsmouseinput *input, > input->motion.sync |= SYNC_DELTAS; > continue; > case VSCROLL: > - input->motion.dz = tp->scroll.dz; > + input->motion.dz = -tp->scroll.dz; > input->motion.sync |= SYNC_DELTAS; > continue; > default: > >
wstpad: speed estimates and gesture detection
My last patch to wstpad has solved some problems by introducing two new ones: The identification of thumb contacts in the bottom area of a touchpad may be too slow, and too strict under certain circumstances. This patch extends the test for stable movement. Touches moving at a medium or high speed pass it immediately, there is no delay in this case. Both thumb detection and scrolling profit from this change. Speed is estimated in the same way as for deceleration; it is not possible, of course, to calculate averages here. It is not unlikely that the center of pressure of a thumb contact changes when a second touch starts a movement quickly; the requirement that it is resting is too strict. The patch relaxes that condition (again). However, it is important that the begin of a scroll gesture is not misinterpreted. The new version will mark a contact in the bottom area as thumb if it is moving slowly while the other touch is moving fast. The "thumb" flag is cleared when a touch moves into the upper area of the touchpad surface. That's a mitigation for false positives; in my tests they occured, very rarely, on an Elantech-v4 touchpad when I started two-finger scrolling with some odd maneuvres. I couldn't reproduce them on a MacBook. OK? Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.20 diff -u -p -r1.20 wstpad.c --- dev/wscons/wstpad.c 5 Dec 2018 19:49:47 - 1.20 +++ dev/wscons/wstpad.c 15 Dec 2018 16:38:04 - @@ -63,6 +63,9 @@ #define MATCHINTERVAL_MS 45 #define STOPINTERVAL_MS55 +#define MAG_LOW(10 << 12) +#define MAG_MEDIUM (18 << 12) + enum tpad_handlers { SOFTBUTTON_HDLR, TOPBUTTON_HDLR, @@ -124,6 +127,7 @@ struct tpad_touch { int dir; struct timespec start; struct timespec match; + struct position *pos; struct { int x; int y; @@ -184,7 +188,7 @@ struct wstpad { int center; int center_left; int center_right; - int middle; + int low; } edge; struct { @@ -339,15 +343,47 @@ wstpad_set_direction(struct wstpad *tp, } } +/* + * Make a very rough, but quick estimation of the speed of a touch. + * Its distance to its previous position is scaled by factors derived + * from the average update rate and the deceleration parameter + * (filter.dclr). The unit of the result is: + * (filter.dclr / 100) device units per millisecond + * + * Magnitudes are returned in [*.12] fixed-point format. For purposes + * of filtering, they are divided into medium and high speeds + * (> MAG_MEDIUM), low speeds, and very low speeds (< MAG_LOW). + * + * The scale factors are not affected if deceleration is turned off. + */ +static inline int +magnitude(struct wsmouseinput *input, int dx, int dy) +{ + int h, v; + + h = abs(dx) * input->filter.h.mag_scale; + v = abs(dy) * input->filter.v.mag_scale; + /* Return an "alpha-max-plus-beta-min" approximation: */ + return (h >= v ? h + 3 * v / 8 : v + 3 * h / 8); +} + +/* + * Treat a touch as stable if it is moving at a medium or high speed, + * if it is moving continuously, or if it has stopped for a certain + * time span. + */ int -wstpad_is_stable(struct wstpad *tp, struct tpad_touch *t) +wstpad_is_stable(struct wsmouseinput *input, struct tpad_touch *t) { struct timespec ts; - if (t->dir >= 0) + if (t->dir >= 0) { + if (magnitude(input, t->pos->dx, t->pos->dy) > MAG_MEDIUM) + return (1); timespecsub(>match, >start, ); - else - timespecsub(>time, >start, ); + } else { + timespecsub(>tp->time, >start, ); + } return (timespeccmp(, _interval, >=)); } @@ -399,8 +435,10 @@ set_freeze_ts(struct wstpad *tp, int sec /* Return TRUE if two-finger- or edge-scrolling would be valid. */ static inline int -chk_scroll_state(struct wstpad *tp) +chk_scroll_state(struct wsmouseinput *input) { + struct wstpad *tp = input->tp; + if (tp->contacts != tp->prev_contacts || tp->btns || tp->btns_sync) { tp->scroll.dz = 0; tp->scroll.dw = 0; @@ -412,10 +450,10 @@ chk_scroll_state(struct wstpad *tp) * a short delay, is only applied initially, a touch that stops and * resumes scrolling is not affected. */ - if (!wstpad_is_stable(tp, tp->t) && !(tp->scroll.dz || tp->scroll.dw)) - return (0); + if (tp->scroll.dz || tp->scroll.dw || wstpad_is_stable(input, tp->t)) + return (tp->dx || tp->dy); - return (tp->dx || tp->dy); + return (0); } void @@ -463,7 +501,7 @@ wstpad_f2scroll(struct wsmouseinput *inp return; } -
wstpad: counting vs timing
This patch removes a loose end in the filter mechanisms of wstpad; it's related to the one that was fixed a few weeks ago. In order to determine whether a touch is moving stably, the driver counts how often its position updates match, roughly, the same direction. The method works as intended, but it's an improvisation that looks a bit hackish. Moreover, while it identifies stable movements, it does not identify touches that are resting stably (yes, that can be a problem). The "thumb detection" method can interfere with two-finger scrolling for this reason. The new version identifies stable states by means of timestamps; instead of counting matches, it simply checks for how long the current state has been valid. For recognizing resting touches properly, the direction updates now require hysteresis-filtered input, and the callers are adapted accordingly. If you are masochistic and want to test this, take a laptop with an MT touchpad and start upward scrolling with one finger in the bottom area, and the other one in the main area of the touchpad; if you do that repeatedly and somewhat sloppily, it may happen that you move the pointer. With the patch, the detection should be much more reliable. OK? Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.19 diff -u -p -r1.19 wstpad.c --- dev/wscons/wstpad.c 10 Nov 2018 14:27:51 - 1.19 +++ dev/wscons/wstpad.c 5 Dec 2018 00:09:26 - @@ -60,7 +60,8 @@ #define CLICKDELAY_MS 20 #define FREEZE_MS 100 -#define MATCHINTERVAL_MS 55 +#define MATCHINTERVAL_MS 45 +#define STOPINTERVAL_MS55 enum tpad_handlers { SOFTBUTTON_HDLR, @@ -121,8 +122,8 @@ struct tpad_touch { int x; int y; int dir; - int matches; - struct timespec stop; + struct timespec start; + struct timespec match; struct { int x; int y; @@ -226,6 +227,12 @@ struct wstpad { } scroll; }; +static const struct timespec match_interval = +{ .tv_sec = 0, .tv_nsec = MATCHINTERVAL_MS * 100 }; + +static const struct timespec stop_interval = +{ .tv_sec = 0, .tv_nsec = STOPINTERVAL_MS * 100 }; + /* * Coordinates in the wstpad struct are "normalized" device coordinates, * the orientation is left-to-right and upward. @@ -254,16 +261,11 @@ normalize_rel(struct axis_filter *filter *7|4 * 6 | 5 * - * Two direction values "match" each other if they are equal or adjacent in - * this ring. Some handlers require that a movement is "stable" and check - * the number of matches. */ /* Tangent constants in [*.12] fixed-point format: */ #define TAN_DEG_60 7094 #define TAN_DEG_30 2365 -#define STABLE 3 - #define NORTH(d) ((d) == 0 || (d) == 11) #define SOUTH(d) ((d) == 5 || (d) == 6) #define EAST(d) ((d) == 2 || (d) == 3) @@ -297,41 +299,59 @@ dircmp(int dir1, int dir2) return (diff <= 6 ? diff : 12 - diff); } +/* + * Update direction and timespec attributes for a touch. They are used to + * determine whether it is moving - or resting - stably. + * + * The callers pass touches from the current frame and the touches that are + * no longer present in the update cycle to this function. Even though this + * ensures that pairs of zero deltas do not result from stale coordinates, + * zero deltas do not reset the state immediately. A short time span - the + * "stop interval" - must pass before the state is cleared, which is + * necessary because some touchpads report intermediate stops when a touch + * is moving very slowly. + */ void wstpad_set_direction(struct wstpad *tp, struct tpad_touch *t, int dx, int dy) { int dir; - static const struct timespec interval = - { .tv_sec = 0, .tv_nsec = MATCHINTERVAL_MS * 100 }; + struct timespec ts; if (t->state != TOUCH_UPDATE) { t->dir = -1; - t->matches = 0; - } else { - dir = direction(dx, dy, tp->ratio); - if (dir >= 0) { - if (t->dir >= 0 && dircmp(t->dir, dir) <= 1) - t->matches++; - else - t->matches = 1; - t->dir = dir; - - timespecadd(>time, , >stop); + memcpy(>start, >time, sizeof(struct timespec)); + return; + } - } else if (t->dir >= 0) { - /* -* Some touchpads report intermediate zero deltas -* when a touch is moving very slowly. Keep the -* the state long enough to avoid errors. -*/ - if (timespeccmp(>time, >stop, >=)) { - t->dir = -1; -
wsmouse/wstpad: remove the strong hysteresis filter
For a while now, wsmouse activates compatibility mode for touchpads by default. There have been no complaints about wobbling pointers or unstable pointer paths. I conclude that the default filtering is sufficient and that the type of touchpad which could profit from the "strong" variant of the hysteresis filter is dying out. This patch removes it (and somewhat simplifies related code of the default method). The patch doesn't change the list of wsmouse parameters in wsconsio.h. Reading the parameter value for strong hysteresis returns 0, an attempt to set it results in an error (should someone actually stumble over the change, I'd like to know that). OK? Index: dev/wscons/wsconsio.h === RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v retrieving revision 1.89 diff -u -p -r1.89 wsconsio.h --- dev/wscons/wsconsio.h 30 Jul 2018 15:56:30 - 1.89 +++ dev/wscons/wsconsio.h 6 Nov 2018 19:03:49 - @@ -295,7 +295,8 @@ enum wsmousecfg { WSMOUSECFG_X_HYSTERESIS,/* retard value for X coordinates */ WSMOUSECFG_Y_HYSTERESIS,/* retard value for Y coordinates */ WSMOUSECFG_DECELERATION,/* threshold (distance) for deceleration */ - WSMOUSECFG_STRONG_HYSTERESIS, /* apply the filter continuously */ + WSMOUSECFG_STRONG_HYSTERESIS, /* FALSE and read-only, the fea- + ture is not supported anymore. */ WSMOUSECFG_SMOOTHING, /* smoothing factor (0-7) */ /* Index: dev/wscons/wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.45 diff -u -p -r1.45 wsmouse.c --- dev/wscons/wsmouse.c7 May 2018 21:58:42 - 1.45 +++ dev/wscons/wsmouse.c6 Nov 2018 19:03:49 - @@ -625,7 +625,10 @@ set_x(struct position *pos, int x, u_int } if ((pos->dx = x - pos->x)) { pos->x = x; - pos->acc_dx += pos->dx; + if (pos->dx > 0 == pos->acc_dx > 0) + pos->acc_dx += pos->dx; + else + pos->acc_dx = pos->dx; *sync |= mask; } } @@ -641,7 +644,10 @@ set_y(struct position *pos, int y, u_int } if ((pos->dy = y - pos->y)) { pos->y = y; - pos->acc_dy += pos->dy; + if (pos->dy > 0 == pos->acc_dy > 0) + pos->acc_dy += pos->dy; + else + pos->acc_dy = pos->dy; *sync |= mask; } } @@ -860,18 +866,6 @@ wsmouse_mt_update(struct wsmouseinput *i int wsmouse_hysteresis(struct wsmouseinput *input, struct position *pos) { - - if (!(input->filter.h.hysteresis && input->filter.v.hysteresis)) - return (0); - - if ((pos->dx > 0 && pos->dx > pos->acc_dx) - || (pos->dx < 0 && pos->dx < pos->acc_dx)) - pos->acc_dx = pos->dx; - - if ((pos->dy > 0 && pos->dy > pos->acc_dy) - || (pos->dy < 0 && pos->dy < pos->acc_dy)) - pos->acc_dy = pos->dy; - return (abs(pos->acc_dx) < input->filter.h.hysteresis && abs(pos->acc_dy) < input->filter.v.hysteresis); } @@ -1489,8 +1483,7 @@ wsmouse_get_params(struct device *sc, params[i].value = input->filter.dclr; break; case WSMOUSECFG_STRONG_HYSTERESIS: - params[i].value = - !!(input->filter.mode & STRONG_HYSTERESIS); + params[i].value = 0; /* The feature has been removed. */ break; case WSMOUSECFG_SMOOTHING: params[i].value = @@ -1569,12 +1562,6 @@ wsmouse_set_params(struct device *sc, break; case WSMOUSECFG_DY_MAX: input->filter.v.dmax = val; - break; - case WSMOUSECFG_STRONG_HYSTERESIS: - if (val) - input->filter.mode |= STRONG_HYSTERESIS; - else - input->filter.mode &= ~STRONG_HYSTERESIS; break; case WSMOUSECFG_SMOOTHING: input->filter.mode &= ~SMOOTHING_MASK; Index: dev/wscons/wsmouseinput.h === RCS file: /cvs/src/sys/dev/wscons/wsmouseinput.h,v retrieving revision 1.11 diff -u -p -r1.11 wsmouseinput.h --- dev/wscons/wsmouseinput.h 7 May 2018 21:58:42 - 1.11 +++ dev/wscons/wsmouseinput.h 6 Nov 2018 19:03:49 - @@ -167,11 +167,9 @@ struct wsmouseinput { #define LOG_INPUT (1 << 19) #define LOG_EVENTS (1 << 20) -/* filter.mode (bit 0-2: smoothing factor, bit 3: hysteresis type) */ -#define
wsmouse/wstpad: improve the scroll mechanism
The touchpad input driver includes a function that identifies "stable" movements. It is very simple, but seems to work sufficiently well with most kinds of inputs. There is an exception: some touchpads regularly report intermediate zero coordinate-deltas when a touch is moving very slowly. The filter state is cleared when it shouldn't be, which may ruin slow scrolling. This patch relaxes the filter conditions. Zero deltas only reset the state if a given time interval (55ms) has passed since the last change of the touch position. Moreover, as long as the contact count and the button state don't change, the check is skipped after scrolling has started (which makes it easier to correct a position). Any objections? Index: dev/wscons/wstpad.c === RCS file: /cvs/src/sys/dev/wscons/wstpad.c,v retrieving revision 1.17 diff -u -p -r1.17 wstpad.c --- dev/wscons/wstpad.c 7 May 2018 21:58:42 - 1.17 +++ dev/wscons/wstpad.c 4 Nov 2018 12:45:06 - @@ -60,6 +60,7 @@ #define CLICKDELAY_MS 20 #define FREEZE_MS 100 +#define MATCHINTERVAL_MS 55 enum tpad_handlers { SOFTBUTTON_HDLR, @@ -121,6 +122,7 @@ struct tpad_touch { int y; int dir; int matches; + struct timespec stop; struct { int x; int y; @@ -296,20 +298,32 @@ dircmp(int dir1, int dir2) } void -wstpad_set_direction(struct tpad_touch *t, int dx, int dy, int ratio) +wstpad_set_direction(struct wstpad *tp, struct tpad_touch *t, int dx, int dy) { int dir; + static const struct timespec interval = + { .tv_sec = 0, .tv_nsec = MATCHINTERVAL_MS * 100 }; if (t->state != TOUCH_UPDATE) { t->dir = -1; t->matches = 0; } else { - dir = direction(dx, dy, ratio); - if (t->dir >= 0 && dir >= 0 && dircmp(t->dir, dir) <= 1) - t->matches++; - else - t->matches = 1; - t->dir = dir; + dir = direction(dx, dy, tp->ratio); + if (dir >= 0) { + if (t->dir >= 0 && dircmp(t->dir, dir) <= 1) + t->matches++; + else + t->matches = 1; + t->dir = dir; + + timespecadd(>time, , >stop); + + } else if (t->dir >= 0) { + if (timespeccmp(>time, >stop, >=)) { + t->dir = -1; + t->matches = 0; + } + } } } @@ -367,6 +381,9 @@ chk_scroll_state(struct wstpad *tp) tp->scroll.dw = 0; return (0); } + if (tp->t->matches < STABLE && !(tp->scroll.dz || tp->scroll.dw)) + return (0); + return (tp->dx || tp->dy); } @@ -433,7 +450,8 @@ wstpad_f2scroll(struct wsmouseinput *inp return; if ((dx > 0 && !EAST(dir)) || (dx < 0 && !WEST(dir))) return; - if (t2->matches < imin(STABLE, tp->t->matches / 4)) + if (t2->matches < STABLE && + !(tp->scroll.dz || tp->scroll.dw)) return; centered |= CENTERED(t2); } @@ -900,7 +918,7 @@ wstpad_mt_inputs(struct wsmouseinput *in t->orig.y = t->y; memcpy(>orig.time, >time, sizeof(struct timespec)); t->flags = edge_flags(tp, t->x, t->y); - wstpad_set_direction(t, 0, 0, tp->ratio); + wstpad_set_direction(tp, t, 0, 0); } /* TOUCH_UPDATE */ @@ -928,9 +946,9 @@ wstpad_mt_inputs(struct wsmouseinput *in dy = normalize_abs(>filter.v, mts->pos.y) - t->y; t->y += dy; t->flags &= (~EDGES | edge_flags(tp, t->x, t->y)); - wstpad_set_direction(t, dx, dy, tp->ratio); + wstpad_set_direction(tp, t, dx, dy); } else if ((1 << slot) & inactive) { - wstpad_set_direction(t, 0, 0, tp->ratio); + wstpad_set_direction(tp, t, 0, 0); } } @@ -1035,7 +1053,7 @@ wstpad_touch_inputs(struct wsmouseinput t->flags &= (~EDGES | edge_flags(tp, t->x, t->y)); } - wstpad_set_direction(t, tp->dx, tp->dy, input->filter.ratio); + wstpad_set_direction(tp, t, tp->dx, tp->dy); } }
Re: ubcmtp: fix multi-finger on type4 devices, pass in proper pressure
Hi Joshua, this patch breaks ubcmtp on the MacBook Pro 8.2. There is no problem with the padding, but the pressure value is always 0, and wsmouse doesn't register any touches. I believe only type4 models fill the 'pressure' field. At least for now, it's better to use the width value (touch_major) as substitute for pressure (hidmt already does this). In case we add to wsmouse or wstpad some mechanism for palm/ thumb detection based on thresholds, this would work as well. So I would prefer: + sc->frame[contacts].pressure = + (int16_t)letoh16(finger->touch_major); Moreover, it shouldn't be necessary to set the PRESSURE_LO/PRESSURE_HI parameters in ubcmtp. Only touchpads that are too sensitive need them (if they are set, wsmouse ignores touches with lower pressure). ok bru@ for the padding part On 08/16/2018 04:51 AM, joshua stein wrote: > Type 4 devices like the MacBookPro12,1 have extra padding in between > each chunk of finger data that needs to be skipped, otherwise the > offset will be wrong and each additional finger will read as static > coordinates. This must have been overlooked when it was added to > the driver in 2015 since the first finger of data always read > properly. > > Also, we can now pass in the actual pressure data instead of having > to use a constant value just to make the synaptics driver happy > since we now have wstpad. The per-type min/max pressure values can > also be passed in when calling wsmouse_configure. > > Tested on the 2015 MacBook Pro. Tests on other Apple devices would > be appreciated. > > > Index: sys/dev/usb/ubcmtp.c > === > RCS file: /cvs/src/sys/dev/usb/ubcmtp.c,v > retrieving revision 1.18 > diff -u -p -u -p -r1.18 ubcmtp.c > --- sys/dev/usb/ubcmtp.c 30 Jul 2018 15:56:30 - 1.18 > +++ sys/dev/usb/ubcmtp.c 16 Aug 2018 02:42:11 - > @@ -118,6 +118,7 @@ struct ubcmtp_finger { > #define UBCMTP_TYPE4_TPLEN UBCMTP_TYPE4_TPOFF + UBCMTP_ALL_FINGER_SIZE > #define UBCMTP_TYPE4_TPIFACE 2 > #define UBCMTP_TYPE4_BTOFF 31 > +#define UBCMTP_TYPE4_FINGERPAD (1 * sizeof(uint16_t)) > > #define UBCMTP_FINGER_ORIENT 16384 > #define UBCMTP_SN_PRESSURE 45 > @@ -128,9 +129,6 @@ struct ubcmtp_finger { > /* Identify clickpads in ubcmtp_configure. */ > #define IS_CLICKPAD(ubcmtp_type) (ubcmtp_type != UBCMTP_TYPE1) > > -/* Use a constant, synaptics-compatible pressure value for now. */ > -#define DEFAULT_PRESSURE 40 > - > struct ubcmtp_limit { > int limit; > int min; > @@ -337,6 +335,7 @@ struct ubcmtp_softc { > int sc_tp_epaddr; /* endpoint addr */ > int tp_maxlen; /* max size of tp data */ > int tp_offset; /* finger offset into data */ > + int tp_fingerpad; /* padding between finger data > */ > uint8_t *tp_pkt; > > int bt_ifacenum;/* button interface number */ > @@ -425,6 +424,7 @@ ubcmtp_attach(struct device *parent, str > > sc->sc_udev = uaa->device; > sc->sc_status = 0; > + sc->tp_fingerpad = 0; > > if ((udd = usbd_get_device_descriptor(dev)) == NULL) { > printf("ubcmtp: failed getting device descriptor\n"); > @@ -478,6 +478,7 @@ ubcmtp_attach(struct device *parent, str > sc->tp_maxlen = UBCMTP_TYPE4_TPLEN; > sc->tp_offset = UBCMTP_TYPE4_TPOFF; > sc->tp_ifacenum = UBCMTP_TYPE4_TPIFACE; > + sc->tp_fingerpad = UBCMTP_TYPE4_FINGERPAD; > break; > } > > @@ -520,6 +521,10 @@ int > ubcmtp_configure(struct ubcmtp_softc *sc) > { > struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); > + struct wsmouse_param params[] = { > + { WSMOUSECFG_PRESSURE_LO, sc->dev_type->l_pressure.min }, > + { WSMOUSECFG_PRESSURE_HI, sc->dev_type->l_pressure.max }, > + }; > > hw->type = WSMOUSE_TYPE_TOUCHPAD; > hw->hw_type = (IS_CLICKPAD(sc->dev_type->type) > @@ -531,7 +536,7 @@ ubcmtp_configure(struct ubcmtp_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, params, 0); > } > > int > @@ -793,9 +798,9 @@ void > ubcmtp_tp_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) > { > struct ubcmtp_softc *sc = priv; > - struct ubcmtp_finger *pkt; > + struct ubcmtp_finger *finger; > u_int32_t pktlen; > - int i, s, btn, contacts, fingers; > + int off, s, btn, contacts = 0; > > if (usbd_is_dying(sc->sc_udev) || !(sc->sc_status & UBCMTP_ENABLED)) > return; > @@ -816,16 +821,19 @@ ubcmtp_tp_intr(struct usbd_xfer *xfer, v > if (sc->tp_pkt == NULL || pktlen < sc->tp_offset) >
Re: stop using WSMOUSE_TYPE_ELANTECH in other drivers
ok bru@ (but please see my comments on the second diff) On 07/27/2018 09:59 PM, joshua stein wrote: > Back when touchpad drivers were using the synaptics Xorg driver, > they had to pretend to be Elantech devices in order to get > particular packet processing. > > Since Ulf switched us to wstpad and xf86-input-ws a while ago, these > drivers can stop claiming to be WSMOUSE_TYPE_ELANTECH devices and > use a common WSMOUSE_TYPE_TOUCHPAD. > > This also makes the WSMOUSEIO_GTYPE ioctl in those drivers respond > with whatever is stored in the softc to avoid repeating ourselves > (or possibly responding incorrectly). > > There's also a corresponding xenocara diff coming after this. > > > Index: sys/dev/hid/hidmt.c > === > RCS file: /cvs/src/sys/dev/hid/hidmt.c,v > retrieving revision 1.6 > diff -u -p -u -p -r1.6 hidmt.c > --- sys/dev/hid/hidmt.c 10 Oct 2017 20:31:50 - 1.6 > +++ sys/dev/hid/hidmt.c 27 Jul 2018 19:53:59 - > @@ -235,7 +235,7 @@ hidmt_configure(struct hidmt *mt) > return; > > hw = wsmouse_get_hw(mt->sc_wsmousedev); > - hw->type = WSMOUSE_TYPE_ELANTECH; /* see hidmt_ioctl */ > + hw->type = WSMOUSE_TYPE_TOUCHPAD; > hw->hw_type = (mt->sc_clickpad > ? WSMOUSEHW_CLICKPAD : WSMOUSEHW_TOUCHPAD); > hw->x_min = mt->sc_minx; > @@ -468,13 +468,11 @@ hidmt_ioctl(struct hidmt *mt, u_long cmd > int wsmode; > > switch (cmd) { > - case WSMOUSEIO_GTYPE: > - /* > - * So we can specify our own finger/w values to the > - * xf86-input-synaptics driver like pms(4) > - */ > - *(u_int *)data = WSMOUSE_TYPE_ELANTECH; > + case WSMOUSEIO_GTYPE: { > + struct wsmousehw *hw = wsmouse_get_hw(mt->sc_wsmousedev); > + *(u_int *)data = hw->type; > break; > + } > > case WSMOUSEIO_GCALIBCOORDS: > wsmc->minx = mt->sc_minx; > Index: sys/dev/i2c/iatp.c > === > RCS file: /cvs/src/sys/dev/i2c/iatp.c,v > retrieving revision 1.5 > diff -u -p -u -p -r1.5 iatp.c > --- sys/dev/i2c/iatp.c22 Jun 2018 15:58:26 - 1.5 > +++ sys/dev/i2c/iatp.c27 Jul 2018 19:53:59 - > @@ -325,7 +325,7 @@ iatp_configure(struct iatp_softc *sc) > > hw = wsmouse_get_hw(sc->sc_wsmousedev); > if (sc->sc_touchpad) { > - hw->type = WSMOUSE_TYPE_SYNAPTICS; > + hw->type = WSMOUSE_TYPE_TOUCHPAD; > hw->hw_type = WSMOUSEHW_CLICKPAD; > } else { > hw->type = WSMOUSE_TYPE_TPANEL; > @@ -415,12 +415,11 @@ iatp_ioctl(void *v, u_long cmd, caddr_t > wsmc->resy = sc->sc_tsscale.resy; > break; > > - case WSMOUSEIO_GTYPE: > - if (sc->sc_touchpad) > - *(u_int *)data = WSMOUSE_TYPE_SYNAPTICS; > - else > - *(u_int *)data = WSMOUSE_TYPE_TPANEL; > + case WSMOUSEIO_GTYPE: { > + struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); > + *(u_int *)data = hw->type; > break; > + } > > case WSMOUSEIO_SETMODE: > if (!sc->sc_touchpad) > Index: sys/dev/usb/ubcmtp.c > === > RCS file: /cvs/src/sys/dev/usb/ubcmtp.c,v > retrieving revision 1.17 > diff -u -p -u -p -r1.17 ubcmtp.c > --- sys/dev/usb/ubcmtp.c 6 Jun 2017 21:53:07 - 1.17 > +++ sys/dev/usb/ubcmtp.c 27 Jul 2018 19:53:59 - > @@ -521,7 +521,7 @@ ubcmtp_configure(struct ubcmtp_softc *sc > { > struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); > > - hw->type = WSMOUSE_TYPE_ELANTECH; /* see ubcmtp_ioctl */ > + hw->type = WSMOUSE_TYPE_TOUCHPAD; > hw->hw_type = (IS_CLICKPAD(sc->dev_type->type) > ? WSMOUSEHW_CLICKPAD : WSMOUSEHW_TOUCHPAD); > hw->x_min = sc->dev_type->l_x.min; > @@ -601,11 +601,11 @@ ubcmtp_ioctl(void *v, unsigned long cmd, > cmd); > > switch (cmd) { > - case WSMOUSEIO_GTYPE: > - /* so we can specify our own finger/w values to the > - * xf86-input-synaptics driver like pms(4) */ > - *(u_int *)data = WSMOUSE_TYPE_ELANTECH; > + case WSMOUSEIO_GTYPE: { > + struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); > + *(u_int *)data = hw->type; > break; > + } > > case WSMOUSEIO_GCALIBCOORDS: > wsmc->minx = sc->dev_type->l_x.min; > Index: sys/dev/wscons/wsconsio.h > === > RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v > retrieving revision 1.88 > diff -u -p -u -p -r1.88 wsconsio.h > --- sys/dev/wscons/wsconsio.h 7 May 2018 21:58:42 - 1.88 > +++ sys/dev/wscons/wsconsio.h 27 Jul 2018
Re: enable middle button scrolling by default in ws(4) ?
Hi, I have the vague impression that the feature isn't popular here, but it makes sense if you are using a trackpoint, or a three-button mouse without a wheel. According to the libinput documentation, it is enabled by default for trackpoints. However, at first sight I'd think that such a default wouldn't hurt the use of other pointing devices (including touchpads and clickpads in compat mode). On 06/16/2018 06:19 PM, Matthieu Herrb wrote: > Hi, > > the ws(4) mouse driver has the option of emulating the mouse wheel > on motion + a given button is generated. > > This is active by default on button 2 on recent Linux systems (those > using libinput). > > Should OpenBSD's ws(4) activate it by default too ? > > If you want to experiment without rebuilding X you can run the > commands below to enable it > > xinput --set-prop --type=int /dev/wsmouse 'WS Pointer Wheel Emulation' 1 > xinput --set-prop --type=int /dev/wsmouse 'WS Pointer Wheel Emulation Button' > 2 > > Index: man/ws.man > === > RCS file: /cvs/OpenBSD/xenocara/driver/xf86-input-ws/man/ws.man,v > retrieving revision 1.14 > diff -u -r1.14 ws.man > --- man/ws.man3 Sep 2016 14:01:16 - 1.14 > +++ man/ws.man16 Jun 2018 14:12:49 - > @@ -94,7 +94,7 @@ > and > .B YAxisMapping > options. > -Default: off. > +Default: on. > .TP 4 > .BI "Option \*qEmulateWheelButton\*q \*q" integer \*q > Specifies which button must be held down to enable wheel emulation mode. > @@ -107,7 +107,7 @@ > If the button is 0 and > .BR EmulateWheel > is on, any motion of the device is converted into wheel events. > -Default:\ 4. > +Default:\ 2. > .TP 4 > .BI "Option \*qEmulateWheelInertia\*q \*q" integer \*q > Specifies how far (in pixels) the pointer must move to generate button > Index: src/emuwheel.c > === > RCS file: /cvs/OpenBSD/xenocara/driver/xf86-input-ws/src/emuwheel.c,v > retrieving revision 1.3 > diff -u -r1.3 emuwheel.c > --- src/emuwheel.c25 Dec 2015 15:08:28 - 1.3 > +++ src/emuwheel.c16 Jun 2018 14:12:49 - > @@ -178,9 +178,9 @@ > int button, inertia, timeout; > > priv->emulateWheel.enabled = xf86SetBoolOption(pInfo->options, > - "EmulateWheel", FALSE); > + "EmulateWheel", TRUE); > > - button = xf86SetIntOption(pInfo->options, "EmulateWheelButton", 4); > + button = xf86SetIntOption(pInfo->options, "EmulateWheelButton", 2); > if (button < 0 || button > NBUTTONS) { > xf86IDrvMsg(pInfo, X_WARNING, > "Invalid EmulateWheelButton value: %d\n", button); >
pms: support for Elantech trackpoints
This patch adds support for Elantech trackpoints to pms. They can be treated like other secondary devices and require only minor extensions in the initialization and input functions. For now, the patch also extends the set of "IC types" that are accepted for V4-touchpads from (6,8) to (6,8,15). It might well be that other types in the range 6-15 work properly with the driver. Thanks to Ryan Lennox for help and testing. OK? Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.86 diff -u -p -r1.86 pms.c --- dev/pckbc/pms.c 29 Apr 2018 08:50:04 - 1.86 +++ dev/pckbc/pms.c 12 May 2018 13:08:46 - @@ -130,6 +130,7 @@ struct elantech_softc { #define ELANTECH_F_2FINGER_PACKET 0x04 #define ELANTECH_F_HW_V1_OLD 0x08 #define ELANTECH_F_CRC_ENABLED 0x10 +#define ELANTECH_F_TRACKPOINT 0x20 int fw_version; u_int mt_slots; @@ -1938,8 +1939,9 @@ elantech_get_hwinfo_v4(struct pms_softc if (synaptics_query(sc, ELANTECH_QUE_FW_VER, _version)) return (-1); - if (((fw_version & 0x0f) >> 16) != 6 && - (fw_version & 0x0f) >> 16 != 8) + if ((fw_version & 0x0f) >> 16 != 6 + && (fw_version & 0x0f) >> 16 != 8 + && (fw_version & 0x0f) >> 16 != 15) return (-1); elantech->fw_version = fw_version; @@ -1963,6 +1965,9 @@ elantech_get_hwinfo_v4(struct pms_softc if ((capabilities[1] < 2) || (capabilities[1] > hw->x_max)) return (-1); + if (capabilities[0] & ELANTECH_CAP_TRACKPOINT) + elantech->flags |= ELANTECH_F_TRACKPOINT; + hw->type = WSMOUSE_TYPE_ELANTECH; hw->hw_type = WSMOUSEHW_CLICKPAD; hw->mt_slots = ELANTECH_MAX_FINGERS; @@ -2140,6 +2145,7 @@ int pms_enable_elantech_v4(struct pms_softc *sc) { struct elantech_softc *elantech = sc->elantech; + struct wsmousedev_attach_args a; if (elantech_knock(sc)) goto err; @@ -2169,6 +2175,14 @@ pms_enable_elantech_v4(struct pms_softc printf("%s: Elantech Clickpad, version %d, firmware 0x%x\n", DEVNAME(sc), 4, sc->elantech->fw_version); + + if (sc->elantech->flags & ELANTECH_F_TRACKPOINT) { + a.accessops = _sec_accessops; + a.accesscookie = sc; + sc->sc_sec_wsmousedev = config_found((void *) sc, , + wsmousedevprint); + } + } else if (elantech_set_absolute_mode_v4(sc)) goto err; @@ -2328,13 +2342,40 @@ pms_sync_elantech_v3(struct pms_softc *s return (0); } +/* Extract the type bits from packet[3]. */ +static inline int +elantech_packet_type(u_char b) +{ + return ((b & 4) ? (b & 0xcf) : (b & 0x1f)); +} + int pms_sync_elantech_v4(struct pms_softc *sc, int data) { - if (sc->inputstate == 0 && (data & 0x0c) != 0x04) + if (sc->inputstate == 0) { + if ((data & 0x0c) == 0x04) + return (0); + if ((sc->elantech->flags & ELANTECH_F_TRACKPOINT) + && (data & 0xc8) == 0) + return (0); return (-1); - else - return (0); + } + if (sc->inputstate == 3) { + switch (elantech_packet_type(data)) { + case ELANTECH_V4_PKT_STATUS: + case ELANTECH_V4_PKT_HEAD: + case ELANTECH_V4_PKT_MOTION: + return ((sc->packet[0] & 4) ? 0 : -1); + case ELANTECH_PKT_TRACKPOINT: + return ((sc->packet[0] & 0xc8) == 0 + && sc->packet[1] == ((data & 0x10) << 3) + && sc->packet[2] == ((data & 0x20) << 2) + && (data ^ (sc->packet[0] & 0x30)) == 0x36 + ? 0 : -1); + } + return (-1); + } + return (0); } void @@ -2474,7 +2515,7 @@ pms_proc_elantech_v4(struct pms_softc *s int id, weight, n, x, y, z; u_int buttons, slots; - switch (sc->packet[3] & 0x1f) { + switch (elantech_packet_type(sc->packet[3])) { case ELANTECH_V4_PKT_STATUS: slots = elantech->mt_slots; elantech->mt_slots = sc->packet[1] & 0x1f; @@ -2509,8 +2550,17 @@ pms_proc_elantech_v4(struct pms_softc *s wsmouse_set(sc_wsmousedev, WSMOUSE_MT_REL_Y, y, id); wsmouse_set(sc_wsmousedev, WSMOUSE_MT_PRESSURE, z, id); } - break; + + case ELANTECH_PKT_TRACKPOINT: + if (sc->sc_dev_enable & PMS_DEV_SECONDARY) { + x = sc->packet[4] - 0x100 + (sc->packet[1] << 1); + y = sc->packet[5] - 0x100 +
Re: pms: reset announcement
Looks fine to me. I made some tests on a T420, with explicitly triggered resets, and the detection and the "reset task" worked as expected. There are noticeable delays, but I don't think optimizing would be worth the effort (if it happens too often, you may want to repair or exchange your touchpad). Maybe we can generalize that later. Very rarely, I observe a similar phenomenon with my Elantech-v4 touchpad (two not-in-sync messages, then data reporting stops, which is to be expected after a PS/2 reset). But here is a little puzzle: There are no constant bits in byte 2 and 3 and byte 5 and 6 of Absolute Mode packets, so theoretically [0xaa, 0x00] may be a valid part of a packet, starting at byte 2 or byte 5 (there is no overlap on other positions). Is there a simple and sound way to exclude false positive errors? Or can we simply ignore it because it's improbable enough or impossible? (If not, a change of the logic could be necessary: don't interrupt the normal processing when the sequence is detected, and check the state of the device in pms_reset_task). On 10/29/2017 09:35 AM, Anton Lindqvist wrote: > Hi, > Every now and then, my Synaptics touchpad stops working and no further > interrupts are received for the device. The following message appears in > the log: > > pms0: not in sync yet, discard input (state = 0) > > Examining the bytes received prior to the halt reveals the sequence > [0xaa, 0x00] which denotes a Synaptics reset announcement[1]. This > sequence is sent after the touchpad experienced a loss of power and the > device is reset. Since any altered setting prior to the reset is lost > the device must be re-enabled in order to continue functioning. The > simplest(?) way is to disable and then enable the device (many thanks to > bru@ for helping out with this part). > > Testing this diff on hardware equipped with a Synaptics touchpad would be much > appreciated. Even if you never experienced a reset in order make sure no > regression is introduced. > > In addition, I'm looking for feedback and OKs. > > [1] > https://www.aquaphoenix.com/hardware/ledlamp/reference/synaptics_touchpad_interfacing_guide.pdf#page=32 > > Index: pms.c > === > RCS file: /cvs/src/sys/dev/pckbc/pms.c,v > retrieving revision 1.81 > diff -u -p -r1.81 pms.c > --- pms.c 28 Oct 2017 14:31:29 - 1.81 > +++ pms.c 28 Oct 2017 16:55:22 - > @@ -30,6 +30,7 @@ > #include > #include > #include > +#include > > #include > > @@ -88,6 +89,8 @@ struct synaptics_softc { > > int mode; > > + int annstate; /* announcement state */ > + > int mask; > #define SYNAPTICS_MASK_NEWABS_STRICT 0xc8 > #define SYNAPTICS_MASK_NEWABS_RELAXED0xc0 > @@ -158,6 +161,8 @@ struct pms_softc {/* driver status inf > #define PMS_DEV_PRIMARY 0x01 > #define PMS_DEV_SECONDARY0x02 > > + struct task sc_reset_task; > + > int poll; > int inputstate; > > @@ -255,6 +260,7 @@ int pms_reset(struct pms_softc *); > int pms_dev_enable(struct pms_softc *); > int pms_dev_disable(struct pms_softc *); > void pms_protocol_lookup(struct pms_softc *); > +void pms_reset_task(void *); > > int pms_enable_intelli(struct pms_softc *); > > @@ -293,6 +299,7 @@ int synaptics_set_mode(struct pms_softc > int synaptics_query(struct pms_softc *, int, int *); > int synaptics_get_hwinfo(struct pms_softc *); > void synaptics_sec_proc(struct pms_softc *); > +int synaptics_is_reset(struct pms_softc *, int); > > int alps_sec_proc(struct pms_softc *); > int alps_get_hwinfo(struct pms_softc *); > @@ -542,6 +549,32 @@ pms_protocol_lookup(struct pms_softc *sc > DPRINTF("%s: protocol type %d\n", DEVNAME(sc), sc->protocol->type); > } > > +void > +pms_reset_task(void *v) > +{ > + struct pms_softc *sc = v; > + > + rw_enter_write(>sc_state_lock); > + > + /* Do nothing if the device already is disabled. */ > + if (sc->sc_state == PMS_STATE_DISABLED) > + goto done; > + > +#ifdef DIAGNOSTIC > + printf("%s: device reset\n", DEVNAME(sc)); > +#endif > + if (sc->sc_sec_wsmousedev != NULL) > + pms_change_state(sc, PMS_STATE_DISABLED, PMS_DEV_SECONDARY); > + pms_change_state(sc, PMS_STATE_DISABLED, PMS_DEV_PRIMARY); > + > + pms_change_state(sc, PMS_STATE_ENABLED, PMS_DEV_PRIMARY); > + if (sc->sc_sec_wsmousedev != NULL) > + pms_change_state(sc, PMS_STATE_ENABLED, PMS_DEV_SECONDARY); > + > +done: > + rw_exit_write(>sc_state_lock); > +} > + > int > pms_enable_intelli(struct pms_softc *sc) > { > @@ -679,6 +712,8 @@ pmsattach(struct device *parent, struct >*/ > sc->sc_wsmousedev = config_found(self, , wsmousedevprint); > > + task_set(>sc_reset_task, pms_reset_task, sc); > + > sc->poll = 1; > sc->sc_dev_enable = 0; > > @@ -850,9 +885,11 @@ pmsinput(void *vsc, int data) >
pms: tests with older Elantech touchpads needed
This patch adapts the Elantech handlers in pms to the new touchpad infrastructure of wsmouse. The changes concern models that use the older protocol versions 1, 2, and 3. You don't find that hardware at the next corner nowadays, so if you have a laptop with one of those models, your help would be greatly appreciated. With the patch, synaptics(4) should work as before, and a configuration with ws(4) should run decently, see https://marc.info/?l=openbsd-misc=150153498920367=2 Index: pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.80 diff -u -p -r1.80 pms.c --- pms.c 26 Aug 2017 18:34:04 - 1.80 +++ pms.c 8 Oct 2017 20:17:09 - @@ -130,9 +130,6 @@ struct elantech_softc { #define ELANTECH_F_CRC_ENABLED 0x10 int fw_version; - int min_x, min_y; - int max_x, max_y; - u_int mt_slots; int width; @@ -140,10 +137,8 @@ struct elantech_softc { u_char parity[256]; u_char p1, p2, p3; - /* Compat mode */ - int wsmode; + int max_x, max_y; int old_x, old_y; - u_int old_buttons; }; struct pms_softc { /* driver status information */ @@ -303,7 +298,6 @@ int alps_sec_proc(struct pms_softc *); intalps_get_hwinfo(struct pms_softc *); intelantech_knock(struct pms_softc *); -void elantech_send_input(struct pms_softc *, int, int, int, int); intelantech_get_hwinfo_v1(struct pms_softc *); intelantech_get_hwinfo_v2(struct pms_softc *); intelantech_get_hwinfo_v3(struct pms_softc *); @@ -1709,6 +1703,7 @@ int elantech_get_hwinfo_v1(struct pms_softc *sc) { struct elantech_softc *elantech = sc->elantech; + struct wsmousehw *hw; int fw_version; u_char capabilities[3]; @@ -1733,10 +1728,13 @@ elantech_get_hwinfo_v1(struct pms_softc if (elantech_set_absolute_mode_v1(sc)) return (-1); - elantech->min_x = ELANTECH_V1_X_MIN; - elantech->max_x = ELANTECH_V1_X_MAX; - elantech->min_y = ELANTECH_V1_Y_MIN; - elantech->max_y = ELANTECH_V1_Y_MAX; + hw = wsmouse_get_hw(sc->sc_wsmousedev); + hw->type = WSMOUSE_TYPE_ELANTECH; + hw->hw_type = WSMOUSEHW_TOUCHPAD; + hw->x_min = ELANTECH_V1_X_MIN; + hw->x_max = ELANTECH_V1_X_MAX; + hw->y_min = ELANTECH_V1_Y_MIN; + hw->y_max = ELANTECH_V1_Y_MAX; return (0); } @@ -1745,6 +1743,7 @@ int elantech_get_hwinfo_v2(struct pms_softc *sc) { struct elantech_softc *elantech = sc->elantech; + struct wsmousehw *hw; int fw_version, ic_ver; u_char capabilities[3]; int i, fixed_dpi; @@ -1768,10 +1767,14 @@ elantech_get_hwinfo_v2(struct pms_softc if (elantech_set_absolute_mode_v2(sc)) return (-1); + hw = wsmouse_get_hw(sc->sc_wsmousedev); + hw->type = WSMOUSE_TYPE_ELANTECH; + hw->hw_type = WSMOUSEHW_TOUCHPAD; + if (fw_version == 0x20800 || fw_version == 0x20b00 || fw_version == 0x20030) { - elantech->max_x = ELANTECH_V2_X_MAX; - elantech->max_y = ELANTECH_V2_Y_MAX; + hw->x_max = ELANTECH_V2_X_MAX; + hw->y_max = ELANTECH_V2_Y_MAX; } else { if (pms_spec_cmd(sc, ELANTECH_QUE_FW_ID) || pms_get_status(sc, resp)) @@ -1782,17 +1785,17 @@ elantech_get_hwinfo_v2(struct pms_softc if (pms_spec_cmd(sc, ELANTECH_QUE_SAMPLE) || pms_get_status(sc, resp)) return (-1); - elantech->max_x = (capabilities[1] - i) * resp[1] / 2; - elantech->max_y = (capabilities[2] - i) * resp[2] / 2; + hw->x_max = (capabilities[1] - i) * resp[1] / 2; + hw->y_max = (capabilities[2] - i) * resp[2] / 2; } else if (fw_version == 0x040216) { - elantech->max_x = 819; - elantech->max_y = 405; + hw->x_max = 819; + hw->y_max = 405; } else if (fw_version == 0x040219 || fw_version == 0x040215) { - elantech->max_x = 900; - elantech->max_y = 500; + hw->x_max = 900; + hw->y_max = 500; } else { - elantech->max_x = (capabilities[1] - i) * 64; - elantech->max_y = (capabilities[2] - i) * 64; + hw->x_max = (capabilities[1] - i) * 64; + hw->y_max = (capabilities[2] - i) * 64; } } @@ -1803,6 +1806,7 @@ int elantech_get_hwinfo_v3(struct pms_softc *sc) { struct elantech_softc *elantech = sc->elantech; + struct wsmousehw *hw; int fw_version; u_char resp[3]; @@ -1825,8
iatp: tests needed (with Atmel touchpads)
This patch adds the wsmouse_configure call to iatp. I haven't seen it running, so it would be nice if someone could confirm that the change doesn't introduce regressions, and check whether it works with both synaptics(4) and ws(4). Index: iatp.c === RCS file: /cvs/src/sys/dev/i2c/iatp.c,v retrieving revision 1.3 diff -u -p -r1.3 iatp.c --- iatp.c 24 Sep 2016 18:32:18 - 1.3 +++ iatp.c 8 Oct 2017 19:27:13 - @@ -319,6 +319,30 @@ iatp_activate(struct device *self, int a } int +iatp_configure(struct iatp_softc *sc) +{ + struct wsmousehw *hw; + + hw = wsmouse_get_hw(sc->sc_wsmousedev); + if (sc->sc_touchpad) { + hw->type = WSMOUSE_TYPE_SYNAPTICS; + hw->hw_type = WSMOUSEHW_CLICKPAD; + } else { + hw->type = WSMOUSE_TYPE_TPANEL; + hw->hw_type = WSMOUSEHW_TPANEL; + } + hw->x_min = sc->sc_tsscale.minx; + hw->x_max = sc->sc_tsscale.maxx; + hw->y_min = sc->sc_tsscale.miny; + hw->y_max = sc->sc_tsscale.maxy; + hw->h_res = sc->sc_tsscale.resx; + hw->v_res = sc->sc_tsscale.resy; + hw->mt_slots = sc->num_touchids; + + return (wsmouse_configure(sc->sc_wsmousedev, NULL, 0)); +} + +int iatp_enable(void *v) { struct iatp_softc *sc = v; @@ -333,13 +357,10 @@ iatp_enable(void *v) DPRINTF(("%s: enabling\n", sc->sc_dev.dv_xname)); - if (wsmouse_mt_init(sc->sc_wsmousedev, sc->num_touchids, 0)) { - printf("%s: failed wsmouse_mt_init\n", sc->sc_dev.dv_xname); + if (iatp_configure(sc)) { + printf("%s: failed wsmouse_configure\n", sc->sc_dev.dv_xname); return 1; } - - if (sc->sc_touchpad) - wsmouse_set_mode(sc->sc_wsmousedev, WSMOUSE_COMPAT); /* force a read of any pending messages so we start getting new * interrupts */
imt/hidmt: tests with "Windows Precision Touchpads" needed
This patch adapts hidmt - which is used by imt(4) - to the multitouch interface of wsmouse, and it adds the compat-mode configuration required by the wsmouse-internal touchpad input driver. Tests with both the synaptics driver and the internal driver would be appreciated (see https://marc.info/?l=openbsd-misc=150153498920367=2). If you have a custom configuration for synaptics, it might be necessary to adjust it, it seems that the current version does not handle the dimensions correctly. Index: dev/hid/hidmt.c === RCS file: /cvs/src/sys/dev/hid/hidmt.c,v retrieving revision 1.2 diff -u -p -r1.2 hidmt.c --- dev/hid/hidmt.c 30 Mar 2016 23:34:12 - 1.2 +++ dev/hid/hidmt.c 19 Sep 2017 19:17:23 - @@ -41,6 +41,70 @@ #define DPRINTF(x) #endif +#define HID_UNIT_CM0x11 +#define HID_UNIT_INCH 0x13 + +/* + * Calculate the horizontal or vertical resolution, in device units per + * millimeter. + * + * With the length unit specified by the descriptor (centimeter or inch), + * the result is: + * (logical_maximum - logical_minimum) / ((physical_maximum - + * physical_minimum) * 10^unit_exponent) + * + * The descriptors should encode the unit exponent as a signed half-byte. + * However, this function accepts the values from -8 to -1 in both the + * 4-bit format and the usual encoding. Other values beyond the 4-bit + * range are treated as undefined. Possibly a misinterpretation of + * section 6.2.2.7 of the HID specification (v1.11) has been turned into + * a standard here, see (from www.usb.org) + * HUTRR39: "HID Sensor Usage Tables", sect. 3.9, 3.10, 4.2.1 + * for an official exegesis and + * https://patchwork.kernel.org/patch/3033191 + * for details and a different view. + */ +int +hidmt_get_resolution(struct hid_item *h) +{ + int log_extent, phy_extent, exponent; + + if (h->unit != HID_UNIT_CM && h->unit != HID_UNIT_INCH) + return (0); + + log_extent = h->logical_maximum - h->logical_minimum; + phy_extent = h->physical_maximum - h->physical_minimum; + if (log_extent <= 0 || phy_extent <= 0) + return (0); + + exponent = h->unit_exponent; + if (exponent < -8 || exponent > 15) /* See above. */ + return (0); + if (exponent > 7) + exponent -= 16; + + for (; exponent < 0 && log_extent <= INT_MAX / 10; exponent++) + log_extent *= 10; + for (; exponent > 0 && phy_extent <= INT_MAX / 10; exponent--) + phy_extent *= 10; + if (exponent != 0) + return (0); + + if (h->unit == HID_UNIT_INCH) { /* Map inches to mm. */ + if ((phy_extent > INT_MAX / 254) + || (log_extent > INT_MAX / 10)) + return (0); + log_extent *= 10; + phy_extent *= 254; + } else {/* Map cm to mm. */ + if (phy_extent > INT_MAX / 10) + return (0); + phy_extent *= 10; + } + + return (log_extent / phy_extent); +} + int hidmt_setup(struct device *self, struct hidmt *mt, void *desc, int dlen) { @@ -111,18 +175,18 @@ hidmt_setup(struct device *self, struct switch (h.usage) { /* contact level usages */ case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X): - if (h.physical_minimum < mt->sc_minx) - mt->sc_minx = h.physical_minimum; - if (h.physical_maximum > mt->sc_maxx) - mt->sc_maxx = h.physical_maximum; - + if (h.logical_maximum - h.logical_minimum) { + mt->sc_minx = h.logical_minimum; + mt->sc_maxx = h.logical_maximum; + mt->sc_resx = hidmt_get_resolution(); + } break; case HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y): - if (h.physical_minimum < mt->sc_miny) - mt->sc_miny = h.physical_minimum; - if (h.physical_maximum > mt->sc_maxy) - mt->sc_maxy = h.physical_maximum; - + if (h.logical_maximum - h.logical_minimum) { + mt->sc_miny = h.logical_minimum; + mt->sc_maxy = h.logical_maximum; + mt->sc_resy = hidmt_get_resolution(); + } break; case HID_USAGE2(HUP_DIGITIZERS, HUD_TIP_SWITCH): case HID_USAGE2(HUP_DIGITIZERS, HUD_CONFIDENCE): @@ -162,6 +226,29 @@ hidmt_setup(struct device *self, struct } void +hidmt_configure(struct hidmt *mt) +{ + struct wsmousehw *hw; + +
Synaptics touchpads: coordinate limits
This patch adds a query for the lower coordinate limits to the Synaptics part of pms. Up to now, the driver always uses the "typical bezel limits" as given in the "Synaptics PS/2 Interfacing Guide". These limits are indeed typical and often work well, but they aren't exact and you cannot control the edge area sizes precisely. I hope the query solves the problem for the models that support it, and I would expect that it only causes minor changes in current setups. A few tests would be nice. A quick way to check whether it has effects is # wsconsctl mouse.scale The first and the third value of the result should be different from mouse.scale=1472,...,1408,...,...,... Index: pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.78 diff -u -p -r1.78 pms.c --- pms.c 21 Jul 2017 20:10:10 - 1.78 +++ pms.c 21 Aug 2017 20:46:45 - @@ -84,7 +84,7 @@ struct synaptics_softc { int identify; int capabilities, ext_capabilities, ext2_capabilities; int model, ext_model; - int resolution, dimension; + int resolution, max_coords, min_coords; int modes; int mode; @@ -928,9 +928,15 @@ synaptics_get_hwinfo(struct pms_softc *s synaptics_query(sc, SYNAPTICS_QUE_RESOLUTION, >resolution)) return (-1); if ((SYNAPTICS_CAP_EXTENDED_QUERIES(syn->capabilities) >= 5) && - (syn->ext_capabilities & SYNAPTICS_EXT_CAP_MAX_DIMENSIONS) && - synaptics_query(sc, SYNAPTICS_QUE_EXT_DIMENSIONS, >dimension)) + (syn->ext_capabilities & SYNAPTICS_EXT_CAP_MAX_COORDS) && + synaptics_query(sc, SYNAPTICS_QUE_EXT_MAX_COORDS, >max_coords)) return (-1); + if ((SYNAPTICS_CAP_EXTENDED_QUERIES(syn->capabilities) >= 7 || + SYNAPTICS_ID_FULL(syn->identify) == 0x801) && + (syn->ext_capabilities & SYNAPTICS_EXT_CAP_MIN_COORDS) && + synaptics_query(sc, SYNAPTICS_QUE_EXT_MIN_COORDS, >min_coords)) + return (-1); + if (SYNAPTICS_ID_FULL(syn->identify) >= 0x705) { if (synaptics_query(sc, SYNAPTICS_QUE_MODES, >modes)) return (-1); @@ -954,12 +960,15 @@ synaptics_get_hwinfo(struct pms_softc *s hw->h_res = SYNAPTICS_RESOLUTION_X(syn->resolution); hw->v_res = SYNAPTICS_RESOLUTION_Y(syn->resolution); } - hw->x_min = SYNAPTICS_XMIN_BEZEL; - hw->y_min = SYNAPTICS_YMIN_BEZEL; - hw->x_max = (syn->dimension) ? - SYNAPTICS_DIM_X(syn->dimension) : SYNAPTICS_XMAX_BEZEL; - hw->y_max = (syn->dimension) ? - SYNAPTICS_DIM_Y(syn->dimension) : SYNAPTICS_YMAX_BEZEL; + + hw->x_min = (syn->min_coords ? + SYNAPTICS_X_LIMIT(syn->min_coords) : SYNAPTICS_XMIN_BEZEL); + hw->y_min = (syn->min_coords ? + SYNAPTICS_Y_LIMIT(syn->min_coords) : SYNAPTICS_YMIN_BEZEL); + hw->x_max = (syn->max_coords ? + SYNAPTICS_X_LIMIT(syn->max_coords) : SYNAPTICS_XMAX_BEZEL); + hw->y_max = (syn->max_coords ? + SYNAPTICS_Y_LIMIT(syn->max_coords) : SYNAPTICS_YMAX_BEZEL); hw->contacts_max = SYNAPTICS_MAX_FINGERS; Index: pmsreg.h === RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v retrieving revision 1.13 diff -u -p -r1.13 pmsreg.h --- pmsreg.h5 Sep 2015 14:02:21 - 1.13 +++ pmsreg.h21 Aug 2017 20:46:45 - @@ -73,7 +73,8 @@ #define SYNAPTICS_QUE_RESOLUTION 0x08 #define SYNAPTICS_QUE_EXT_MODEL0x09 #define SYNAPTICS_QUE_EXT_CAPABILITIES 0x0c -#define SYNAPTICS_QUE_EXT_DIMENSIONS 0x0d +#define SYNAPTICS_QUE_EXT_MAX_COORDS 0x0d +#define SYNAPTICS_QUE_EXT_MIN_COORDS 0x0f #define SYNAPTICS_QUE_EXT2_CAPABILITIES0x10 #define SYNAPTICS_CMD_SET_MODE 0x14 @@ -137,13 +138,14 @@ /* Extended Capability bits */ #define SYNAPTICS_EXT_CAP_CLICKPAD (1 << 20) #define SYNAPTICS_EXT_CAP_ADV_GESTURE (1 << 19) -#define SYNAPTICS_EXT_CAP_MAX_DIMENSIONS (1 << 17) +#define SYNAPTICS_EXT_CAP_MAX_COORDS (1 << 17) +#define SYNAPTICS_EXT_CAP_MIN_COORDS (1 << 13) #define SYNAPTICS_EXT_CAP_CLICKPAD_2BTN(1 << 8) -/* Extended Dimensions */ -#define SYNAPTICS_DIM_X(d) d) & 0xff) >> 11) | \ +/* Coordinate Limits */ +#define SYNAPTICS_X_LIMIT(d) d) & 0xff) >> 11) | \ (((d) & 0xf00) >> 7)) -#define SYNAPTICS_DIM_Y(d) d) & 0xff) << 5) | \ +#define SYNAPTICS_Y_LIMIT(d) d) & 0xff) << 5) | \ (((d) & 0xf000) >> 11)) /* Extended Capability 2 */
Improved support for Apple trackpads: tests needed
This patch for ubcmtp makes it use the multitouch-input functions of wsmouse. It's the first driver that would apply the "tracking" variant (wsmouse_mtframe). No wonders will result from the change, but the two-finger gestures that involve movement - scrolling and click-and-drag with two fingers on a clickpad - should work without flaws. A quick way to check whether all touch positions are available and the selection of the active touch works properly is two-finger-scrolling, performed with only one finger moving, then switching to the other one. Please note that click-and-drag will still require that the "ClickPad" attribute is set in the synaptics(4) configuration. The patch has been tested on a MacBookPro 8,2 (from 2011). It would be nice to learn that it doesn't introduce regressions on older or newer models. If you don't use a brand-new version of the synaptics driver, you may encounter the following bug: If the X cursor is in a window with scrollable content and you put two finger on the touchpad without moving them, the window content may quickly scroll up and down by a small distance. This bug is fixed in the latest version. Index: dev/usb/ubcmtp.c === RCS file: /cvs/src/sys/dev/usb/ubcmtp.c,v retrieving revision 1.12 diff -u -p -r1.12 ubcmtp.c --- dev/usb/ubcmtp.c30 Mar 2016 23:34:12 - 1.12 +++ dev/usb/ubcmtp.c9 Mar 2017 22:17:50 - @@ -125,6 +125,12 @@ struct ubcmtp_finger { #define UBCMTP_SN_COORD250 #define UBCMTP_SN_ORIENT 10 +/* Identify clickpads in ubcmtp_configure. */ +#define IS_CLICKPAD(ubcmtp_type) (ubcmtp_type != UBCMTP_TYPE1) + +/* Use a constant, synaptics-compatible pressure value for now. */ +#define DEFAULT_PRESSURE 40 + struct ubcmtp_limit { int limit; int min; @@ -316,17 +322,6 @@ static struct ubcmtp_dev ubcmtp_devices[ }, }; -/* coordinates for each tracked finger */ -struct ubcmtp_pos { - int down; - int x; - int y; - int z; - int w; - int dx; - int dy; -}; - struct ubcmtp_softc { struct device sc_dev; /* base device */ @@ -355,7 +350,8 @@ struct ubcmtp_softc { uint32_tsc_status; #define UBCMTP_ENABLED 1 - struct ubcmtp_pos pos[UBCMTP_MAX_FINGERS]; + struct mtpoint frame[UBCMTP_MAX_FINGERS]; + int contacts; int btn; }; @@ -519,6 +515,24 @@ ubcmtp_activate(struct device *self, int } int +ubcmtp_configure(struct ubcmtp_softc *sc) +{ + struct wsmousehw *hw = wsmouse_get_hw(sc->sc_wsmousedev); + + hw->type = WSMOUSE_TYPE_ELANTECH; /* see ubcmtp_ioctl */ + hw->hw_type = (IS_CLICKPAD(sc->dev_type->type) + ? WSMOUSEHW_CLICKPAD : WSMOUSEHW_TOUCHPAD); + hw->x_min = sc->dev_type->l_x.min; + hw->x_max = sc->dev_type->l_x.max; + hw->y_min = sc->dev_type->l_y.min; + hw->y_max = sc->dev_type->l_y.max; + hw->mt_slots = UBCMTP_MAX_FINGERS; + hw->flags = WSMOUSEHW_MT_TRACKING; + + return wsmouse_configure(sc->sc_wsmousedev, NULL, 0); +} + +int ubcmtp_enable(void *v) { struct ubcmtp_softc *sc = v; @@ -534,6 +548,9 @@ ubcmtp_enable(void *v) return (1); } + if (ubcmtp_configure(sc)) + return (1); + if (ubcmtp_setup_pipes(sc) == 0) { sc->sc_status |= UBCMTP_ENABLED; return (0); @@ -608,6 +625,7 @@ ubcmtp_ioctl(void *v, unsigned long cmd, wsmode); return (EINVAL); } + wsmouse_set_mode(sc->sc_wsmousedev, wsmode); DPRINTF("%s: changing mode to %s\n", sc->sc_dev.dv_xname, (wsmode == WSMOUSE_COMPAT ? "compat" : @@ -779,7 +797,7 @@ ubcmtp_tp_intr(struct usbd_xfer *xfer, v struct ubcmtp_softc *sc = priv; struct ubcmtp_finger *pkt; u_int32_t pktlen; - int i, diff = 0, finger = 0, fingers = 0, s, t; + int i, s, btn, contacts, fingers; if (usbd_is_dying(sc->sc_udev) || !(sc->sc_status & UBCMTP_ENABLED)) return; @@ -803,76 +821,30 @@ ubcmtp_tp_intr(struct usbd_xfer *xfer, v pkt = (struct ubcmtp_finger *)(sc->tp_pkt + sc->tp_offset); fingers = (pktlen - sc->tp_offset) / sizeof(struct ubcmtp_finger); + contacts = 0; for (i = 0; i < fingers; i++) { - if ((int16_t)letoh16(pkt[i].touch_major) == 0) { - /* finger lifted */ - sc->pos[i].down = 0; - diff = 1; - continue; - } - - if (!sc->pos[finger].down) { - sc->pos[finger].down = 1; - diff = 1; - } - - if ((t =
synaptics(4): multitouch input and hysteresis
While preparing and testing some changes in ubcmtp I found a bug in wsconscomm that may affect two-finger touches on "noisy" MT devices, that is, on devices that constantly report small deltas of the touch positions even if there is no noticeable movement. Whenever the contact count or the pointer-controlling touch changes, wsmouse will generate a TOUCH_RESET event, which signals that there is a coordinate update that may not correspond to a movement on the touchpad. The wsconscomm handler ensures that in this case the driver doesn't trigger pointer movement. If scrolling is active, it also adjusts the scroll coordinates and the "move history" to the new position (this is necessary because the driver computes its scroll deltas independently of the motion deltas). The hysteresis coordinates will need a similar adjustment. If it works with stale coordinates, the filter may produce an output that differs from its input by an amount that is equal to the hysteresis threshold. If you have a "noisy" device and put two fingers on its surface without moving them, pointer control can quickly switch back and forth, and the deltas add up quickly to visible changes of the scroll position. The good news is that the fix is much shorter than its explanation. OK? Index: src/wsconscomm.c === RCS file: /cvs/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c,v retrieving revision 1.16 diff -u -p -r1.16 wsconscomm.c --- src/wsconscomm.c12 Sep 2016 22:12:44 - 1.16 +++ src/wsconscomm.c6 Mar 2017 18:37:41 - @@ -252,6 +252,9 @@ WSConsReadHwState(InputInfoPtr pInfo, if (reset) { /* Ensure that pointer motion stops. */ priv->count_packet_finger = 0; +/* Don't use stale coordinates for filtering. */ +priv->hyst_center_x = hw->x; +priv->hyst_center_y = hw->y; if (priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on) { WSConsAdjustScrollCoords(priv, hw);
Re: Fix Wacom Intuos S 2 descriptor and make wsmouse work
Maybe one day I'll get it right: s/wsmouse_input_sync()/wsmouse_input_sync(ms->sc_wsmousedev)/ On 09/07/2016 12:12 AM, Ulf Brosziewski wrote: > Hi, I was a bit hasty, I should have mentioned that calling > wsmouse_input_sync is required here. The equivalent of your > code would would be this: > > if (x != 0 || y != 0 || buttons != ms->sc_buttons) { > wsmouse_position(ms->sc_wsmousedev, x, y); > /* ignore proximity, it will cause invalid button 2 events */ > if ((data[0] & 0xf0) != 0xc0) > wsmouse_buttons(ms->sc_wsmousedev, buttons); > wsmouse_input_sync(); > } > > The WSMOUSE_INPUT macro - a substitute for the old wsmouse_input > function - does include that call (see wsmousevar.h). > > There is a set of functions for reporting input states: > wsmouse_buttons, wsmouse_motion, wsmouse_position, wsmouse_touch, > and wsmouse_mtstate (and the somewhat special wsmouse_set and > wsmouse_mtframe). A driver can call them in any order, and it > doesn't need to check whether there are deltas, wsmouse does > this anyway. However, a frame must be finished by a call to > wsmouse_input_sync. It is this function that generates the > wscons events. > > The new interface has been introduced in 6.0. > > On 09/06/2016 09:00 PM, Frank Groeneveld wrote: >> On Tue, Sep 06, 2016 at 02:19:28PM +0200, Ulf Brosziewski wrote: >>> Just a remark on your use of the wsmouse interface (which isn't well >>> known and documented yet): wsmouse_set is a function for uncommon >>> cases. To report a pair of absolute coordinates use wsmouse_position, >>> that is, instead of >>> wsmouse_set(ms->sc_wsmousedev, WSMOUSE_ABS_X, x, 0); >>> wsmouse_set(ms->sc_wsmousedev, WSMOUSE_ABS_Y, y, 0); >>> you should use >>> wsmouse_position(ms->sc_wsmousedev, x, y); >>> Likewise, for reporting the button state there is >>> wsmouse_buttons(ms->sc_wsmousedev, buttons); >>> There is no need for the WSMOUSE_INPUT macro here. >> >> Seems like a cleaner API indeed, but those functions don't seem to work >> for me. Both mouse movement and button reporting stop functioning when >> replaced by those calls. How old is this API, might it be some outdated >> sources on my side? Something else I'm doing wrong? >> >> Frank >> >> > >
Re: Fix Wacom Intuos S 2 descriptor and make wsmouse work
Just a remark on your use of the wsmouse interface (which isn't well known and documented yet): wsmouse_set is a function for uncommon cases. To report a pair of absolute coordinates use wsmouse_position, that is, instead of wsmouse_set(ms->sc_wsmousedev, WSMOUSE_ABS_X, x, 0); wsmouse_set(ms->sc_wsmousedev, WSMOUSE_ABS_Y, y, 0); you should use wsmouse_position(ms->sc_wsmousedev, x, y); Likewise, for reporting the button state there is wsmouse_buttons(ms->sc_wsmousedev, buttons); There is no need for the WSMOUSE_INPUT macro here. On 09/05/2016 09:04 PM, Frank Groeneveld wrote: > On Sun, Sep 04, 2016 at 02:25:06PM +0200, Martin Pieuchot wrote: >>> - One bug still left: when the device is attached after X has started, >>> it seems the scaling is done wrongly. I had this problem with the >>> hacked ums driver as well. Most of the time it is fixed by switching >>> between console and X. > > Correction: the problem can only be fixed by making sure the device is > plugged in before starting X. After suspend a restart of X is needed to > make scaling work again. > >> >> This is a common problem for drivers needing calibration. Does the X driver >> opens your device through /dev/wsmouseN or does it uses the mux? > > I think that's weird for this device tough: input is always report from > zero till the maximum values in the driver. No matter how or when you > attach it. > I'm not sure how the X driver opens the device. I've based it off ums(4) > mostly, so it will probably be the same as ums(4) does. > >>> - Documentation is still absent, I'll gladly write it when you guys >>> apporve of the code I wrote. >> >> I'll be happy to do so, could you provide a man page for this driver? > > Attached a new diff with documentation. > >>> What do you guys think? Any comments or suggestions? Any ideas on how to >>> attach to all three uhidevs? >> >> Yes, you have to match the device id. uhidev(4) attaches to the 3 first >> interfaces of your first configuration. And you want a single piece of code >> driving all these interfaces. Do you have some documentation for the device >> you're hacking on? Do you know what you can do with these interfaces? It's >> important to know otherwise you >> might spend as much work refactoring the driver to extend it than you >> spent in the beginning. > > Unfortunately I couldn't find any documentation except for the Linux > device driver implementation (but it supports all kinds of Wacom > tablets, so it isn't exactly readable). > I've written this driver by using the broken device descriptor > and reverse-engeneering with commands such as: > > cat /dev/uhid6 | hexdump -e '9/1 "%02x " "\n"' > > And just moving the pen and seeing which bytes change. > > It seems only the first uhidev device actually reports inputs. The last > uhidev device seems to have the most correct descriptor, but never > reports any data. My guess is that it's there for Windows users without > the driver: they can recognize the tablet as a reported generic mouse. > > As far as I can understand the Linux driver, they only use the data from > the reportid that my driver uses. For completeness I've attached lsusb > output from a Linux computer as well. > > Frank >
Re: wsmouse re-enabling
Ping? On 07/14/2016 12:11 AM, Ulf Brosziewski wrote: > Sorry for the repetition, it seems that single-touch state > needs the same treatment as MT state when wsmouse is being > reopened. Single-touch state "synchronizes" itself immediately > when the first changes occur, but it may happen that the first > touch after a restart with dirty state won't trigger pointer > motion (if there is no update of the contact count). > > The patch reverts wsmouse_mt_init to its previous form, the > input state will now be cleared completely by wsmousedoopen. > > OK? > > > Index: wsmouse.c > === > RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v > retrieving revision 1.32 > diff -u -p -r1.32 wsmouse.c > --- wsmouse.c 12 Jul 2016 22:02:53 - 1.32 > +++ wsmouse.c 13 Jul 2016 21:59:01 - > @@ -379,6 +379,8 @@ wsmousedoopen(struct wsmouse_softc *sc, > { > sc->sc_base.me_evp = evp; > > + wsmouse_input_reset(>input); > + > /* enable the device, and punt if that's not possible */ > return (*sc->sc_accessops->enable)(sc->sc_accesscookie); > } > @@ -1266,8 +1268,11 @@ wsmouse_mt_init(struct device *sc, int n > &((struct wsmouse_softc *) sc)->input; > int n, size; > > + if (num_slots == input->mt.num_slots > + && (!tracking == ((input->flags & MT_TRACKING) == 0))) > + return (0); > + > free_mt_slots(input); > - memset(>mt, 0, sizeof(struct mt_state)); > > if (tracking) > input->flags |= MT_TRACKING; > @@ -1375,4 +1380,25 @@ void > wsmouse_input_cleanup(struct wsmouseinput *input) > { > free_mt_slots(input); > +} > + > +void > +wsmouse_input_reset(struct wsmouseinput *input) > +{ > + int num_slots, *matrix; > + struct mt_slot *slots; > + > + memset(>btn, 0, sizeof(struct btn_state)); > + memset(>motion, 0, sizeof(struct motion_state)); > + memset(>touch, 0, sizeof(struct touch_state)); > + input->touch.min_pressure = input->params.pressure_hi; > + if ((num_slots = input->mt.num_slots)) { > + slots = input->mt.slots; > + matrix = input->mt.matrix; > + memset(>mt, 0, sizeof(struct mt_state)); > + memset(slots, 0, num_slots * sizeof(struct mt_slot)); > + input->mt.num_slots = num_slots; > + input->mt.slots = slots; > + input->mt.matrix = matrix; > + } > } > Index: wsmouseinput.h > === > RCS file: /cvs/src/sys/dev/wscons/wsmouseinput.h,v > retrieving revision 1.1 > diff -u -p -r1.1 wsmouseinput.h > --- wsmouseinput.h30 Mar 2016 23:34:12 - 1.1 > +++ wsmouseinput.h13 Jul 2016 21:59:01 - > @@ -141,6 +141,7 @@ void wsmouse_init_scaling(struct wsmouse > > void wsmouse_input_init(struct wsmouseinput *, struct wseventvar **); > void wsmouse_input_cleanup(struct wsmouseinput *); > +void wsmouse_input_reset(struct wsmouseinput *); > > > #define FOREACHBIT(v, i) \ > >
wsmouse re-enabling
Sorry for the repetition, it seems that single-touch state needs the same treatment as MT state when wsmouse is being reopened. Single-touch state "synchronizes" itself immediately when the first changes occur, but it may happen that the first touch after a restart with dirty state won't trigger pointer motion (if there is no update of the contact count). The patch reverts wsmouse_mt_init to its previous form, the input state will now be cleared completely by wsmousedoopen. OK? Index: wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.32 diff -u -p -r1.32 wsmouse.c --- wsmouse.c 12 Jul 2016 22:02:53 - 1.32 +++ wsmouse.c 13 Jul 2016 21:59:01 - @@ -379,6 +379,8 @@ wsmousedoopen(struct wsmouse_softc *sc, { sc->sc_base.me_evp = evp; + wsmouse_input_reset(>input); + /* enable the device, and punt if that's not possible */ return (*sc->sc_accessops->enable)(sc->sc_accesscookie); } @@ -1266,8 +1268,11 @@ wsmouse_mt_init(struct device *sc, int n &((struct wsmouse_softc *) sc)->input; int n, size; + if (num_slots == input->mt.num_slots + && (!tracking == ((input->flags & MT_TRACKING) == 0))) + return (0); + free_mt_slots(input); - memset(>mt, 0, sizeof(struct mt_state)); if (tracking) input->flags |= MT_TRACKING; @@ -1375,4 +1380,25 @@ void wsmouse_input_cleanup(struct wsmouseinput *input) { free_mt_slots(input); +} + +void +wsmouse_input_reset(struct wsmouseinput *input) +{ + int num_slots, *matrix; + struct mt_slot *slots; + + memset(>btn, 0, sizeof(struct btn_state)); + memset(>motion, 0, sizeof(struct motion_state)); + memset(>touch, 0, sizeof(struct touch_state)); + input->touch.min_pressure = input->params.pressure_hi; + if ((num_slots = input->mt.num_slots)) { + slots = input->mt.slots; + matrix = input->mt.matrix; + memset(>mt, 0, sizeof(struct mt_state)); + memset(slots, 0, num_slots * sizeof(struct mt_slot)); + input->mt.num_slots = num_slots; + input->mt.slots = slots; + input->mt.matrix = matrix; + } } Index: wsmouseinput.h === RCS file: /cvs/src/sys/dev/wscons/wsmouseinput.h,v retrieving revision 1.1 diff -u -p -r1.1 wsmouseinput.h --- wsmouseinput.h 30 Mar 2016 23:34:12 - 1.1 +++ wsmouseinput.h 13 Jul 2016 21:59:01 - @@ -141,6 +141,7 @@ void wsmouse_init_scaling(struct wsmouse void wsmouse_input_init(struct wsmouseinput *, struct wseventvar **); void wsmouse_input_cleanup(struct wsmouseinput *); +void wsmouse_input_reset(struct wsmouseinput *); #define FOREACHBIT(v, i) \
always reset mt state in wsmouse_mt_init
It seems that if an MT device is disabled and reenabled, remnants of the previous MT state can lead to problems. wsmouse_mt_init should always reset that state completely (thanks to jcs@ for help). OK? Index: dev/wscons/wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.31 diff -u -p -r1.31 wsmouse.c --- dev/wscons/wsmouse.c5 Jul 2016 19:33:14 - 1.31 +++ dev/wscons/wsmouse.c12 Jul 2016 21:01:17 - @@ -1266,11 +1266,8 @@ wsmouse_mt_init(struct device *sc, int n &((struct wsmouse_softc *) sc)->input; int n, size; - if (num_slots == input->mt.num_slots - && (!tracking == ((input->flags & MT_TRACKING) == 0))) - return (0); - free_mt_slots(input); + memset(>mt, 0, sizeof(struct mt_state)); if (tracking) input->flags |= MT_TRACKING;
improve wsmouse_matching
The diff below adds a little improvement to the wsmouse_matching function, which is the core of the MT tracking mechanism in wsmouse. Sadly, that mechanism isn't in use up to now, but this also means that OKs are riskless ;-) With small matrices - roughly, of orders up to 300 or 400 - and most kinds of input, the current version is faster than the alternatives that I tested some time ago. The tests included two clean and compact O(n^3) implementations of the "Hungarian Method" as well as the Linux equivalent of the matching function (find_reduced_matrix in input_mt.c). The input types were random data in various ranges, "Machol-Wien" data, and geometric data (the type that is relevant for wsmouse). It might not matter in wsmouse, but the current version doesn't perform well if the range and variation of the matrix values is very small, and matrices filled with equal values belong to the worst-case inputs. To a large extent, this is due to a flaw of the implementation; it may trigger superfluous searches. The change below removes this defect. OK? Index: dev/wscons/wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.30 diff -u -p -r1.30 wsmouse.c --- dev/wscons/wsmouse.c6 Jun 2016 22:32:47 - 1.30 +++ dev/wscons/wsmouse.c4 Jul 2016 23:15:58 - @@ -1125,11 +1125,13 @@ wsmouse_matching(int *matrix, int m, int for (; p < alt; *p++ = 0) {} for (col = 0; col < n; col++) { delta = INT_MAX; - for (i = 0, p = matrix + col; i < m; i++, p += n) - if ((d = *p - red[i]) <= delta) { + for (i = 0, p = matrix + col; i < m; i++, p += n) { + d = *p - red[i]; + if (d < delta || (d == delta && r2c[i] < 0)) { delta = d; row = i; } + } cd[col] = delta; if (r2c[row] < 0) { r2c[row] = col; @@ -1151,7 +1153,8 @@ wsmouse_matching(int *matrix, int m, int mc[i] = j; } d -= red[i]; - if (d <= delta) { + if (d < delta || (d == delta + && r2c[i] < 0)) { delta = d; row = i; }
Re: removing wsmouse_input [2]: zts, hilms, uts
The input functions of wsmouse have changed completely, this also concerns ums/hidms. All tests are - and will be - welcome ;-) On 06/06/2016 11:31 PM, Edd Barrett wrote: > On Mon, Jun 06, 2016 at 01:53:01PM +0200, Stefan Sperling wrote: >> On Mon, Jun 06, 2016 at 12:40:24PM +0100, Edd Barrett wrote: >>> I have a uts. >>> >>> I can test later. Am I expecting to see any functional change? >> >> No change is expected. It should just work. > > Ah, my apologies, my touchscreen is attaching to ums. > > ums2 at uhidev4 reportid 2: 3 buttons, tip, barrel, eraser > wsmouse3 at ums2 mux 0 > > > P.S. > > Please feel free to CC me if there is any touch-screen related diffs > that I could test with my touchscreen. Although I have a touch-screen, > and despite a bit of hacking a few years back to get it working at all, > the support is still not good, and thus I have barely used it. > > My touch-screen has issues with suspend: > http://marc.info/?l=openbsd-bugs=146504820529987=2 > > And we currently do not correctly transpose X co-ordinates when randr is > used to rotate the screen. > > Cheers >
removing wsmouse_input [3]: cleanup
This the last patch of this series, which removes wsmouse_input. ok? Index: dev/wscons/wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.29 diff -u -p -r1.29 wsmouse.c --- dev/wscons/wsmouse.c30 Mar 2016 23:34:12 - 1.29 +++ dev/wscons/wsmouse.c5 Jun 2016 21:44:58 - @@ -72,6 +72,22 @@ */ /* + * Copyright (c) 2015, 2016 Ulf Brosziewski + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* * Mouse driver. */ @@ -112,28 +128,12 @@ extern int wsmuxdebug; #defineDPRINTFN(n,x) #endif -#defineINVALID_X INT_MAX -#defineINVALID_Y INT_MAX -#defineINVALID_Z INT_MAX -#defineINVALID_W INT_MAX - struct wsmouse_softc { struct wsevsrc sc_base; const struct wsmouse_accessops *sc_accessops; void*sc_accesscookie; - u_int sc_mb; /* mouse button state */ - u_int sc_ub; /* user button state */ - int sc_dx; /* delta-x */ - int sc_dy; /* delta-y */ - int sc_dz; /* delta-z */ - int sc_dw; /* delta-w */ - int sc_x; /* absolute-x */ - int sc_y; /* absolute-y */ - int sc_z; /* absolute-z */ - int sc_w; /* absolute-w */ - struct wsmouseinput input; int sc_refcnt; @@ -290,200 +290,6 @@ wsmouse_detach(struct device *self, int return (0); } -void -wsmouse_input(struct device *wsmousedev, u_int btns, /* 0 is up */ -int x, int y, int z, int w, u_int flags) -{ - struct wsmouse_softc *sc = (struct wsmouse_softc *)wsmousedev; - struct wscons_event *ev; - struct wseventvar *evar; - int mb, ub, d, get, put, any; - - add_mouse_randomness(x ^ y ^ z ^ w ^ btns); - - /* -* Discard input if not ready. -*/ - evar = sc->sc_base.me_evp; - if (evar == NULL) - return; - -#ifdef DIAGNOSTIC - if (evar->q == NULL) { - printf("wsmouse_input: evar->q=NULL\n"); - return; - } -#endif - -#if NWSMUX > 0 - DPRINTFN(5,("wsmouse_input: %s mux=%p, evar=%p\n", - sc->sc_base.me_dv.dv_xname, sc->sc_base.me_parent, evar)); -#endif - - sc->sc_mb = btns; - if (!(flags & WSMOUSE_INPUT_ABSOLUTE_X)) - sc->sc_dx += x; - if (!(flags & WSMOUSE_INPUT_ABSOLUTE_Y)) - sc->sc_dy += y; - if (!(flags & WSMOUSE_INPUT_ABSOLUTE_Z)) - sc->sc_dz += z; - if (!(flags & WSMOUSE_INPUT_ABSOLUTE_W)) - sc->sc_dw += w; - - /* -* We have at least one event (mouse button, delta-X, or -* delta-Y; possibly all three, and possibly three separate -* button events). Deliver these events until we are out -* of changes or out of room. As events get delivered, -* mark them `unchanged'. -*/ - ub = sc->sc_ub; - any = 0; - get = evar->get; - put = evar->put; - ev = >q[put]; - - /* NEXT prepares to put the next event, backing off if necessary */ -#defineNEXT \ - if ((++put) % WSEVENT_QSIZE == get) { \ - put--; \ - goto out; \ - } - /* ADVANCE completes the `put' of the event */ -#defineADVANCE \ - ev++; \ - if (put >= WSEVENT_QSIZE) { \ - put = 0;\ - ev = >q[0]; \ - } \ - any
Re: removing wsmouse_input [2]: zts, hilms, uts
Again, I think the risk is small. A test with hilms would have been nice, of course (unfortunately, I didn't succeed in contacting Miod). On 06/05/16 10:38, Stefan Sperling wrote: > On Sun, Jun 05, 2016 at 09:55:07AM +0200, Ulf Brosziewski wrote: >> ok? > > Again, I can't test this, but it's ok by me. > > I like the new wsmouse interface a lot better than the old one. > >> On 06/01/2016 01:23 AM, Ulf Brosziewski wrote: >>> zts, hilms, and uts are the drivers that still use wsmouse_input >>> with absolute coordinates (or with both types of coordinates). >>> The new, "flag-less" interface of wsmouse requires calls of >>> wsmouse_position, and, possibly, of wsmouse_touch in this case. >>> >>> Questions, tests and OKs would be welcome. >>> >>> >>> Index: arch/zaurus/dev/zts.c >>> === >>> RCS file: /cvs/src/sys/arch/zaurus/dev/zts.c,v >>> retrieving revision 1.16 >>> diff -u -p -r1.16 zts.c >>> --- arch/zaurus/dev/zts.c 29 Mar 2014 18:09:30 - 1.16 >>> +++ arch/zaurus/dev/zts.c 31 May 2016 19:23:10 - >>> @@ -544,10 +544,9 @@ zts_irq(void *v) >>> DPRINTF(("%s: tp.z = %d, tp.x = %d, tp.y = %d\n", >>> sc->sc_dev.dv_xname, tp.z, tp.x, tp.y)); >>> >>> - wsmouse_input(sc->sc_wsmousedev, down, tp.x, tp.y, >>> - 0 /* z */, 0 /* w */, >>> - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | >>> - WSMOUSE_INPUT_ABSOLUTE_Z); >>> + wsmouse_buttons(sc->sc_wsmousedev, down); >>> + wsmouse_position(sc->sc_wsmousedev, tp.x, tp.y); >>> + wsmouse_input_sync(sc->sc_wsmousedev); >>> sc->sc_buttons = down; >>> sc->sc_oldx = tp.x; >>> sc->sc_oldy = tp.y; >>> Index: dev/hil/hilms.c >>> === >>> RCS file: /cvs/src/sys/dev/hil/hilms.c,v >>> retrieving revision 1.5 >>> diff -u -p -r1.5 hilms.c >>> --- dev/hil/hilms.c 10 Apr 2007 22:37:17 - 1.5 >>> +++ dev/hil/hilms.c 31 May 2016 19:23:10 - >>> @@ -219,7 +219,7 @@ void >>> hilms_callback(struct hildev_softc *dev, u_int buflen, u_int8_t *buf) >>> { >>> struct hilms_softc *sc = (struct hilms_softc *)dev; >>> - int type, flags; >>> + int type; >>> int dx, dy, dz, button; >>> #ifdef DIAGNOSTIC >>> int minlen; >>> @@ -256,9 +256,6 @@ hilms_callback(struct hildev_softc *dev, >>> */ >>> >>> if (type & HIL_MOUSEMOTION) { >>> - flags = sc->sc_features & HIL_ABSOLUTE ? >>> - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | >>> - WSMOUSE_INPUT_ABSOLUTE_Z : WSMOUSE_INPUT_DELTA; >>> if (sc->sc_features & HIL_16_BITS) { >>> dx = *buf++; >>> dx |= (*buf++) << 8; >>> @@ -302,8 +299,7 @@ hilms_callback(struct hildev_softc *dev, >>> if ((sc->sc_features & HIL_ABSOLUTE) == 0 && >>> sc->sc_buttons == 0) >>> dy = -dy; >>> - } else >>> - dx = dy = dz = flags = 0; >>> + } >>> >>> if (type & HIL_MOUSEBUTTON) { >>> button = *buf; >>> @@ -332,7 +328,18 @@ hilms_callback(struct hildev_softc *dev, >>> /* buf++; */ >>> } >>> >>> - if (sc->sc_wsmousedev != NULL) >>> - wsmouse_input(sc->sc_wsmousedev, >>> - sc->sc_buttonstate, dx, dy, dz, 0, flags); >>> + if (sc->sc_wsmousedev == NULL) >>> + return; >>> + >>> + wsmouse_buttons(sc->sc_wsmousedev, sc->sc_buttonstate); >>> + if (type & HIL_MOUSEMOTION) { >>> + if ((sc->sc_features & HIL_ABSOLUTE) == 0) { >>> + wsmouse_motion(sc->sc_wsmousedev, dx, dy, dz, 0); >>> + } else { >>> + wsmouse_position(sc->sc_wsmousedev, dx, dy); >>> + if (sc->sc_axes > 2) >>> + wsmouse_touch(sc->sc_wsmousedev, dz, 0); >>> + } >>> + } >>> + wsmouse_input_sync(sc->sc_wsmousedev); >>> } >>> Index: dev/usb/uts.c >>> === >>> RCS file: /cvs/src/sys/dev/usb/uts.c,v >>> retrieving revision 1.37 >>> diff -u -p -r1.37 uts.c >>> --- dev/usb/uts.c 10 Feb 2016 05:49:50 - 1.37 >>> +++ dev/usb/uts.c 31 May 2016 19:23:12 - >>> @@ -476,9 +476,7 @@ uts_intr(struct usbd_xfer *xfer, void *a >>> DPRINTF(("%s: tp.down = %d, tp.z = %d, tp.x = %d, tp.y = %d\n", >>> sc->sc_dev.dv_xname, tp.down, tp.z, tp.x, tp.y)); >>> >>> - wsmouse_input(sc->sc_wsmousedev, tp.down, tp.x, tp.y, tp.z, 0, >>> - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | >>> - WSMOUSE_INPUT_ABSOLUTE_Z); >>> + WSMOUSE_TOUCH(sc->sc_wsmousedev, tp.down, tp.x, tp.y, tp.z, 0); >>> sc->sc_oldy = tp.y; >>> sc->sc_oldx = tp.x; >>> >>> >>> >> >
Re: removing wsmouse_input [1]
The changes are simple, the functions are already in use and no regressions are known; if nobody insists on tests, I will commit that soon. On 06/05/16 10:36, Stefan Sperling wrote: > On Sun, Jun 05, 2016 at 09:54:55AM +0200, Ulf Brosziewski wrote: >> ok? >> > > Looks good, ok by me. > > I don't think I have any of these devices, though, so I can't test. > >> On 06/01/2016 01:21 AM, Ulf Brosziewski wrote: >>> These diffs adapt various drivers to the new input functions of >>> wsmouse, namely >>> arch/i386/isa/lms.c, >>> arch/i386/isa/mms.c, >>> arch/luna88k/dev/lunaws.c, >>> arch/sgi/hpc/z8530ms.c, >>> dev/adb/ams.c, >>> dev/sun/sunms.c, and >>> dev/usb/utpms.c. >>> Each of the diffs just replaces wsmouse_input with the WSMOUSE_INPUT >>> macro, which reports inputs with relative coordinates to wsmouse >>> (I will post a second set of diffs for drivers that handle absolute >>> coordinates). >>> >>> Tests and/or OKs would be welcome. >>> >>> >>> Index: arch/i386/isa/lms.c >>> === >>> RCS file: /cvs/src/sys/arch/i386/isa/lms.c,v >>> retrieving revision 1.20 >>> diff -u -p -r1.20 lms.c >>> --- arch/i386/isa/lms.c 10 Apr 2007 22:37:17 - 1.20 >>> +++ arch/i386/isa/lms.c 31 May 2016 19:23:09 - >>> @@ -235,8 +235,7 @@ lmsintr(void *arg) >>> sc->oldbuttons = buttons; >>> >>> if (dx || dy || changed) >>> - wsmouse_input(sc->sc_wsmousedev, >>> - buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); >>> + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, 0, 0); >>> >>> return -1; >>> } >>> Index: arch/i386/isa/mms.c >>> === >>> RCS file: /cvs/src/sys/arch/i386/isa/mms.c,v >>> retrieving revision 1.19 >>> diff -u -p -r1.19 mms.c >>> --- arch/i386/isa/mms.c 10 Apr 2007 22:37:17 - 1.19 >>> +++ arch/i386/isa/mms.c 31 May 2016 19:23:09 - >>> @@ -229,8 +229,7 @@ mmsintr(void *arg) >>> changed = status & 0x38; >>> >>> if (dx || dy || changed) >>> - wsmouse_input(sc->sc_wsmousedev, >>> - buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); >>> + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, 0, 0); >>> >>> return -1; >>> } >>> Index: arch/luna88k/dev/lunaws.c >>> === >>> RCS file: /cvs/src/sys/arch/luna88k/dev/lunaws.c,v >>> retrieving revision 1.11 >>> diff -u -p -r1.11 lunaws.c >>> --- arch/luna88k/dev/lunaws.c 7 Jun 2014 11:55:35 - 1.11 >>> +++ arch/luna88k/dev/lunaws.c 31 May 2016 19:23:09 - >>> @@ -260,9 +260,8 @@ wsintr(int chan) >>> else if (sc->sc_msreport == 2) { >>> sc->dy = (signed char)code; >>> if (sc->sc_wsmousedev != NULL) >>> - wsmouse_input(sc->sc_wsmousedev, >>> - sc->buttons, sc->dx, sc->dy, 0, 0, >>> - WSMOUSE_INPUT_DELTA); >>> + WSMOUSE_INPUT(sc->sc_wsmousedev, >>> + sc->buttons, sc->dx, sc->dy, 0, 0); >>> sc->sc_msreport = 0; >>> } >>> #else >>> Index: arch/sgi/hpc/z8530ms.c >>> === >>> RCS file: /cvs/src/sys/arch/sgi/hpc/z8530ms.c,v >>> retrieving revision 1.1 >>> diff -u -p -r1.1 z8530ms.c >>> --- arch/sgi/hpc/z8530ms.c 17 Apr 2012 22:06:33 - 1.1 >>> +++ arch/sgi/hpc/z8530ms.c 31 May 2016 19:23:09 - >>> @@ -296,7 +296,7 @@ zsms_wsmouse_input(struct zsms_softc *sc >>> x = (int)sc->packet[ZSMS_PACKET_X1] + (int)sc->packet[ZSMS_PACKET_X2]; >>> y = (int)sc->packet[ZSMS_PACKET_Y1] + (int)sc->packet[ZSMS_PACKET_Y2]; >>> >>> - wsmouse_input(sc->wsmousedev, btns, x, y, 0, 0, WSMOUSE_INPUT_DELTA); >>> + WSMOUSE_INPUT(sc->wsmousedev, btns, x, y, 0, 0); >>> } >>> >
Re: removing wsmouse_input [2]: zts, hilms, uts
ok? On 06/01/2016 01:23 AM, Ulf Brosziewski wrote: > zts, hilms, and uts are the drivers that still use wsmouse_input > with absolute coordinates (or with both types of coordinates). > The new, "flag-less" interface of wsmouse requires calls of > wsmouse_position, and, possibly, of wsmouse_touch in this case. > > Questions, tests and OKs would be welcome. > > > Index: arch/zaurus/dev/zts.c > === > RCS file: /cvs/src/sys/arch/zaurus/dev/zts.c,v > retrieving revision 1.16 > diff -u -p -r1.16 zts.c > --- arch/zaurus/dev/zts.c 29 Mar 2014 18:09:30 - 1.16 > +++ arch/zaurus/dev/zts.c 31 May 2016 19:23:10 - > @@ -544,10 +544,9 @@ zts_irq(void *v) > DPRINTF(("%s: tp.z = %d, tp.x = %d, tp.y = %d\n", > sc->sc_dev.dv_xname, tp.z, tp.x, tp.y)); > > - wsmouse_input(sc->sc_wsmousedev, down, tp.x, tp.y, > - 0 /* z */, 0 /* w */, > - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | > - WSMOUSE_INPUT_ABSOLUTE_Z); > + wsmouse_buttons(sc->sc_wsmousedev, down); > + wsmouse_position(sc->sc_wsmousedev, tp.x, tp.y); > + wsmouse_input_sync(sc->sc_wsmousedev); > sc->sc_buttons = down; > sc->sc_oldx = tp.x; > sc->sc_oldy = tp.y; > Index: dev/hil/hilms.c > === > RCS file: /cvs/src/sys/dev/hil/hilms.c,v > retrieving revision 1.5 > diff -u -p -r1.5 hilms.c > --- dev/hil/hilms.c 10 Apr 2007 22:37:17 - 1.5 > +++ dev/hil/hilms.c 31 May 2016 19:23:10 - > @@ -219,7 +219,7 @@ void > hilms_callback(struct hildev_softc *dev, u_int buflen, u_int8_t *buf) > { > struct hilms_softc *sc = (struct hilms_softc *)dev; > - int type, flags; > + int type; > int dx, dy, dz, button; > #ifdef DIAGNOSTIC > int minlen; > @@ -256,9 +256,6 @@ hilms_callback(struct hildev_softc *dev, >*/ > > if (type & HIL_MOUSEMOTION) { > - flags = sc->sc_features & HIL_ABSOLUTE ? > - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | > - WSMOUSE_INPUT_ABSOLUTE_Z : WSMOUSE_INPUT_DELTA; > if (sc->sc_features & HIL_16_BITS) { > dx = *buf++; > dx |= (*buf++) << 8; > @@ -302,8 +299,7 @@ hilms_callback(struct hildev_softc *dev, > if ((sc->sc_features & HIL_ABSOLUTE) == 0 && > sc->sc_buttons == 0) > dy = -dy; > - } else > - dx = dy = dz = flags = 0; > + } > > if (type & HIL_MOUSEBUTTON) { > button = *buf; > @@ -332,7 +328,18 @@ hilms_callback(struct hildev_softc *dev, > /* buf++; */ > } > > - if (sc->sc_wsmousedev != NULL) > - wsmouse_input(sc->sc_wsmousedev, > - sc->sc_buttonstate, dx, dy, dz, 0, flags); > + if (sc->sc_wsmousedev == NULL) > + return; > + > + wsmouse_buttons(sc->sc_wsmousedev, sc->sc_buttonstate); > + if (type & HIL_MOUSEMOTION) { > + if ((sc->sc_features & HIL_ABSOLUTE) == 0) { > + wsmouse_motion(sc->sc_wsmousedev, dx, dy, dz, 0); > + } else { > + wsmouse_position(sc->sc_wsmousedev, dx, dy); > + if (sc->sc_axes > 2) > + wsmouse_touch(sc->sc_wsmousedev, dz, 0); > + } > + } > + wsmouse_input_sync(sc->sc_wsmousedev); > } > Index: dev/usb/uts.c > === > RCS file: /cvs/src/sys/dev/usb/uts.c,v > retrieving revision 1.37 > diff -u -p -r1.37 uts.c > --- dev/usb/uts.c 10 Feb 2016 05:49:50 - 1.37 > +++ dev/usb/uts.c 31 May 2016 19:23:12 - > @@ -476,9 +476,7 @@ uts_intr(struct usbd_xfer *xfer, void *a > DPRINTF(("%s: tp.down = %d, tp.z = %d, tp.x = %d, tp.y = %d\n", > sc->sc_dev.dv_xname, tp.down, tp.z, tp.x, tp.y)); > > - wsmouse_input(sc->sc_wsmousedev, tp.down, tp.x, tp.y, tp.z, 0, > - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | > - WSMOUSE_INPUT_ABSOLUTE_Z); > + WSMOUSE_TOUCH(sc->sc_wsmousedev, tp.down, tp.x, tp.y, tp.z, 0); > sc->sc_oldy = tp.y; > sc->sc_oldx = tp.x; > > >
Re: removing wsmouse_input [1]
ok? On 06/01/2016 01:21 AM, Ulf Brosziewski wrote: > These diffs adapt various drivers to the new input functions of > wsmouse, namely > arch/i386/isa/lms.c, > arch/i386/isa/mms.c, > arch/luna88k/dev/lunaws.c, > arch/sgi/hpc/z8530ms.c, > dev/adb/ams.c, > dev/sun/sunms.c, and > dev/usb/utpms.c. > Each of the diffs just replaces wsmouse_input with the WSMOUSE_INPUT > macro, which reports inputs with relative coordinates to wsmouse > (I will post a second set of diffs for drivers that handle absolute > coordinates). > > Tests and/or OKs would be welcome. > > > Index: arch/i386/isa/lms.c > === > RCS file: /cvs/src/sys/arch/i386/isa/lms.c,v > retrieving revision 1.20 > diff -u -p -r1.20 lms.c > --- arch/i386/isa/lms.c 10 Apr 2007 22:37:17 - 1.20 > +++ arch/i386/isa/lms.c 31 May 2016 19:23:09 - > @@ -235,8 +235,7 @@ lmsintr(void *arg) > sc->oldbuttons = buttons; > > if (dx || dy || changed) > - wsmouse_input(sc->sc_wsmousedev, > - buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); > + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, 0, 0); > > return -1; > } > Index: arch/i386/isa/mms.c > === > RCS file: /cvs/src/sys/arch/i386/isa/mms.c,v > retrieving revision 1.19 > diff -u -p -r1.19 mms.c > --- arch/i386/isa/mms.c 10 Apr 2007 22:37:17 - 1.19 > +++ arch/i386/isa/mms.c 31 May 2016 19:23:09 - > @@ -229,8 +229,7 @@ mmsintr(void *arg) > changed = status & 0x38; > > if (dx || dy || changed) > - wsmouse_input(sc->sc_wsmousedev, > - buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); > + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, 0, 0); > > return -1; > } > Index: arch/luna88k/dev/lunaws.c > === > RCS file: /cvs/src/sys/arch/luna88k/dev/lunaws.c,v > retrieving revision 1.11 > diff -u -p -r1.11 lunaws.c > --- arch/luna88k/dev/lunaws.c 7 Jun 2014 11:55:35 - 1.11 > +++ arch/luna88k/dev/lunaws.c 31 May 2016 19:23:09 - > @@ -260,9 +260,8 @@ wsintr(int chan) > else if (sc->sc_msreport == 2) { > sc->dy = (signed char)code; > if (sc->sc_wsmousedev != NULL) > - wsmouse_input(sc->sc_wsmousedev, > - sc->buttons, sc->dx, sc->dy, 0, 0, > - WSMOUSE_INPUT_DELTA); > + WSMOUSE_INPUT(sc->sc_wsmousedev, > + sc->buttons, sc->dx, sc->dy, 0, 0); > sc->sc_msreport = 0; > } > #else > Index: arch/sgi/hpc/z8530ms.c > === > RCS file: /cvs/src/sys/arch/sgi/hpc/z8530ms.c,v > retrieving revision 1.1 > diff -u -p -r1.1 z8530ms.c > --- arch/sgi/hpc/z8530ms.c17 Apr 2012 22:06:33 - 1.1 > +++ arch/sgi/hpc/z8530ms.c31 May 2016 19:23:09 - > @@ -296,7 +296,7 @@ zsms_wsmouse_input(struct zsms_softc *sc > x = (int)sc->packet[ZSMS_PACKET_X1] + (int)sc->packet[ZSMS_PACKET_X2]; > y = (int)sc->packet[ZSMS_PACKET_Y1] + (int)sc->packet[ZSMS_PACKET_Y2]; > > - wsmouse_input(sc->wsmousedev, btns, x, y, 0, 0, WSMOUSE_INPUT_DELTA); > + WSMOUSE_INPUT(sc->wsmousedev, btns, x, y, 0, 0); > } > > int > Index: dev/adb/ams.c > === > RCS file: /cvs/src/sys/dev/adb/ams.c,v > retrieving revision 1.6 > diff -u -p -r1.6 ams.c > --- dev/adb/ams.c 15 Jun 2011 21:32:05 - 1.6 > +++ dev/adb/ams.c 31 May 2016 19:23:10 - > @@ -501,8 +501,7 @@ ms_processevent(adb_event_t *event, stru > ((event->bytes[0] & 0x40) ? 64 : 0); > > if (sc->sc_wsmousedev) > - wsmouse_input(sc->sc_wsmousedev, buttons, dx, -dy, 0, 0, > - WSMOUSE_INPUT_DELTA); > + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, -dy, 0, 0); > } > > int > Index: dev/sun/sunms.c > === > RCS file: /cvs/src/sys/dev/sun/sunms.c,v > retrieving revision 1.1 > diff -u -p -r1.1 sunms.c > --- dev/sun/sunms.c 20 May 2009 18:22:33 - 1.1 > +++ dev/sun/sunms.c 31 Ma
removing wsmouse_input [2]: zts, hilms, uts
zts, hilms, and uts are the drivers that still use wsmouse_input with absolute coordinates (or with both types of coordinates). The new, "flag-less" interface of wsmouse requires calls of wsmouse_position, and, possibly, of wsmouse_touch in this case. Questions, tests and OKs would be welcome. Index: arch/zaurus/dev/zts.c === RCS file: /cvs/src/sys/arch/zaurus/dev/zts.c,v retrieving revision 1.16 diff -u -p -r1.16 zts.c --- arch/zaurus/dev/zts.c 29 Mar 2014 18:09:30 - 1.16 +++ arch/zaurus/dev/zts.c 31 May 2016 19:23:10 - @@ -544,10 +544,9 @@ zts_irq(void *v) DPRINTF(("%s: tp.z = %d, tp.x = %d, tp.y = %d\n", sc->sc_dev.dv_xname, tp.z, tp.x, tp.y)); - wsmouse_input(sc->sc_wsmousedev, down, tp.x, tp.y, - 0 /* z */, 0 /* w */, - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | - WSMOUSE_INPUT_ABSOLUTE_Z); + wsmouse_buttons(sc->sc_wsmousedev, down); + wsmouse_position(sc->sc_wsmousedev, tp.x, tp.y); + wsmouse_input_sync(sc->sc_wsmousedev); sc->sc_buttons = down; sc->sc_oldx = tp.x; sc->sc_oldy = tp.y; Index: dev/hil/hilms.c === RCS file: /cvs/src/sys/dev/hil/hilms.c,v retrieving revision 1.5 diff -u -p -r1.5 hilms.c --- dev/hil/hilms.c 10 Apr 2007 22:37:17 - 1.5 +++ dev/hil/hilms.c 31 May 2016 19:23:10 - @@ -219,7 +219,7 @@ void hilms_callback(struct hildev_softc *dev, u_int buflen, u_int8_t *buf) { struct hilms_softc *sc = (struct hilms_softc *)dev; - int type, flags; + int type; int dx, dy, dz, button; #ifdef DIAGNOSTIC int minlen; @@ -256,9 +256,6 @@ hilms_callback(struct hildev_softc *dev, */ if (type & HIL_MOUSEMOTION) { - flags = sc->sc_features & HIL_ABSOLUTE ? - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | - WSMOUSE_INPUT_ABSOLUTE_Z : WSMOUSE_INPUT_DELTA; if (sc->sc_features & HIL_16_BITS) { dx = *buf++; dx |= (*buf++) << 8; @@ -302,8 +299,7 @@ hilms_callback(struct hildev_softc *dev, if ((sc->sc_features & HIL_ABSOLUTE) == 0 && sc->sc_buttons == 0) dy = -dy; - } else - dx = dy = dz = flags = 0; + } if (type & HIL_MOUSEBUTTON) { button = *buf; @@ -332,7 +328,18 @@ hilms_callback(struct hildev_softc *dev, /* buf++; */ } - if (sc->sc_wsmousedev != NULL) - wsmouse_input(sc->sc_wsmousedev, - sc->sc_buttonstate, dx, dy, dz, 0, flags); + if (sc->sc_wsmousedev == NULL) + return; + + wsmouse_buttons(sc->sc_wsmousedev, sc->sc_buttonstate); + if (type & HIL_MOUSEMOTION) { + if ((sc->sc_features & HIL_ABSOLUTE) == 0) { + wsmouse_motion(sc->sc_wsmousedev, dx, dy, dz, 0); + } else { + wsmouse_position(sc->sc_wsmousedev, dx, dy); + if (sc->sc_axes > 2) + wsmouse_touch(sc->sc_wsmousedev, dz, 0); + } + } + wsmouse_input_sync(sc->sc_wsmousedev); } Index: dev/usb/uts.c === RCS file: /cvs/src/sys/dev/usb/uts.c,v retrieving revision 1.37 diff -u -p -r1.37 uts.c --- dev/usb/uts.c 10 Feb 2016 05:49:50 - 1.37 +++ dev/usb/uts.c 31 May 2016 19:23:12 - @@ -476,9 +476,7 @@ uts_intr(struct usbd_xfer *xfer, void *a DPRINTF(("%s: tp.down = %d, tp.z = %d, tp.x = %d, tp.y = %d\n", sc->sc_dev.dv_xname, tp.down, tp.z, tp.x, tp.y)); - wsmouse_input(sc->sc_wsmousedev, tp.down, tp.x, tp.y, tp.z, 0, - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | - WSMOUSE_INPUT_ABSOLUTE_Z); + WSMOUSE_TOUCH(sc->sc_wsmousedev, tp.down, tp.x, tp.y, tp.z, 0); sc->sc_oldy = tp.y; sc->sc_oldx = tp.x;
removing wsmouse_input [1]
These diffs adapt various drivers to the new input functions of wsmouse, namely arch/i386/isa/lms.c, arch/i386/isa/mms.c, arch/luna88k/dev/lunaws.c, arch/sgi/hpc/z8530ms.c, dev/adb/ams.c, dev/sun/sunms.c, and dev/usb/utpms.c. Each of the diffs just replaces wsmouse_input with the WSMOUSE_INPUT macro, which reports inputs with relative coordinates to wsmouse (I will post a second set of diffs for drivers that handle absolute coordinates). Tests and/or OKs would be welcome. Index: arch/i386/isa/lms.c === RCS file: /cvs/src/sys/arch/i386/isa/lms.c,v retrieving revision 1.20 diff -u -p -r1.20 lms.c --- arch/i386/isa/lms.c 10 Apr 2007 22:37:17 - 1.20 +++ arch/i386/isa/lms.c 31 May 2016 19:23:09 - @@ -235,8 +235,7 @@ lmsintr(void *arg) sc->oldbuttons = buttons; if (dx || dy || changed) - wsmouse_input(sc->sc_wsmousedev, - buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, 0, 0); return -1; } Index: arch/i386/isa/mms.c === RCS file: /cvs/src/sys/arch/i386/isa/mms.c,v retrieving revision 1.19 diff -u -p -r1.19 mms.c --- arch/i386/isa/mms.c 10 Apr 2007 22:37:17 - 1.19 +++ arch/i386/isa/mms.c 31 May 2016 19:23:09 - @@ -229,8 +229,7 @@ mmsintr(void *arg) changed = status & 0x38; if (dx || dy || changed) - wsmouse_input(sc->sc_wsmousedev, - buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, 0, 0); return -1; } Index: arch/luna88k/dev/lunaws.c === RCS file: /cvs/src/sys/arch/luna88k/dev/lunaws.c,v retrieving revision 1.11 diff -u -p -r1.11 lunaws.c --- arch/luna88k/dev/lunaws.c 7 Jun 2014 11:55:35 - 1.11 +++ arch/luna88k/dev/lunaws.c 31 May 2016 19:23:09 - @@ -260,9 +260,8 @@ wsintr(int chan) else if (sc->sc_msreport == 2) { sc->dy = (signed char)code; if (sc->sc_wsmousedev != NULL) - wsmouse_input(sc->sc_wsmousedev, - sc->buttons, sc->dx, sc->dy, 0, 0, - WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, + sc->buttons, sc->dx, sc->dy, 0, 0); sc->sc_msreport = 0; } #else Index: arch/sgi/hpc/z8530ms.c === RCS file: /cvs/src/sys/arch/sgi/hpc/z8530ms.c,v retrieving revision 1.1 diff -u -p -r1.1 z8530ms.c --- arch/sgi/hpc/z8530ms.c 17 Apr 2012 22:06:33 - 1.1 +++ arch/sgi/hpc/z8530ms.c 31 May 2016 19:23:09 - @@ -296,7 +296,7 @@ zsms_wsmouse_input(struct zsms_softc *sc x = (int)sc->packet[ZSMS_PACKET_X1] + (int)sc->packet[ZSMS_PACKET_X2]; y = (int)sc->packet[ZSMS_PACKET_Y1] + (int)sc->packet[ZSMS_PACKET_Y2]; - wsmouse_input(sc->wsmousedev, btns, x, y, 0, 0, WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->wsmousedev, btns, x, y, 0, 0); } int Index: dev/adb/ams.c === RCS file: /cvs/src/sys/dev/adb/ams.c,v retrieving revision 1.6 diff -u -p -r1.6 ams.c --- dev/adb/ams.c 15 Jun 2011 21:32:05 - 1.6 +++ dev/adb/ams.c 31 May 2016 19:23:10 - @@ -501,8 +501,7 @@ ms_processevent(adb_event_t *event, stru ((event->bytes[0] & 0x40) ? 64 : 0); if (sc->sc_wsmousedev) - wsmouse_input(sc->sc_wsmousedev, buttons, dx, -dy, 0, 0, - WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, -dy, 0, 0); } int Index: dev/sun/sunms.c === RCS file: /cvs/src/sys/dev/sun/sunms.c,v retrieving revision 1.1 diff -u -p -r1.1 sunms.c --- dev/sun/sunms.c 20 May 2009 18:22:33 - 1.1 +++ dev/sun/sunms.c 31 May 2016 19:23:12 - @@ -220,8 +220,8 @@ sunms_input(struct sunms_softc *sc, int if (sc->sc_byteno == sc->sc_pktlen) { timeout_del(>sc_abort_tmo); sc->sc_byteno = -1; - wsmouse_input(sc->sc_wsmousedev, sc->sc_mb, - sc->sc_dx, sc->sc_dy, 0, 0, WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, + sc->sc_mb, sc->sc_dx, sc->sc_dy, 0, 0); sc->sc_dx = sc->sc_dy = 0; } } Index: dev/usb/utpms.c === RCS file: /cvs/src/sys/dev/usb/utpms.c,v
Re: wsmouse_input: hidms, pms
Ping? Wouldn't it be nice if wsmouse were more coherent again in the next release? On 05/14/2016 04:46 PM, Ulf Brosziewski wrote: > The new input-processing functions of wsmouse seem to work well > for touchpads, and it might be time to update the mouse drivers > now. I start with the two drivers that I could test myself, hidms > (ums) and pms. > > Please note that hidms can mix, in principle, absolute and relative > coordinates. The new version doesn't change this property. I don't > know whether it is really necessary. > > OK? > > > Index: dev/hid/hidms.c > === > RCS file: /cvs/src/sys/dev/hid/hidms.c,v > retrieving revision 1.2 > diff -u -p -r1.2 hidms.c > --- dev/hid/hidms.c 10 Feb 2016 05:49:50 - 1.2 > +++ dev/hid/hidms.c 14 May 2016 13:47:06 - > @@ -331,7 +331,6 @@ hidms_input(struct hidms *ms, uint8_t *d > { > int dx, dy, dz, dw; > u_int32_t buttons = 0; > - int flags; > int i, s; > > DPRINTFN(5,("hidms_input: len=%d\n", len)); > @@ -358,12 +357,6 @@ hidms_input(struct hidms *ms, uint8_t *d > return; > } > > - flags = WSMOUSE_INPUT_DELTA; > - if (ms->sc_flags & HIDMS_ABSX) > - flags |= WSMOUSE_INPUT_ABSOLUTE_X; > - if (ms->sc_flags & HIDMS_ABSY) > - flags |= WSMOUSE_INPUT_ABSOLUTE_Y; > - > dx = hid_get_data(data, len, >sc_loc_x); > dy = -hid_get_data(data, len, >sc_loc_y); > dz = hid_get_data(data, len, >sc_loc_z); > @@ -403,8 +396,18 @@ hidms_input(struct hidms *ms, uint8_t *d > ms->sc_buttons = buttons; > if (ms->sc_wsmousedev != NULL) { > s = spltty(); > - wsmouse_input(ms->sc_wsmousedev, buttons, > - dx, dy, dz, dw, flags); > + if (ms->sc_flags & HIDMS_ABSX) { > + wsmouse_set(ms->sc_wsmousedev, > + WSMOUSE_ABS_X, dx, 0); > + dx = 0; > + } > + if (ms->sc_flags & HIDMS_ABSY) { > + wsmouse_set(ms->sc_wsmousedev, > + WSMOUSE_ABS_Y, dy, 0); > + dy = 0; > + } > + WSMOUSE_INPUT(ms->sc_wsmousedev, > + buttons, dx, dy, dz, dw); > splx(s); > } > } > Index: dev/pckbc/pms.c > === > RCS file: /cvs/src/sys/dev/pckbc/pms.c,v > retrieving revision 1.69 > diff -u -p -r1.69 pms.c > --- dev/pckbc/pms.c 30 Mar 2016 23:34:12 - 1.69 > +++ dev/pckbc/pms.c 14 May 2016 13:47:06 - > @@ -632,8 +632,7 @@ pms_proc_mouse(struct pms_softc *sc) > else > dz = 0; > > - wsmouse_input(sc->sc_wsmousedev, > - buttons, dx, dy, dz, 0, WSMOUSE_INPUT_DELTA); > + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, dz, 0); > } > > int > >
wsmouse_input: hidms, pms
The new input-processing functions of wsmouse seem to work well for touchpads, and it might be time to update the mouse drivers now. I start with the two drivers that I could test myself, hidms (ums) and pms. Please note that hidms can mix, in principle, absolute and relative coordinates. The new version doesn't change this property. I don't know whether it is really necessary. OK? Index: dev/hid/hidms.c === RCS file: /cvs/src/sys/dev/hid/hidms.c,v retrieving revision 1.2 diff -u -p -r1.2 hidms.c --- dev/hid/hidms.c 10 Feb 2016 05:49:50 - 1.2 +++ dev/hid/hidms.c 14 May 2016 13:47:06 - @@ -331,7 +331,6 @@ hidms_input(struct hidms *ms, uint8_t *d { int dx, dy, dz, dw; u_int32_t buttons = 0; - int flags; int i, s; DPRINTFN(5,("hidms_input: len=%d\n", len)); @@ -358,12 +357,6 @@ hidms_input(struct hidms *ms, uint8_t *d return; } - flags = WSMOUSE_INPUT_DELTA; - if (ms->sc_flags & HIDMS_ABSX) - flags |= WSMOUSE_INPUT_ABSOLUTE_X; - if (ms->sc_flags & HIDMS_ABSY) - flags |= WSMOUSE_INPUT_ABSOLUTE_Y; - dx = hid_get_data(data, len, >sc_loc_x); dy = -hid_get_data(data, len, >sc_loc_y); dz = hid_get_data(data, len, >sc_loc_z); @@ -403,8 +396,18 @@ hidms_input(struct hidms *ms, uint8_t *d ms->sc_buttons = buttons; if (ms->sc_wsmousedev != NULL) { s = spltty(); - wsmouse_input(ms->sc_wsmousedev, buttons, - dx, dy, dz, dw, flags); + if (ms->sc_flags & HIDMS_ABSX) { + wsmouse_set(ms->sc_wsmousedev, + WSMOUSE_ABS_X, dx, 0); + dx = 0; + } + if (ms->sc_flags & HIDMS_ABSY) { + wsmouse_set(ms->sc_wsmousedev, + WSMOUSE_ABS_Y, dy, 0); + dy = 0; + } + WSMOUSE_INPUT(ms->sc_wsmousedev, + buttons, dx, dy, dz, dw); splx(s); } } Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.69 diff -u -p -r1.69 pms.c --- dev/pckbc/pms.c 30 Mar 2016 23:34:12 - 1.69 +++ dev/pckbc/pms.c 14 May 2016 13:47:06 - @@ -632,8 +632,7 @@ pms_proc_mouse(struct pms_softc *sc) else dz = 0; - wsmouse_input(sc->sc_wsmousedev, - buttons, dx, dy, dz, 0, WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, dz, 0); } int
Re: synaptics: two-finger scrolling and coasting
Ping? It isn't a severe bug and it doesn't concern a spectacular feature, but shouldn't we fix it? On 04/16/2016 06:01 PM, Ulf Brosziewski wrote: > The changes I have introduced in wsconscomm.c recently can make the > transition from two-finger scrolling to coasting somewhat difficult. > Provided that you have scrolled quickly enough, coasting will start > if you finish the scroll gesture by lifting both fingers simultaneously, > but a short delay will prevent coasting. When the contact count drops > from 2 to 1 a RESET event will occur, and the handler clears the scroll > flag. > > The diff below is a fix for this problem. The new version won't interrupt > or stop scrolling, rather it ensures that the current coordinate deltas > won't affect its speed or direction. I have tested it with my Elantech-v4 > touchpad. > > OK? > > > Index: src/wsconscomm.c > === > RCS file: /cvs/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c,v > retrieving revision 1.14 > diff -u -p -r1.14 wsconscomm.c > --- src/wsconscomm.c 30 Mar 2016 23:33:34 - 1.14 > +++ src/wsconscomm.c 16 Apr 2016 15:15:46 - > @@ -150,6 +150,21 @@ WSConsQueryHardware(InputInfoPtr pInfo) > return WSConsIsTouchpad(pInfo, NULL); > } > > +static void > +WSConsAdjustScrollCoords(SynapticsPrivate *priv, struct SynapticsHwState *hw) > +{ > +int dx, dy, i; > + > +dx = hw->x - priv->scroll.last_x; > +dy = hw->y - priv->scroll.last_y; > +priv->scroll.last_x = hw->x; > +priv->scroll.last_y = hw->y; > +for (i = 0; i < SYNAPTICS_MOVE_HISTORY; i++) { > +priv->move_hist[i].x += dx; > +priv->move_hist[i].y += dy; > +} > +} > + > static Bool > WSConsReadHwState(InputInfoPtr pInfo, > struct CommData *comm, struct SynapticsHwState *hwRet) > @@ -158,7 +173,7 @@ WSConsReadHwState(InputInfoPtr pInfo, > struct wsconscomm_proto_data *proto_data = priv->proto_data; > struct SynapticsHwState *hw = comm->hwState; > struct wscons_event *event; > -Bool v; > +Bool v, reset = FALSE; > > while ((event = WSConsGetEvent(pInfo)) != NULL) { > switch (event->type) { > @@ -229,15 +244,18 @@ WSConsReadHwState(InputInfoPtr pInfo, > hw->fingerWidth = event->value; > break; > case WSCONS_EVENT_TOUCH_RESET: > -/* > - * The contact count or the active MT-slot has changed. > - * Suppress pointer motion and two-finger scrolling. > - */ > -priv->count_packet_finger = 0; > -priv->vert_scroll_twofinger_on = FALSE; > -priv->horiz_scroll_twofinger_on = FALSE; > +/* The contact count or the active MT slot has changed. */ > +reset = TRUE; > break; > case WSCONS_EVENT_SYNC: > +if (reset) { > +/* Ensure that pointer motion stops. */ > +priv->count_packet_finger = 0; > +if (priv->vert_scroll_twofinger_on > +|| priv->horiz_scroll_twofinger_on) { > +WSConsAdjustScrollCoords(priv, hw); > +} > +} > hw->millis = 1000 * event->time.tv_sec + > event->time.tv_nsec / 100; > SynapticsCopyHwState(hwRet, hw); > >
synaptics: two-finger scrolling and coasting
The changes I have introduced in wsconscomm.c recently can make the transition from two-finger scrolling to coasting somewhat difficult. Provided that you have scrolled quickly enough, coasting will start if you finish the scroll gesture by lifting both fingers simultaneously, but a short delay will prevent coasting. When the contact count drops from 2 to 1 a RESET event will occur, and the handler clears the scroll flag. The diff below is a fix for this problem. The new version won't interrupt or stop scrolling, rather it ensures that the current coordinate deltas won't affect its speed or direction. I have tested it with my Elantech-v4 touchpad. OK? Index: src/wsconscomm.c === RCS file: /cvs/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c,v retrieving revision 1.14 diff -u -p -r1.14 wsconscomm.c --- src/wsconscomm.c30 Mar 2016 23:33:34 - 1.14 +++ src/wsconscomm.c16 Apr 2016 15:15:46 - @@ -150,6 +150,21 @@ WSConsQueryHardware(InputInfoPtr pInfo) return WSConsIsTouchpad(pInfo, NULL); } +static void +WSConsAdjustScrollCoords(SynapticsPrivate *priv, struct SynapticsHwState *hw) +{ +int dx, dy, i; + +dx = hw->x - priv->scroll.last_x; +dy = hw->y - priv->scroll.last_y; +priv->scroll.last_x = hw->x; +priv->scroll.last_y = hw->y; +for (i = 0; i < SYNAPTICS_MOVE_HISTORY; i++) { +priv->move_hist[i].x += dx; +priv->move_hist[i].y += dy; +} +} + static Bool WSConsReadHwState(InputInfoPtr pInfo, struct CommData *comm, struct SynapticsHwState *hwRet) @@ -158,7 +173,7 @@ WSConsReadHwState(InputInfoPtr pInfo, struct wsconscomm_proto_data *proto_data = priv->proto_data; struct SynapticsHwState *hw = comm->hwState; struct wscons_event *event; -Bool v; +Bool v, reset = FALSE; while ((event = WSConsGetEvent(pInfo)) != NULL) { switch (event->type) { @@ -229,15 +244,18 @@ WSConsReadHwState(InputInfoPtr pInfo, hw->fingerWidth = event->value; break; case WSCONS_EVENT_TOUCH_RESET: -/* - * The contact count or the active MT-slot has changed. - * Suppress pointer motion and two-finger scrolling. - */ -priv->count_packet_finger = 0; -priv->vert_scroll_twofinger_on = FALSE; -priv->horiz_scroll_twofinger_on = FALSE; +/* The contact count or the active MT slot has changed. */ +reset = TRUE; break; case WSCONS_EVENT_SYNC: +if (reset) { +/* Ensure that pointer motion stops. */ +priv->count_packet_finger = 0; +if (priv->vert_scroll_twofinger_on +|| priv->horiz_scroll_twofinger_on) { +WSConsAdjustScrollCoords(priv, hw); +} +} hw->millis = 1000 * event->time.tv_sec + event->time.tv_nsec / 100; SynapticsCopyHwState(hwRet, hw);
Re: multitouch support again
On 03/25/2016 01:53 PM, Theo Buehler wrote: > On Fri, Mar 25, 2016 at 01:47:07PM +0100, Matthieu Herrb wrote: >> On Thu, Mar 24, 2016 at 10:34:12PM +0100, Ulf Brosziewski wrote: >>> Are there any reviews, tests, OKs, or NOs pending? And if >>> not, may I ask if someone knows a better way to make progress >>> in this area? I'm at a loss here. As far as I can see, I >>> cannot offer a smaller diff; this one contains the minimum >>> that technically makes sense. And as it just adds the basics, >>> a lot of things remain that could and possibly should be done >>> soon, 6.0 isn't far away here. >> >> I've been running the previous version of your diff without problem. >> However, on my laptop (X2240) I can't figure out if the >> touchpad is supposed to support multitouch or not. >> > > Same here: I've been running the three patches you sent gzipped on my > Thinkpad T450 since you posted them and didn't notice any regression so > far. It just works as I expect it to. > Thanks. Verifying that the new input functions and the modified wsconscomm don't break anything is more or less all that can be done with these versions of my diffs. Synaptics touchpads are running in a mode that doesn't need the MT functions. Only Elantech-v4 models make use of them currently. ubcmtp and hidmt could apply it, but I haven't adapted the drivers, it is a bit less trivial than replacing the wsmouse_input call. If someone wants to do that, or could do the tests for me, please let me know (up to now, the wsmouse_mtframe and wsmouse_id_to_slot functions have only been tested with special versions of the elantech handler). >> I wanted to do more tests (comparing with Linux for instance) but I've >> lacked time so far. >> >> If you have some small test programs (or recipes based on xinput) >> to suggest I'll try that. > > Yes, it would be very helpful if you could give some good test cases and > instructions what to look for. > I don't have a very systematic way of testing touchpads. Usually I check "gestures" that involve changes of the contact count or - possibly - pointer-control, like two-finger scrolling (with two, one, or alternating fingers moving), click-and-drag actions with two fingers on clickpads (again, with alternating fingers moving), tapping, tap-and-drag, and tap-and-drag with "locked drags". >> Again, your work on this is much appreciated, even if it's true that >> we've not provided feedback... > > Seconded. > > Thanks again.
Re: multitouch support again
Again, my mail client insisted on the "flowed" text format, sorry. Here is a clean version of the diff. Index: src/wsconscomm.c === RCS file: /cvs/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c,v retrieving revision 1.13 diff -u -p -r1.13 wsconscomm.c --- src/wsconscomm.c29 Aug 2015 08:48:28 - 1.13 +++ src/wsconscomm.c11 Mar 2016 20:46:30 - @@ -215,45 +215,29 @@ WSConsReadHwState(InputInfoPtr pInfo, hw->y = priv->maxy - event->value + priv->miny; hw->cumulative_dy = hw->y; break; -case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: +case WSCONS_EVENT_TOUCH_PRESSURE: hw->z = event->value; break; -case WSCONS_EVENT_MOUSE_ABSOLUTE_W: -if (priv->model == MODEL_ELANTECH) { -/* Elantech touchpads report number of fingers directly. */ -hw->fingerWidth = 5; -hw->numFingers = event->value; -break; -} -/* XXX magic number mapping which is mirrored in pms driver */ -switch (event->value) { -case 0: -hw->fingerWidth = 5; -hw->numFingers = 2; -break; -case 1: +case WSCONS_EVENT_TOUCH_CONTACTS: +hw->numFingers = event->value; +if (hw->numFingers == 0) +hw->fingerWidth = 0; +else if (hw->fingerWidth == 0) hw->fingerWidth = 5; -hw->numFingers = 3; -break; -case 4 ... 5: -hw->fingerWidth = event->value; -hw->numFingers = 1; -break; -} +break; +case WSCONS_EVENT_TOUCH_WIDTH: +hw->fingerWidth = event->value; +break; +case WSCONS_EVENT_TOUCH_RESET: +/* + * The contact count or the active MT-slot has changed. + * Suppress pointer motion and two-finger scrolling. + */ +priv->count_packet_finger = 0; +priv->vert_scroll_twofinger_on = FALSE; +priv->horiz_scroll_twofinger_on = FALSE; break; case WSCONS_EVENT_SYNC: -if (hw->z == 0) { -hw->fingerWidth = 0; -hw->numFingers = 0; -} else if (hw->numFingers == 0) { -/* - * Because W may be 0 already, a two-finger touch on a - * Synaptics touchpad doesn't necessarily produce an update - * event for W. - */ -hw->fingerWidth = 5; -hw->numFingers = 2; -} hw->millis = 1000 * event->time.tv_sec + event->time.tv_nsec / 100; SynapticsCopyHwState(hwRet, hw); Index: dev/hid/hidmt.c === RCS file: /cvs/src/sys/dev/hid/hidmt.c,v retrieving revision 1.1 diff -u -p -r1.1 hidmt.c --- dev/hid/hidmt.c 20 Jan 2016 01:26:00 - 1.1 +++ dev/hid/hidmt.c 20 Mar 2016 14:22:49 - @@ -329,20 +329,15 @@ hidmt_input(struct hidmt *mt, uint8_t *d width = 50; } - wsmouse_input(mt->sc_wsmousedev, mt->sc_button, + WSMOUSE_TOUCH(mt->sc_wsmousedev, mt->sc_button, (mt->last_x = mt->sc_contacts[i].x), (mt->last_y = mt->sc_contacts[i].y), - width, tips, - WSMOUSE_INPUT_ABSOLUTE_X | - WSMOUSE_INPUT_ABSOLUTE_Y | - WSMOUSE_INPUT_ABSOLUTE_Z | - WSMOUSE_INPUT_ABSOLUTE_W); + width, tips); } else { - wsmouse_input(mt->sc_wsmousedev, mt->sc_button, + WSMOUSE_INPUT(mt->sc_wsmousedev, mt->sc_button, (mt->last_x - mt->sc_contacts[i].x), (mt->last_y - mt->sc_contacts[i].y), - 0, 0, - WSMOUSE_INPUT_DELTA); + 0, 0); mt->last_x = mt->sc_contacts[i].x; mt->last_y = mt->sc_contacts[i].y; } Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.68 diff -u -p -r1.68 pms.c --- dev/pckbc/pms.c 27 Feb 2016 22:01:58 - 1.68 +++ dev/pckbc/pms.c 20 Mar 2016 14:22:52 - @@ -143,17 +143,8 @@ struct elantech_softc { int min_x, min_y; int max_x, max_y; - struct { - unsigned int x; - unsigned int y; - unsigned int z; -
Re: multitouch support again
Are there any reviews, tests, OKs, or NOs pending? And if not, may I ask if someone knows a better way to make progress in this area? I'm at a loss here. As far as I can see, I cannot offer a smaller diff; this one contains the minimum that technically makes sense. And as it just adds the basics, a lot of things remain that could and possibly should be done soon, 6.0 isn't far away here. On 03/20/2016 06:18 PM, Ulf Brosziewski wrote: I have been asked to prepare a less invasive version of the MT diffs I posted a week ago. Here it is. It doesn't delete wsmouse_input(). The old and the new infrastructure coexist in wsmouse, and only the touchpad drivers have been changed to use the new one. Except for a stylistic detail (s/timespeccpy/memcpy/), nothing else has changed, and the descriptions I added last week apply to this version as well (the synaptics diff, which needs the modified wsconsio.h, is the first one here, the rest is for the kernel). Tests have been made with an Elantech-v4 touchpad, an ALPS Glidepoint, and an old Synaptics touchpad. I couldn't test the older Elantech models, more recent Synaptics models, or models that run with hidmt or ubcmtp. (The December version had more tests, but this isn't exactly the same code anymore.) [...]
multitouch support again
I have been asked to prepare a less invasive version of the MT diffs I posted a week ago. Here it is. It doesn't delete wsmouse_input(). The old and the new infrastructure coexist in wsmouse, and only the touchpad drivers have been changed to use the new one. Except for a stylistic detail (s/timespeccpy/memcpy/), nothing else has changed, and the descriptions I added last week apply to this version as well (the synaptics diff, which needs the modified wsconsio.h, is the first one here, the rest is for the kernel). Tests have been made with an Elantech-v4 touchpad, an ALPS Glidepoint, and an old Synaptics touchpad. I couldn't test the older Elantech models, more recent Synaptics models, or models that run with hidmt or ubcmtp. (The December version had more tests, but this isn't exactly the same code anymore.) Index: src/wsconscomm.c === RCS file: /cvs/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c,v retrieving revision 1.13 diff -u -p -r1.13 wsconscomm.c --- src/wsconscomm.c29 Aug 2015 08:48:28 - 1.13 +++ src/wsconscomm.c11 Mar 2016 20:46:30 - @@ -215,45 +215,29 @@ WSConsReadHwState(InputInfoPtr pInfo, hw->y = priv->maxy - event->value + priv->miny; hw->cumulative_dy = hw->y; break; -case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: +case WSCONS_EVENT_TOUCH_PRESSURE: hw->z = event->value; break; -case WSCONS_EVENT_MOUSE_ABSOLUTE_W: -if (priv->model == MODEL_ELANTECH) { -/* Elantech touchpads report number of fingers directly. */ -hw->fingerWidth = 5; -hw->numFingers = event->value; -break; -} -/* XXX magic number mapping which is mirrored in pms driver */ -switch (event->value) { -case 0: -hw->fingerWidth = 5; -hw->numFingers = 2; -break; -case 1: +case WSCONS_EVENT_TOUCH_CONTACTS: +hw->numFingers = event->value; +if (hw->numFingers == 0) +hw->fingerWidth = 0; +else if (hw->fingerWidth == 0) hw->fingerWidth = 5; -hw->numFingers = 3; -break; -case 4 ... 5: -hw->fingerWidth = event->value; -hw->numFingers = 1; -break; -} +break; +case WSCONS_EVENT_TOUCH_WIDTH: +hw->fingerWidth = event->value; +break; +case WSCONS_EVENT_TOUCH_RESET: +/* + * The contact count or the active MT-slot has changed. + * Suppress pointer motion and two-finger scrolling. + */ +priv->count_packet_finger = 0; +priv->vert_scroll_twofinger_on = FALSE; +priv->horiz_scroll_twofinger_on = FALSE; break; case WSCONS_EVENT_SYNC: -if (hw->z == 0) { -hw->fingerWidth = 0; -hw->numFingers = 0; -} else if (hw->numFingers == 0) { -/* - * Because W may be 0 already, a two-finger touch on a - * Synaptics touchpad doesn't necessarily produce an update - * event for W. - */ -hw->fingerWidth = 5; -hw->numFingers = 2; -} hw->millis = 1000 * event->time.tv_sec + event->time.tv_nsec / 100; SynapticsCopyHwState(hwRet, hw); Index: dev/hid/hidmt.c === RCS file: /cvs/src/sys/dev/hid/hidmt.c,v retrieving revision 1.1 diff -u -p -r1.1 hidmt.c --- dev/hid/hidmt.c 20 Jan 2016 01:26:00 - 1.1 +++ dev/hid/hidmt.c 20 Mar 2016 14:22:49 - @@ -329,20 +329,15 @@ hidmt_input(struct hidmt *mt, uint8_t *d width = 50; } - wsmouse_input(mt->sc_wsmousedev, mt->sc_button, + WSMOUSE_TOUCH(mt->sc_wsmousedev, mt->sc_button, (mt->last_x = mt->sc_contacts[i].x), (mt->last_y = mt->sc_contacts[i].y), - width, tips, - WSMOUSE_INPUT_ABSOLUTE_X | - WSMOUSE_INPUT_ABSOLUTE_Y | - WSMOUSE_INPUT_ABSOLUTE_Z | - WSMOUSE_INPUT_ABSOLUTE_W); + width, tips); } else { - wsmouse_input(mt->sc_wsmousedev, mt->sc_button, + WSMOUSE_INPUT(mt->sc_wsmousedev, mt->sc_button, (mt->last_x - mt->sc_contacts[i].x), (mt->last_y - mt->sc_contacts[i].y), - 0, 0, -
Re: multitouch support in wsmouse 1/3
It isn't possible to leave all of the existing code intact, at least not for touchpads, which form the most complex and critical case here. Either all of them run with the modified synaptics driver, or they don't. I don't see a reasonable solution in between (wsconscomm.c might become a little monster otherwise). This leaves the option of running mouse and touch panel drivers with wsmouse_input, as before, and restrict the changes to the touchpad drivers. This could provide a kind of "fallback" in case of serious regressions, and the trivial parts of the "drivers" diff could be removed. If this is what you want, I could prepare it, but it would take a few days. On 03/17/2016 01:58 PM, Martin Pieuchot wrote: On 13/03/16(Sun) 18:37, Ulf Brosziewski wrote: The diffs below are a rewrite of the input-processing part of wsmouse. It adds support for multitouch input. I have split the set of diffs into three parts and I will post part 2 and 3 in separate messages. Part 1 below contains all patches for wscons, part 2 is for the hardware drivers, part 3 is a patch for the synaptics driver in xenocara (compiling that driver will require the modified version of wsconsio.h in /usr/include/dev/wscons). I'm really afraid because this is just a single diff split in 3, they are not independent. Plus since your original mails included a broken diff I doubt anybody tried it. That said you've done some great work and I like it a lot. Could you prepare a diff with all the new stuff that does do change anything in the existing code? This could go in directly. Which hardware still need to be tested?
Re: multitouch support in wsmouse 1/3
There are whitespace errors in the diffs. In case anyone wants to test them, please use the new versions in the attachment. On 03/13/2016 06:37 PM, Ulf Brosziewski wrote: The diffs below are a rewrite of the input-processing part of wsmouse. It adds support for multitouch input. [...] mtsupport.tgz Description: application/compressed-tar
multitouch support in wsmouse 3/3
This patch adapts the synaptics driver to the changes described in 1/3 and 2/3. wsconsio.h defines alternative names for the ABSOLUTE_Z and ABSOLUTE_W events, namely WSCONS_EVENT_TOUCH_PRESSURE and WSCONS_EVENT_TOUCH_CONTACTS, and wsmouse uses the latter exclusively for the plain contact count. For contact width, wsconsio.h defines the new event type WSCONS_EVENT_TOUCH_WIDTH. The event type WSCONS_EVENT_TOUCH_RESET is introduced in order to make the synaptics driver work properly with input that is derived from MT state (I'm not happy with the event name, perhaps someone has a better idea). This event - which has no value - is generated whenever the absolute coordinates are being updated, but no pointer motion events must be generated. Usually touchpad drivers suppress pointer motion when the contact count changes. But this is not sufficient for the MT case, because wsmouse may change the "pointer- controlling" input slot even even when the contact count is constant. Index: src/wsconscomm.c === RCS file: /cvs/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c,v retrieving revision 1.13 diff -u -p -r1.13 wsconscomm.c --- src/wsconscomm.c29 Aug 2015 08:48:28 - 1.13 +++ src/wsconscomm.c11 Mar 2016 20:46:30 - @@ -215,45 +215,29 @@ WSConsReadHwState(InputInfoPtr pInfo, hw->y = priv->maxy - event->value + priv->miny; hw->cumulative_dy = hw->y; break; -case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: +case WSCONS_EVENT_TOUCH_PRESSURE: hw->z = event->value; break; -case WSCONS_EVENT_MOUSE_ABSOLUTE_W: -if (priv->model == MODEL_ELANTECH) { -/* Elantech touchpads report number of fingers directly. */ -hw->fingerWidth = 5; -hw->numFingers = event->value; -break; -} -/* XXX magic number mapping which is mirrored in pms driver */ -switch (event->value) { -case 0: -hw->fingerWidth = 5; -hw->numFingers = 2; -break; -case 1: +case WSCONS_EVENT_TOUCH_CONTACTS: +hw->numFingers = event->value; +if (hw->numFingers == 0) +hw->fingerWidth = 0; +else if (hw->fingerWidth == 0) hw->fingerWidth = 5; -hw->numFingers = 3; -break; -case 4 ... 5: -hw->fingerWidth = event->value; -hw->numFingers = 1; -break; -} +break; +case WSCONS_EVENT_TOUCH_WIDTH: +hw->fingerWidth = event->value; +break; +case WSCONS_EVENT_TOUCH_RESET: +/* + * The contact count or the active MT-slot has changed. + * Suppress pointer motion and two-finger scrolling. + */ +priv->count_packet_finger = 0; +priv->vert_scroll_twofinger_on = FALSE; +priv->horiz_scroll_twofinger_on = FALSE; break; case WSCONS_EVENT_SYNC: -if (hw->z == 0) { -hw->fingerWidth = 0; -hw->numFingers = 0; -} else if (hw->numFingers == 0) { -/* - * Because W may be 0 already, a two-finger touch on a - * Synaptics touchpad doesn't necessarily produce an update - * event for W. - */ -hw->fingerWidth = 5; -hw->numFingers = 2; -} hw->millis = 1000 * event->time.tv_sec + event->time.tv_nsec / 100; SynapticsCopyHwState(hwRet, hw);
multitouch support in wsmouse 2/3
These diffs adapt the drivers that attach to wsmouse to its new interface. Most changes are fairly trivial and replace wsmouse_input calls with the WSMOUSE_INPUT/WSMOUSE_TOUCH macros. However, some cases may need a second thought. hidms, for example, now permits, at least in principle, to mix relative and absolute coordinates, which looks somewhat strange. Do scenarios exist where this makes sense? I believe it doesn't make sense to stick to the Synaptics "W mode" encoding in the wsmouse infrastructure any longer. Among the devices that provide touch data it is an exception and not the common case. Please note that the last argument of WSMOUSE_TOUCH is always the plain contact count, not the W value as produced by Synaptics touchpads. Drivers can pass 0 as contact count if it is redundant (wsmouse_touch adapts the value to the pressure state). Width values must be reported via wsmouse_set. I haven't tried to introduce MT functions into drivers that I couldn't test, up to now the elantech-v4 handler in pms is the only one that uses them. As pointed out in the previous message, a call to wsmouse_mt_init is necessary when the device is enabled. Moreover, the ioctl function passes the mode setting back to wsmouse via wsmouse_set_mode; the packet handler has no branches for native mode and compat mode, the modes are handled by wsmouse_input_sync. For the same reason there is no need to track coordinates and check for deltas here, wsmouse does this anyway (with more hardware information it could do more, like controlling and switching the modes without that callback, and handling the other ioctl calls; the code that is repeated over and over again in the wsmouse-dependent drivers could be removed). Index: arch/i386/isa/lms.c === RCS file: /cvs/src/sys/arch/i386/isa/lms.c,v retrieving revision 1.20 diff -u -p -r1.20 lms.c --- arch/i386/isa/lms.c 10 Apr 2007 22:37:17 - 1.20 +++ arch/i386/isa/lms.c 12 Mar 2016 20:42:46 - @@ -235,8 +235,7 @@ lmsintr(void *arg) sc->oldbuttons = buttons; if (dx || dy || changed) - wsmouse_input(sc->sc_wsmousedev, - buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, 0, 0); return -1; } Index: arch/i386/isa/mms.c === RCS file: /cvs/src/sys/arch/i386/isa/mms.c,v retrieving revision 1.19 diff -u -p -r1.19 mms.c --- arch/i386/isa/mms.c 10 Apr 2007 22:37:17 - 1.19 +++ arch/i386/isa/mms.c 12 Mar 2016 20:42:46 - @@ -229,8 +229,7 @@ mmsintr(void *arg) changed = status & 0x38; if (dx || dy || changed) - wsmouse_input(sc->sc_wsmousedev, - buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, buttons, dx, dy, 0, 0); return -1; } Index: arch/luna88k/dev/lunaws.c === RCS file: /cvs/src/sys/arch/luna88k/dev/lunaws.c,v retrieving revision 1.11 diff -u -p -r1.11 lunaws.c --- arch/luna88k/dev/lunaws.c 7 Jun 2014 11:55:35 - 1.11 +++ arch/luna88k/dev/lunaws.c 12 Mar 2016 20:42:46 - @@ -260,9 +260,8 @@ wsintr(int chan) else if (sc->sc_msreport == 2) { sc->dy = (signed char)code; if (sc->sc_wsmousedev != NULL) - wsmouse_input(sc->sc_wsmousedev, - sc->buttons, sc->dx, sc->dy, 0, 0, - WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, + sc->buttons, sc->dx, sc->dy, 0, 0); sc->sc_msreport = 0; } #else Index: arch/sgi/hpc/z8530ms.c === RCS file: /cvs/src/sys/arch/sgi/hpc/z8530ms.c,v retrieving revision 1.1 diff -u -p -r1.1 z8530ms.c --- arch/sgi/hpc/z8530ms.c 17 Apr 2012 22:06:33 - 1.1 +++ arch/sgi/hpc/z8530ms.c 12 Mar 2016 20:42:47 - @@ -296,7 +296,7 @@ zsms_wsmouse_input(struct zsms_softc *sc x = (int)sc->packet[ZSMS_PACKET_X1] + (int)sc->packet[ZSMS_PACKET_X2]; y = (int)sc->packet[ZSMS_PACKET_Y1] + (int)sc->packet[ZSMS_PACKET_Y2]; - wsmouse_input(sc->wsmousedev, btns, x, y, 0, 0, WSMOUSE_INPUT_DELTA); + WSMOUSE_INPUT(sc->sc_wsmousedev, btns, x, y, 0, 0); } int Index: arch/zaurus/dev/zts.c === RCS file: /cvs/src/sys/arch/zaurus/dev/zts.c,v retrieving revision 1.16 diff -u -p -r1.16 zts.c --- arch/zaurus/dev/zts.c 29 Mar 2014 18:09:30 - 1.16 +++ arch/zaurus/dev/zts.c 12 Mar 2016 20:42:47
multitouch support in wsmouse 1/3
The diffs below are a rewrite of the input-processing part of wsmouse. It adds support for multitouch input. I have split the set of diffs into three parts and I will post part 2 and 3 in separate messages. Part 1 below contains all patches for wscons, part 2 is for the hardware drivers, part 3 is a patch for the synaptics driver in xenocara (compiling that driver will require the modified version of wsconsio.h in /usr/include/dev/wscons). For those who had a look at the test version from December: The code for the internal touchpad driver ("wstpad") is not included here, I intend to add and present it again later. Apart from that there are only minor changes. I have moved the input-processing functions into wsmouse.c, renamed various things, and improved the tracking functions and the handling of overflows of the event queue. The wsmouse_input function has been removed. Hardware drivers make one or more calls to the new "state-reporting" functions of wsmouse (see wsmousevar.h), and signal that a frame is complete by calling wsmouse_input_sync, which generates the wscons events. Roughly, the set of functions corresponds to the different types of state: button state, relative motion, absolute positions, single-touch state, and (MT) slot state. "Standard" combinations of calls are covered by the macros WSMOUSE_INPUT and WSMOUSE_TOUCH. There is also a more generic function which can be used for less common inputs or requirements (wsmouse_set). I assume that support for multi-user touch devices is not required, the maximal number of MT slots is defined in wsmousevar.h as 10. The technical limit is sizeof(u_int) * 8. The MT structures in wsmouse must be initialized with a call to wsmouse_mt_init. Drivers for MT devices that associate touches with "tracking IDs" can use wsmouse_id_to_slot() to assign or to look up slot numbers, and call wsmouse_mtstate subsequently. hidmt may be a driver that needs it. Drivers for MT devices that don't provide "MT tracking" - ubcmtp, for example - must collect the contact points in an array of mtpoint structures and pass it to wsmouse_mtframe, which computes a matching with the points of the last frame and calls wsmouse_mtstate internally. Currently MT state is always converted into a single-touch representation, and wscons events are generated accordingly. No MT events have been defined yet. However, minor changes in the set of events are necessary to make the new code work cleanly with the synaptics driver (see 3/3). I will comment on some more details in the next messages. And, yes, this is a request for OKs. Index: dev/wscons/wsmousevar.h === RCS file: /cvs/src/sys/dev/wscons/wsmousevar.h,v retrieving revision 1.8 diff -u -p -r1.8 wsmousevar.h --- dev/wscons/wsmousevar.h 21 Dec 2014 18:16:07 - 1.8 +++ dev/wscons/wsmousevar.h 12 Mar 2016 20:42:48 - @@ -32,6 +32,22 @@ */ /* + * Copyright (c) 2015, 2016 Ulf Brosziewski + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* * WSMOUSE interfaces. */ @@ -64,14 +80,151 @@ struct wsmousedev_attach_args { */ intwsmousedevprint(void *, const char *); + +/* Process standard mouse input. */ +#define WSMOUSE_INPUT(sc_wsmousedev, btns, dx, dy, dz, dw) \ + do {\ + wsmouse_buttons((sc_wsmousedev), (btns)); \ + wsmouse_motion((sc_wsmousedev), (dx), (dy), (dz), (dw));\ + wsmouse_input_sync(sc_wsmousedev); \ + } while (0) + + +/* Process standard touchpad input. */ +#define WSMOUSE_TOUCH(sc_wsmousedev, btns, x, y, pressure, contacts) \ + do {\ + wsmouse_buttons((sc_wsmousedev), (btns)); \ + wsmouse_position((sc_wsmousedev), (x), (y));\ + wsmouse_touch((sc_wsmousedev), (pressure), (contacts)); \ + wsmouse_input_sync(sc_wsmousedev); \ + } while (0) + + +/* + * Drivers for touchpads that don't report pressure values can pass + * WSMOUSE_DEFAULT_PRESSURE to wsm
Re: preparing multitouch support - request for tests
On 12/16/2015 03:11 PM, Matthieu Herrb wrote: On Wed, Dec 16, 2015 at 02:32:44AM +0100, Ulf Brosziewski wrote: Ping? No further thoughts on this, no tests? Do I have to conclude that most people are happy with wsmouse as it is? Hi, I'd like to see things move forward, but I currently lack time to do anything serious on this. One thing is not clear to me after looking (quickly) at your patch and trying it: how does this work integrate with the libinput port ? I hope it keeps various options open. Something like the wsmouseinput part, which tracks input states and produces events, is necessary anyway, would you agree with that? Quite generally, there might be three strategies for porting libinput: 1) We could try to make a port with a minimal change of the libinput sources. I'm afraid this would require making our input framework "libinput-compatible" and trying to rebuild at least a half of evdev. 2) We could try to separate the "reusable" parts of the libinput code and replace the rest with new developments. I don't know what the ratio would be, and whether the advantages would outweigh the difficulties. 3) We provide a "thin" libinput layer that supports its API and is backed by extended kernel functionality. This might be the most flexible solution. Various mixtures of 3) and 2) will also be possible. Some work on a port that aims at 3) has already been done, and the "touchpad extension" in my diff (wstpad) could support such a solution. With or without wstpad, it will be necessary to extend the event system, and probably not only with a zoo of new (MT) type codes. The wsmouse_configure() function and the struct wsmousehw might be a base for handling extended informations about the devices. Perhaps it isn't well-structured, and it will change in the future; but both the basic MT suppport as well as wstpad already needed more than wsconsio provides. Using ws with touchpads isn't intended to be the end of the story in this form. An unchanged ws isn't ideal, e.g., with respect to things like acceleration and deceleration (I had to add a "deceleration" feature because least the default acceleration profiles don't work well with touchpads; but this means that similar and related operations are scattered between distinct layers). From what I understand from libinput, it moves a lot of the code that maps low-level events to higher-level X events (for multi-touch, but also for features like 2 fingers scrolling or side scrolling) from the kernel to libinput itself. With libinput, xf86-input-ws should be replaced by xf86-input-libinput and there is no need to hack on xf86-input-ws anymore. I've the impression that here you're adding this code to the kernel. Please correct me if I'm wrong. There is also the fact that I'm conviced that xinput (and libinput) needs more information about the individual input device than what is currently exposed through wsconsio. This is probably even more true for multi-touch devices, since they have such a large set of possible features.. I'm aware that the diff isn't small, but anything smaller would make some of the remaining parts void and possibly blur the concept. The core of the approach is actually quite simple: wsmouse_input() will be replaced by a set of functions for reporting state, and by wsmouse_input_sync(), which generates the wscons events (please note that it doesn't produce MT events yet; there are no userland drivers that could use them). Running mice, and tablets and touchpads that can only track a single contact wouldn't need much more. MT support needs some bits of configuration: the number of touches that might be tracked simultaneously, and the information whether a buffer for "MT tracking" is required. For use with the synaptics driver, MT input from touchpads must be converted into a single-touch representation, and this conversion is based on a mechanism that selects a "pointer-controlling" slot. The implementation generalizes the method currently applied by the Elantech-v4 packet handler in pms. Single-touch representations are also the base for handling "compat-mode" of touchpads in wsmouse. Currently, each hardware driver tracks absolute coordinates in its device data, and has a compat-mode branch in its packet handler that computes relative coordinates, applies a more or less arbitrary scaling to them, and calls wsmouse_input() with the "DELTA" flags. This is not only ugly, it would be even more ugly for touchpad drivers that use the new MT functions: It would still require a driver-internal representation of the input, a driver-internal selection of the pointer-controlling touch, etc. That's obviously nonsense, compat mode should be handled by wsmouse. However, it requires some configuration. There is a second point concerning compat mode that I would like to change: it could be made useful. Because of the arbitrary scaling and the
Re: preparing multitouch support - request for tests
Ping? No further thoughts on this, no tests? Do I have to conclude that most people are happy with wsmouse as it is? I'm aware that the diff isn't small, but anything smaller would make some of the remaining parts void and possibly blur the concept. The core of the approach is actually quite simple: wsmouse_input() will be replaced by a set of functions for reporting state, and by wsmouse_input_sync(), which generates the wscons events (please note that it doesn't produce MT events yet; there are no userland drivers that could use them). Running mice, and tablets and touchpads that can only track a single contact wouldn't need much more. MT support needs some bits of configuration: the number of touches that might be tracked simultaneously, and the information whether a buffer for "MT tracking" is required. For use with the synaptics driver, MT input from touchpads must be converted into a single-touch representation, and this conversion is based on a mechanism that selects a "pointer-controlling" slot. The implementation generalizes the method currently applied by the Elantech-v4 packet handler in pms. Single-touch representations are also the base for handling "compat-mode" of touchpads in wsmouse. Currently, each hardware driver tracks absolute coordinates in its device data, and has a compat-mode branch in its packet handler that computes relative coordinates, applies a more or less arbitrary scaling to them, and calls wsmouse_input() with the "DELTA" flags. This is not only ugly, it would be even more ugly for touchpad drivers that use the new MT functions: It would still require a driver-internal representation of the input, a driver-internal selection of the pointer-controlling touch, etc. That's obviously nonsense, compat mode should be handled by wsmouse. However, it requires some configuration. There is a second point concerning compat mode that I would like to change: it could be made useful. Because of the arbitrary scaling and the unpredictable pointer movement, I cannot use it with wsmoused at the console. Do touchpads exist where it works? Recently Thierry Deval posted a diff here which proved that we could easily do something about that, but that is a different story. In my diff, wsmouseinput hooks its "touchpad extension" (wstpad) into the compat-mode conversion function, which works well with ws for all touchpads that are available to me. The internal configuration of wstpad may cause headaches, it seems to be easy to make a mess out if it. This is one of the reasons why there are no ioctl mechanisms yet for a configuration from userland. Up to now, I had less headaches with the input-processing parts of wstpad, and I don't believe that a decent driver necessarily looks like the synaptics driver, or the touchpad module of libinput. Its tapping handler, for example, seems to be built on a somewhat unlucky abstraction (I mean the "state machine", where states mirror input states and sequences of input states; in wstpad, the "states" of the handler correspond the kind of decision that is to be taken next). Of course I don't want to suggest that this is children's play; e.g., I haven't worked seriously on the palm detection part up to now (I cannot do that, because I don't have "real" problems with accidental touches). Many things that may sound trivial first may turn out to be intricate (e.g., how do you distinguish a two-finger click from a click-and-drag action? This might need a timeout. Perhaps Mac users can help here ...) On 12/03/2015 12:20 AM, Ulf Brosziewski wrote: The diffs below contain a complete and extensive rewrite of the input-processing parts of wsmouse and the interface it provides to the hardware drivers. It prepares the support for various kinds of multitouch input, as well as an extended support for touchpads by wsmouse. Tests for regression with all kinds of "pointing devices" would be welcome. Only a small set of touchpads and USB mice is available to me, which is a somewhat uncomfortable situation when you are working on things like this. Please note that the first diff is for the synaptics driver in xenocara, the rest is for the kernel. Patching that driver will be necessary if you test with touchpads (and compiling it requires the modified version of wsconsio.h in /usr/include/dev/wscons/). In most drivers I have made only short and trivial changes, the Elantech-v4 part of pms is the only one that makes full use of the new MT functions. Unlike the basic input layer, which I hope is already fairly stable, the in-kernel touchpad support is in a more experimental stage. If you have a Synaptics, ALPS, or Elantech-v4 touchpad, you could test it by adding this xorg.conf to /etc: Section "InputClass" Identifier "wstpad" Driver "ws" MatchIsTouchPad "true" EndSection Only a default configuration will be
Re: preparing multitouch support - request for tests
Hi, here are the diffs again, as tgz archive (it's the version I posted last week, which doesn't include the latest bug fix: hilms is incomplete in that version and won't work with tablets, only with mice). On 12/07/15 15:59, Matthieu Herrb wrote: On Thu, Dec 03, 2015 at 12:20:15AM +0100, Ulf Brosziewski wrote: The diffs below contain a complete and extensive rewrite of the input-processing parts of wsmouse and the interface it provides to the hardware drivers. It prepares the support for various kinds of multitouch input, as well as an extended support for touchpads by wsmouse. Hi, it looks like the diff got some white space mangled somewhere on the path to my mailbox. Would you have a version available somewhere with a more reliable transport than email ? Thank you. wsmouseinput.tgz Description: Binary data
preparing multitouch support - request for tests
The diffs below contain a complete and extensive rewrite of the input-processing parts of wsmouse and the interface it provides to the hardware drivers. It prepares the support for various kinds of multitouch input, as well as an extended support for touchpads by wsmouse. Tests for regression with all kinds of "pointing devices" would be welcome. Only a small set of touchpads and USB mice is available to me, which is a somewhat uncomfortable situation when you are working on things like this. Please note that the first diff is for the synaptics driver in xenocara, the rest is for the kernel. Patching that driver will be necessary if you test with touchpads (and compiling it requires the modified version of wsconsio.h in /usr/include/dev/wscons/). In most drivers I have made only short and trivial changes, the Elantech-v4 part of pms is the only one that makes full use of the new MT functions. Unlike the basic input layer, which I hope is already fairly stable, the in-kernel touchpad support is in a more experimental stage. If you have a Synaptics, ALPS, or Elantech-v4 touchpad, you could test it by adding this xorg.conf to /etc: Section "InputClass" Identifier "wstpad" Driver "ws" MatchIsTouchPad "true" EndSection Only a default configuration will be available with this. It enables two-finger-scrolling and a lower soft-button area for clickpads, and two-finger- or edge-scrolling for touchpads (support for tapping and upper soft-button areas is implemented, but it won't be enabled by the automatic configuration). If this works, it would also be interesting for me to know whether the defaults for pointer speed and acceleration are decent. Of course I'm not only interested in tests. Questions, comments, suggestions, and any kind of help would also be welcome. Index: src/wsconscomm.c === RCS file: /cvs/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c,v retrieving revision 1.13 diff -u -p -r1.13 wsconscomm.c --- src/wsconscomm.c29 Aug 2015 08:48:28 - 1.13 +++ src/wsconscomm.c1 Dec 2015 22:40:15 - @@ -215,45 +215,29 @@ WSConsReadHwState(InputInfoPtr pInfo, hw->y = priv->maxy - event->value + priv->miny; hw->cumulative_dy = hw->y; break; -case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: +case WSCONS_EVENT_TOUCH_PRESSURE: hw->z = event->value; break; -case WSCONS_EVENT_MOUSE_ABSOLUTE_W: -if (priv->model == MODEL_ELANTECH) { -/* Elantech touchpads report number of fingers directly. */ -hw->fingerWidth = 5; -hw->numFingers = event->value; -break; -} -/* XXX magic number mapping which is mirrored in pms driver */ -switch (event->value) { -case 0: -hw->fingerWidth = 5; -hw->numFingers = 2; -break; -case 1: +case WSCONS_EVENT_TOUCH_FINGERS: +hw->numFingers = event->value; +if (hw->numFingers == 0) +hw->fingerWidth = 0; +else if (hw->fingerWidth == 0) hw->fingerWidth = 5; -hw->numFingers = 3; -break; -case 4 ... 5: -hw->fingerWidth = event->value; -hw->numFingers = 1; -break; -} +break; +case WSCONS_EVENT_TOUCH_WIDTH: +hw->fingerWidth = event->value; +break; +case WSCONS_EVENT_TOUCH_UPDATE: +/* + * The finger count or the active MT-slot has changed. + * Suppress pointer motion and two-finger scrolling. + */ +priv->count_packet_finger = 0; +priv->vert_scroll_twofinger_on = FALSE; +priv->horiz_scroll_twofinger_on = FALSE; break; case WSCONS_EVENT_SYNC: -if (hw->z == 0) { -hw->fingerWidth = 0; -hw->numFingers = 0; -} else if (hw->numFingers == 0) { -/* - * Because W may be 0 already, a two-finger touch on a - * Synaptics touchpad doesn't necessarily produce an update - * event for W. - */ -hw->fingerWidth = 5; -hw->numFingers = 2; -} hw->millis = 1000 * event->time.tv_sec + event->time.tv_nsec / 100; SynapticsCopyHwState(hwRet, hw); Index: arch/i386/isa/lms.c === RCS file: /cvs/src/sys/arch/i386/isa/lms.c,v retrieving revision 1.20 diff -u -p -r1.20 lms.c --- arch/i386/isa/lms.c 10 Apr 2007 22:37:17 - 1.20 +++ arch/i386/isa/lms.c 1 Dec 2015 22:17:41 - @@ -36,6 +36,7 @@ #include #include +#include #define
Re: Slow wsmouse down in console
This looks nice. Maybe someone else who is more familiar with wsdisplay could also have a look at it? I made a test with a USB mouse and an ALPS Glidepoint, which worked well. Without the patch wsmoused is completely useless for that touchpad. Out of curiosity, I made another test with an Elantech-v4 clickpad, and the cursor control also worked well (of course, wsmoused remains useless for clickpads because you cannot paste). Both tracking the remainders when scaling and taking the size of the cells into account looks reasonable. There might still be no garantuee that this works everywhere - pms, for example, applies somewhat arbitrary scale factors in compat mode, there is no stable correlation to the touchpad resolutions. But if this works in standard environments, it is certainly more useful than the current version. Because I saw no complaints up to now, I have been thinking that hardly anyone uses touchpads at the console. Am I wrong here? On 11/27/2015 12:35 AM, Thierry Deval wrote: Hi, I hope I'm not the only one being annoyed by the fast movement of wsmouse when in text mode, and this one can be useful. Here is a patch that slows down the cursor by reducing the mouse coordinates proportionally to the console font size. I confess I have only tried it on this laptop with its Synaptics touchpad and some other USB mouses. Anyone else interested ? Thierry Index: sys/dev/wscons/wsdisplay.c === RCS file: /cvs/src/sys/dev/wscons/wsdisplay.c,v retrieving revision 1.124 diff -u -p -r1.124 wsdisplay.c --- dev/wscons/wsdisplay.c 8 Sep 2015 11:13:20 - 1.124 +++ dev/wscons/wsdisplay.c 26 Nov 2015 20:28:48 - @@ -2463,27 +2463,39 @@ ctrl_event(struct wsdisplay_softc *sc, u void mouse_moverel(struct wsscreen *scr, int dx, int dy) { + static int acc_dx, acc_dy; struct wsscreen_internal *dconf = scr->scr_dconf; + const struct wsscreen_descr *descr = dconf->scrdata; u_int old_mouse = scr->mouse; int mouse_col = scr->mouse % N_COLS(dconf); int mouse_row = scr->mouse / N_COLS(dconf); + int norm_dx, norm_dy; + + /* accumulate movement and calculate character equivalent */ + acc_dx += dx; + if ((norm_dx = acc_dx / descr->fontwidth )) acc_dx -= descr->fontwidth * norm_dx; + acc_dy += dy; + if ((norm_dy = acc_dy / descr->fontheight)) acc_dy -= descr->fontheight * norm_dy; + + /* bail out if mouse hasn't virtually moved */ + if (norm_dx == 0 && norm_dy == 0) return; /* update position */ - if (mouse_col + dx >= MAXCOL(dconf)) + if (mouse_col + norm_dx >= MAXCOL(dconf)) mouse_col = MAXCOL(dconf); else { - if (mouse_col + dx <= 0) + if (mouse_col + norm_dx <= 0) mouse_col = 0; else - mouse_col += dx; + mouse_col += norm_dx; } - if (mouse_row + dy >= MAXROW(dconf)) + if (mouse_row + norm_dy >= MAXROW(dconf)) mouse_row = MAXROW(dconf); else { - if (mouse_row + dy <= 0) + if (mouse_row + norm_dy <= 0) mouse_row = 0; else - mouse_row += dy; + mouse_row += norm_dy; } scr->mouse = mouse_row * N_COLS(dconf) + mouse_col;
Re: synaptics touchpads: w mode and resolution
On 08/29/2015 01:13 PM, Alexandr Shadchin wrote: On Fri, Aug 28, 2015 at 10:04:51PM +0200, Ulf Brosziewski wrote: Some weeks ago a change was made in pms to support Synaptics touchpads that don't provide W mode. I assume that only fairly old models are concerned, and that the variant in the patch below is more accurate. It only fakes W values where necessary. The patch contains a second change, a check whether the resolution query was successful. According to the Synaptics PS/2 Interfacing Guide, bit 7 of the second response byte will be set in case of success. It seems that if it isn't set, the other bytes are garbage or have an unknown meaning. Unfortunately I only have that old model - with firmware 4.1 - for testing. Could someone confirm that newer models aren't affected by these changes? Tested on X201 (Synaptics touchpad, firmware 7.4), no regress. See comment below. Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.65 diff -u -p -r1.65 pms.c --- dev/pckbc/pms.c 23 Aug 2015 04:45:23 - 1.65 +++ dev/pckbc/pms.c 28 Aug 2015 18:04:45 - @@ -949,8 +949,10 @@ synaptics_get_hwinfo(struct pms_softc *s return (-1); } - syn-res_x = SYNAPTICS_RESOLUTION_X(syn-resolution); - syn-res_y = SYNAPTICS_RESOLUTION_Y(syn-resolution); + if (syn-resolution 0x8000) { I think it makes sense to define SYNAPTICS_RESOLUTION_VALID instead of magic numbers. + syn-res_x = SYNAPTICS_RESOLUTION_X(syn-resolution); + syn-res_y = SYNAPTICS_RESOLUTION_Y(syn-resolution); + } [...] Thanks a lot. I have added the constant to pmsreg.h, this is the updated diff: Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.65 diff -u -p -r1.65 pms.c --- dev/pckbc/pms.c 23 Aug 2015 04:45:23 - 1.65 +++ dev/pckbc/pms.c 29 Aug 2015 12:33:57 - @@ -949,8 +949,10 @@ synaptics_get_hwinfo(struct pms_softc *s return (-1); } - syn-res_x = SYNAPTICS_RESOLUTION_X(syn-resolution); - syn-res_y = SYNAPTICS_RESOLUTION_Y(syn-resolution); + if (syn-resolution SYNAPTICS_RESOLUTION_VALID) { + syn-res_x = SYNAPTICS_RESOLUTION_X(syn-resolution); + syn-res_y = SYNAPTICS_RESOLUTION_Y(syn-resolution); + } syn-min_x = SYNAPTICS_XMIN_BEZEL; syn-min_y = SYNAPTICS_YMIN_BEZEL; syn-max_x = (syn-dimension) ? @@ -1163,30 +1165,21 @@ pms_proc_synaptics(struct pms_softc *sc) w = ((sc-packet[0] 0x30) 2) | ((sc-packet[0] 0x04) 1) | ((sc-packet[3] 0x04) 2); + z = sc-packet[2]; - /* -* Conform to the encoding understood by -* /usr/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c -*/ - switch (w) { - case 0: - /* fingerwidth 5, numfingers 2 */ - break; - case 1: - /* fingerwidth 5, numfingers 3 */ - break; - case 5: - /* fingerwidth 5, numfingers 1 */ - break; - case 4: - case 8: - /* fingerwidth 4, numfingers 1 */ - w = 4; - break; - default: - break; + if ((syn-capabilities SYNAPTICS_CAP_EXTENDED) == 0) { + /* +* Emulate W mode for models that don't provide it. Bit 3 +* of the w-input signals a touch (finger), Bit 2 and +* the gesture bits 1-0 can be ignored. +*/ + if (w 8) + w = 4; + else + z = w = 0; } + if ((syn-capabilities SYNAPTICS_CAP_PASSTHROUGH) w == 3) { synaptics_sec_proc(sc); return; @@ -1203,7 +1196,6 @@ pms_proc_synaptics(struct pms_softc *sc) sc-packet[4]; y = ((sc-packet[3] 0x20) 7) | ((sc-packet[1] 0xf0) 4) | sc-packet[5]; - z = sc-packet[2]; buttons = ((sc-packet[0] sc-packet[3]) 0x01) ? WSMOUSE_BUTTON(1) : 0; Index: dev/pckbc/pmsreg.h === RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v retrieving revision 1.11 diff -u -p -r1.11 pmsreg.h --- dev/pckbc/pmsreg.h 26 Mar 2015 01:30:22 - 1.11 +++ dev/pckbc/pmsreg.h 29 Aug 2015 12:33:57 - @@ -119,6 +119,7 @@ #define SYNAPTICS_MODEL_GEOMETRY(m)((m) 0x0f) /* Resolutions */ +#define SYNAPTICS_RESOLUTION_VALID (1 15) #define SYNAPTICS_RESOLUTION_X(r) (((r) 16) 0xff) #define SYNAPTICS_RESOLUTION_Y(r) ((r) 0xff)
synaptics touchpads: w mode and resolution
Some weeks ago a change was made in pms to support Synaptics touchpads that don't provide W mode. I assume that only fairly old models are concerned, and that the variant in the patch below is more accurate. It only fakes W values where necessary. The patch contains a second change, a check whether the resolution query was successful. According to the Synaptics PS/2 Interfacing Guide, bit 7 of the second response byte will be set in case of success. It seems that if it isn't set, the other bytes are garbage or have an unknown meaning. Unfortunately I only have that old model - with firmware 4.1 - for testing. Could someone confirm that newer models aren't affected by these changes? Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.65 diff -u -p -r1.65 pms.c --- dev/pckbc/pms.c 23 Aug 2015 04:45:23 - 1.65 +++ dev/pckbc/pms.c 28 Aug 2015 18:04:45 - @@ -949,8 +949,10 @@ synaptics_get_hwinfo(struct pms_softc *s return (-1); } - syn-res_x = SYNAPTICS_RESOLUTION_X(syn-resolution); - syn-res_y = SYNAPTICS_RESOLUTION_Y(syn-resolution); + if (syn-resolution 0x8000) { + syn-res_x = SYNAPTICS_RESOLUTION_X(syn-resolution); + syn-res_y = SYNAPTICS_RESOLUTION_Y(syn-resolution); + } syn-min_x = SYNAPTICS_XMIN_BEZEL; syn-min_y = SYNAPTICS_YMIN_BEZEL; syn-max_x = (syn-dimension) ? @@ -1163,30 +1165,21 @@ pms_proc_synaptics(struct pms_softc *sc) w = ((sc-packet[0] 0x30) 2) | ((sc-packet[0] 0x04) 1) | ((sc-packet[3] 0x04) 2); + z = sc-packet[2]; - /* -* Conform to the encoding understood by -* /usr/xenocara/driver/xf86-input-synaptics/src/wsconscomm.c -*/ - switch (w) { - case 0: - /* fingerwidth 5, numfingers 2 */ - break; - case 1: - /* fingerwidth 5, numfingers 3 */ - break; - case 5: - /* fingerwidth 5, numfingers 1 */ - break; - case 4: - case 8: - /* fingerwidth 4, numfingers 1 */ - w = 4; - break; - default: - break; + if ((syn-capabilities SYNAPTICS_CAP_EXTENDED) == 0) { + /* +* Emulate W mode for models that don't provide it. Bit 3 +* of the w-input signals a touch (finger), Bit 2 and +* the gesture bits 1-0 can be ignored. +*/ + if (w 8) + w = 4; + else + z = w = 0; } + if ((syn-capabilities SYNAPTICS_CAP_PASSTHROUGH) w == 3) { synaptics_sec_proc(sc); return; @@ -1203,7 +1196,6 @@ pms_proc_synaptics(struct pms_softc *sc) sc-packet[4]; y = ((sc-packet[3] 0x20) 7) | ((sc-packet[1] 0xf0) 4) | sc-packet[5]; - z = sc-packet[2]; buttons = ((sc-packet[0] sc-packet[3]) 0x01) ? WSMOUSE_BUTTON(1) : 0;
Re: tap-and-drag on ALPS touchpads
On 08/22/2015 12:35 PM, Martin Pieuchot wrote: On 15/08/15(Sat) 01:32, Ulf Brosziewski wrote: The tap-and-drag gesture doesn't work reliably with the ALPS touchpads supported by pms. To make it work, it is necessary to start dragging immediately with the second touch, which doesn't always succeed. Increasing the tap timeout helps, but doesn't change the principle. The patch below solves that problem. Tests and comments would be welcome. In case someone is interested in the background: I have observed the same problem with a Linux installation on a machine with an ALPS touchpad; however, increasing the tap timeout to a sufficiently high value (= 260ms) makes it work normally. The somewhat special behaviour of those ALPS models is described in this LKML posting: https://lkml.org/lkml/2004/7/28/210 The approach put forward there - which is partially reproduced in the current version of pms - is improved by the patch as follows: When the hardware signals a tap, the handler does nothing. The missing events will be emulated when the next packet arrives, which either signals the end of the gesture, or the start of a drag action. No timeout will occur even if the hardware introduces a long delay between the first and the second packet (which just happens when the finger is resting after the second contact). This looks good to me. Did you get reports from other ALPS users? No, I haven't received any reports. Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.64 diff -u -p -r1.64 pms.c --- dev/pckbc/pms.c 20 Jul 2015 00:55:06 - 1.64 +++ dev/pckbc/pms.c 14 Aug 2015 18:27:57 - @@ -120,7 +120,8 @@ struct alps_softc { int min_x, min_y; int max_x, max_y; - int old_fin; + + u_int gesture; u_int sec_buttons; /* trackpoint */ @@ -1521,8 +1522,7 @@ pms_proc_alps(struct pms_softc *sc) { struct alps_softc *alps = sc-alps; int x, y, z, w, dx, dy; - u_int buttons; - int fin, ges; + u_int buttons, gesture; if ((alps-model ALPS_DUALPOINT) alps_sec_proc(sc)) return; @@ -1557,28 +1557,44 @@ pms_proc_alps(struct pms_softc *sc) y = ALPS_YMAX_BEZEL - y + ALPS_YMIN_BEZEL; if (alps-wsmode == WSMOUSE_NATIVE) { - ges = sc-packet[2] 0x01; - fin = sc-packet[2] 0x02; + if (alps-gesture == ALPS_TAP) { + /* Report a touch with the tap coordinates. */ + wsmouse_input(sc-sc_wsmousedev, buttons, + alps-old_x, alps-old_y, ALPS_PRESSURE, 4, + WSMOUSE_INPUT_ABSOLUTE_X + | WSMOUSE_INPUT_ABSOLUTE_Y + | WSMOUSE_INPUT_ABSOLUTE_Z + | WSMOUSE_INPUT_ABSOLUTE_W); + if (z 0) { + /* +* The hardware doesn't send a null pressure +* event when dragging starts. +*/ + wsmouse_input(sc-sc_wsmousedev, buttons, + alps-old_x, alps-old_y, 0, 0, + WSMOUSE_INPUT_ABSOLUTE_X + | WSMOUSE_INPUT_ABSOLUTE_Y + | WSMOUSE_INPUT_ABSOLUTE_Z + | WSMOUSE_INPUT_ABSOLUTE_W); + } + } - /* Simulate click (tap) */ - if (ges !fin) - z = 35; - - /* Generate a null pressure event (needed for tap drag) */ - if (ges fin !alps-old_fin) - z = 0; - - /* Generate a width value corresponding to one finger */ - if (z 0) - w = 4; - else - w = 0; + gesture = sc-packet[2] 0x03; + if (gesture != ALPS_TAP) { + w = z ? 4 : 0; + wsmouse_input(sc-sc_wsmousedev, buttons, x, y, z, w, + WSMOUSE_INPUT_ABSOLUTE_X + | WSMOUSE_INPUT_ABSOLUTE_Y + | WSMOUSE_INPUT_ABSOLUTE_Z + | WSMOUSE_INPUT_ABSOLUTE_W); + } - wsmouse_input(sc-sc_wsmousedev, buttons, x, y, z, w, - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | - WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W); + if (alps-gesture != ALPS_DRAG || gesture != ALPS_TAP) + alps-gesture = gesture; + + alps-old_x = x; + alps-old_y = y; - alps-old_fin = fin; } else { dx = dy = 0
tap-and-drag on ALPS touchpads
The tap-and-drag gesture doesn't work reliably with the ALPS touchpads supported by pms. To make it work, it is necessary to start dragging immediately with the second touch, which doesn't always succeed. Increasing the tap timeout helps, but doesn't change the principle. The patch below solves that problem. Tests and comments would be welcome. In case someone is interested in the background: I have observed the same problem with a Linux installation on a machine with an ALPS touchpad; however, increasing the tap timeout to a sufficiently high value (= 260ms) makes it work normally. The somewhat special behaviour of those ALPS models is described in this LKML posting: https://lkml.org/lkml/2004/7/28/210 The approach put forward there - which is partially reproduced in the current version of pms - is improved by the patch as follows: When the hardware signals a tap, the handler does nothing. The missing events will be emulated when the next packet arrives, which either signals the end of the gesture, or the start of a drag action. No timeout will occur even if the hardware introduces a long delay between the first and the second packet (which just happens when the finger is resting after the second contact). Index: dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.64 diff -u -p -r1.64 pms.c --- dev/pckbc/pms.c 20 Jul 2015 00:55:06 - 1.64 +++ dev/pckbc/pms.c 14 Aug 2015 18:27:57 - @@ -120,7 +120,8 @@ struct alps_softc { int min_x, min_y; int max_x, max_y; - int old_fin; + + u_int gesture; u_int sec_buttons; /* trackpoint */ @@ -1521,8 +1522,7 @@ pms_proc_alps(struct pms_softc *sc) { struct alps_softc *alps = sc-alps; int x, y, z, w, dx, dy; - u_int buttons; - int fin, ges; + u_int buttons, gesture; if ((alps-model ALPS_DUALPOINT) alps_sec_proc(sc)) return; @@ -1557,28 +1557,44 @@ pms_proc_alps(struct pms_softc *sc) y = ALPS_YMAX_BEZEL - y + ALPS_YMIN_BEZEL; if (alps-wsmode == WSMOUSE_NATIVE) { - ges = sc-packet[2] 0x01; - fin = sc-packet[2] 0x02; + if (alps-gesture == ALPS_TAP) { + /* Report a touch with the tap coordinates. */ + wsmouse_input(sc-sc_wsmousedev, buttons, + alps-old_x, alps-old_y, ALPS_PRESSURE, 4, + WSMOUSE_INPUT_ABSOLUTE_X + | WSMOUSE_INPUT_ABSOLUTE_Y + | WSMOUSE_INPUT_ABSOLUTE_Z + | WSMOUSE_INPUT_ABSOLUTE_W); + if (z 0) { + /* +* The hardware doesn't send a null pressure +* event when dragging starts. +*/ + wsmouse_input(sc-sc_wsmousedev, buttons, + alps-old_x, alps-old_y, 0, 0, + WSMOUSE_INPUT_ABSOLUTE_X + | WSMOUSE_INPUT_ABSOLUTE_Y + | WSMOUSE_INPUT_ABSOLUTE_Z + | WSMOUSE_INPUT_ABSOLUTE_W); + } + } - /* Simulate click (tap) */ - if (ges !fin) - z = 35; - - /* Generate a null pressure event (needed for tap drag) */ - if (ges fin !alps-old_fin) - z = 0; - - /* Generate a width value corresponding to one finger */ - if (z 0) - w = 4; - else - w = 0; + gesture = sc-packet[2] 0x03; + if (gesture != ALPS_TAP) { + w = z ? 4 : 0; + wsmouse_input(sc-sc_wsmousedev, buttons, x, y, z, w, + WSMOUSE_INPUT_ABSOLUTE_X + | WSMOUSE_INPUT_ABSOLUTE_Y + | WSMOUSE_INPUT_ABSOLUTE_Z + | WSMOUSE_INPUT_ABSOLUTE_W); + } - wsmouse_input(sc-sc_wsmousedev, buttons, x, y, z, w, - WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | - WSMOUSE_INPUT_ABSOLUTE_Z | WSMOUSE_INPUT_ABSOLUTE_W); + if (alps-gesture != ALPS_DRAG || gesture != ALPS_TAP) + alps-gesture = gesture; + + alps-old_x = x; + alps-old_y = y; - alps-old_fin = fin; } else { dx = dy = 0; if (z ALPS_PRESSURE) { Index: dev/pckbc/pmsreg.h === RCS file: /cvs/src/sys/dev/pckbc/pmsreg.h,v retrieving revision 1.11 diff -u
Re: add support for crc_enabled Elantech v3 touchpads
On 04/02/2015 03:39 AM, Fasse wrote: On Wed, 01 Apr 2015 21:23:15 +0200 Ulf Brosziewskiulf.brosziew...@t-online.de wrote: Yes, without some refactoring there won't be an elegant way. pms_sync_elantech_v2 encodes some sync state in the 'flags' field (ELANTECH_F_2FINGER_PACKET), but doing the same in the v3/CRC case might be ugly. Admittedly I am biased because I don't want to refactor ~2400 LOC to get my touchpad working but I don't think that crc enabled v3 touchpads use the debounce packet. I just installed Ubuntu and compiled the 3.19.3 linux kernel with added printk statements in the elantech_packet_check_v3 function on my laptop. In the linux kernel documentation [0] for elantech touchpads it says about the debounce packet: Note on debounce: In case the box has unstable power supply or other electricity issues, or when number of finger changes, F/W would send debounce packet to inform driver that the hardware is in debounce status. I could not reproduce the unstable power supply but when switching the number of fingers on the touchpad no debounce packet is issued. Instead just the head and tail packets are registered and processed (unlike the OpenBSD driver which ignores the tail packet). This leads me to belief that v3/crc does not use debounce packets. Do you think this is possible/likely? (...) Why not? You seem to have shown that it is possible, at least for your hardware and multiple touches. It might well be that the author(s) of the Linux driver just wanted to be on the safe side. (...) There doesn't appear to be any official documentation in regard to elantech touchpads, hence I can't be certain. Nonetheless a refactor would obviously be beneficial but in the interim the patch might do a sufficient job. [0] https://www.kernel.org/doc/Documentation/input/elantech.txt
Re: add support for crc_enabled Elantech v3 touchpads
On 04/01/2015 08:46 PM, Fasse wrote: On Wed, 01 Apr 2015 20:05:46 +0200 Ulf Brosziewskiulf.brosziew...@t-online.de wrote: Hi, there might be a problem. The Linux driver for that touchpad type also accepts debounce packets, which have the same format as for the non-crc version. I have no idea whether that is correct and if those packets do occur in practice, but if they do they wouldn't pass this version of sync() (byte 3 would be 0x02 then). You are right. I haven't had issues so far with debounce packets missing but I obviously only have a very small sample size so there is that. Since the debounce packet is ignored anyways I don't know if it matters that it is thrown out early. Although if it didn't matter there probably wouldn't even be a debounce packet? We could allow byte 3 to pass if its value after the check is 0x02 but that kind of defeats the purpose of the integrity check I guess. Fortunately the values of debounce and head packets match up for non crc elantech v3 touchpads. I don't think there is an elegant way to solve this problem because pms_sync_elantech_v3 is called before the packet is complete and you need the whole packet to check if it is a debounce packet. To solve this we would have to do somthing similar to the linux driver by only checking complete packets. Yes, without some refactoring there won't be an elegant way. pms_sync_elantech_v2 encodes some sync state in the 'flags' field (ELANTECH_F_2FINGER_PACKET), but doing the same in the v3/CRC case might be ugly.
Re: add support for crc_enabled Elantech v3 touchpads
Hi, there might be a problem. The Linux driver for that touchpad type also accepts debounce packets, which have the same format as for the non-crc version. I have no idea whether that is correct and if those packets do occur in practice, but if they do they wouldn't pass this version of sync() (byte 3 would be 0x02 then). On 04/01/2015 05:44 PM, Fasse wrote: This diff adds support for Elantech v3 touchpads using the crc_enabled integrity check. I tested this patch with my Elantech v3 touchpad using firmware version 0x454f00, it now works correctly. Other hardware versions should not be affected by this change. I could not check if this introduces regression with other firmware versions. If you have an elantech touchpad, particularly v3, could you please try this diff and see if it causes any issues. Index: sys/dev/pckbc/pms.c === RCS file: /cvs/src/sys/dev/pckbc/pms.c,v retrieving revision 1.58 diff -u -p -r1.58 pms.c --- sys/dev/pckbc/pms.c 26 Mar 2015 01:30:22 - 1.58 +++ sys/dev/pckbc/pms.c 1 Apr 2015 14:22:10 - @@ -137,6 +137,7 @@ struct elantech_softc { #define ELANTECH_F_HAS_ROCKER 0x02 #define ELANTECH_F_2FINGER_PACKET 0x04 #define ELANTECH_F_HW_V1_OLD 0x08 +#define ELANTECH_F_CRC_ENABLED 0x10 int fw_version; int min_x, min_y; @@ -1812,6 +1813,9 @@ elantech_get_hwinfo_v3(struct pms_softc elantech-fw_version = fw_version; elantech-flags |= ELANTECH_F_REPORTS_PRESSURE; + if ((fw_version 0x4000) == 0x4000) + elantech-flags |= ELANTECH_F_CRC_ENABLED; + if (elantech_set_absolute_mode_v3(sc)) return (-1); @@ -2164,14 +2168,23 @@ pms_sync_elantech_v2(struct pms_softc *s int pms_sync_elantech_v3(struct pms_softc *sc, int data) { + struct elantech_softc *elantech = sc-elantech; + switch (sc-inputstate) { case 0: + if (elantech-flags ELANTECH_F_CRC_ENABLED) + break; if ((data 0x0c) != 0x04 (data 0x0c) != 0x0c) return (-1); break; case 3: - if ((data 0xcf) != 0x02 (data 0xce) != 0x0c) - return (-1); + if (elantech-flags ELANTECH_F_CRC_ENABLED) { + if ((data 0x09) != 0x08 (data 0x09) != 0x09) + return (-1); + } else { + if ((data 0xcf) != 0x02 (data 0xce) != 0x0c) + return (-1); + } break; } @@ -2271,11 +2284,18 @@ pms_proc_elantech_v3(struct pms_softc *s * and a tail packet. We report a single event and ignore * the tail packet. */ - if ((sc-packet[0] 0x0c) != 0x04 - (sc-packet[3] 0xcf) != 0x02) { - /* not the head packet -- ignore */ - return; + switch (elantech-flags ELANTECH_F_CRC_ENABLED) { + case 0: + if ((sc-packet[0] 0x0c) != 0x04 + (sc-packet[3] 0xcf) != 0x02) { + /* not the head packet -- ignore */ + return; + } + case ELANTECH_F_CRC_ENABLED: + if ((sc-packet[3] 0x09) != 0x08) + return; } + } /* Prevent juming cursor if pad isn't touched or reports garbage. */
Re: touchpad slight regression (snap: 20141121-20150217)
On 02/28/2015 09:38 AM, Martin Pieuchot wrote: [moved to tech@] On 27/02/15(Fri) 11:40, patrick keshishian wrote: Hi, On 2/26/15, Ulf Brosziewskiulf.brosziew...@t-online.de wrote: On 02/27/2015 03:31 AM, Ulf Brosziewski wrote: ... It might be that the following patch to wsmouse.c solves the problem with the new version of wsconscomm. Tests would be welcome (I could only verify that the patch does no harm to other touchpad types, i.e., Elantech-v4 and Alps Glidepoint). [...] Sorry, the change was in the wrong place and would only do a half of the work. It should look like: Index: wsmouse.c === RCS file: /cvs/src/sys/dev/wscons/wsmouse.c,v retrieving revision 1.26 diff -u -p -r1.26 wsmouse.c --- wsmouse.c 27 Oct 2014 13:55:05 - 1.26 +++ wsmouse.c 27 Feb 2015 02:50:06 - @@ -433,6 +433,9 @@ wsmouse_input(struct device *wsmousedev, } } + if (sc-sc_z == 0) + sc-sc_w = INVALID_W; + mb = sc-sc_mb; while ((d = mb ^ ub) != 0) { /* I can confirm this change alone causes no adverse, observable change on my x120e's touchpad. I the long term, I think that having a similar logic in wsmouse_input() makes sense. As I already told Ulf, it would be really nice to improve the wsmouse(4)/wscons(4) layer to support modern touchpad features and get rid of wsconscomm. But right now this chunk is really intrusive. Plus I believe it should only be applied on touchpad ``native'' mode. Sure, we could be able to check for WSMOUSE_INPUT_ABSOLUTE_W, but can it be a bad idea? What about putting a similar chunk in pms_proc_synpatics() instead? However, I would appreciate it if someone could enlighten me as to what the Z and W axis refer. I'm glad you asked, because it really depends on which hardware you're using :) Plus right now our code use magic values which are most of the time not documented. Diffs are more than welcome to improve the situation. Martin I was a bit hasty with that patch. I reasoned that sc_z is initialized with INT_MAX, and it is only used in native mode. Later I thought that change to wsconscomm might be a better (short-term) solution, something like the code below. But it doesn't look less odd than the other patch, or does it? It is not clear to me how a purely local change to pms_proc_input() could help here. As long as we don't add or redefine event types, or introduce a special convention for W values, the only way to circumvent the problem might be to produce an additional event at the start of a two-finger touch (i.e., to change W from 0 to 1 and back again). diff --git a/wsconscomm.c b/wsconscomm.c index f6b9d88..78f47ab 100644 --- a/wsconscomm.c +++ b/wsconscomm.c @@ -217,6 +217,14 @@ WSConsReadHwState(InputInfoPtr pInfo, if (hw-z == 0) { hw-fingerWidth = 0; hw-numFingers = 0; +} else if (hw-numFingers == 0) { +/* + * Because W may be 0 already, a two-finger touch on a + * Synaptics touchpad doesn't necessarily produce an update + * event for W. + */ +hw-fingerWidth = 5; +hw-numFingers = 2; } hw-millis = 1000 * event.time.tv_sec + event.time.tv_nsec / 100; SynapticsCopyHwState(hwRet, hw);
Re: elantech-v4 clickpad support
On 01/30/2015 11:04 AM, Ulf Brosziewski wrote: On 01/30/2015 07:15 AM, Martin Pieuchot wrote: On 30/01/15(Fri) 01:25, Ulf Brosziewski wrote: Probably I was too sceptical about synaptics.c. The bug I observed with the ALPS touchpad seems to be due to a kind of mismatch between the ALPS code in pms and the event handling in wsconscomm. The patch below contains the initial change as well as what was necessary to fix this. Do you think it is possible to fix the pms(4) driver instead of adding another quirk? ... Certainly that would be a better solution. For synaptics hardware there seems to be no specific W value that signals the end of a touch. If I understand it correctly, the hardware reports zero coordinates instead and the X driver adjusts its state accordingly. I will try to check soon whether this is correct and whether the ALPS code could be adapted. I couldn't test it directly, but according to the Synaptics PS/2 TouchPad Interfacing Guide synaptics hardware does indeed signal a W value of 0 if there is no pressure as well as for two-finger contacts. This means that the ALPS part of pms is correct and shouldn't be changed. For a proper finger count Z must be checked, and the place to do this is probably in wsconscomm. I have changed the patch accordingly. The change in the new version applies to all touchpad/clickpad models and would require appropriate testing. In my own tests with the ALPS Glidepoint touchpad and the Elantech Clickpad - and the patched pms version - I didn't observe any problems. diff --git a/wsconscomm.c b/wsconscomm.c index df3512d..70c103a 100644 --- a/wsconscomm.c +++ b/wsconscomm.c @@ -132,12 +132,6 @@ WSConsReadHwState(InputInfoPtr pInfo, struct wscons_event event; Bool v; -/* Reset cumulative values if buttons were not previously pressed */ -if (!hw-left !hw-right !hw-middle) { -hw-cumulative_dx = hw-x; -hw-cumulative_dy = hw-y; -} - while (WSConsReadEvent(pInfo, event)) { switch (event.type) { case WSCONS_EVENT_MOUSE_UP: @@ -187,9 +181,11 @@ WSConsReadHwState(InputInfoPtr pInfo, break; case WSCONS_EVENT_MOUSE_ABSOLUTE_X: hw-x = event.value; +hw-cumulative_dx = hw-x; break; case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: hw-y = priv-maxy - event.value + priv-miny; +hw-cumulative_dy = hw-y; break; case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: hw-z = event.value; @@ -218,6 +214,10 @@ WSConsReadHwState(InputInfoPtr pInfo, } break; case WSCONS_EVENT_SYNC: +if (hw-z == 0) { +hw-fingerWidth = 0; +hw-numFingers = 0; +} hw-millis = 1000 * event.time.tv_sec + event.time.tv_nsec / 100; SynapticsCopyHwState(hwRet, hw); return TRUE;
Re: elantech-v4 clickpad support
On 01/30/2015 07:15 AM, Martin Pieuchot wrote: On 30/01/15(Fri) 01:25, Ulf Brosziewski wrote: Probably I was too sceptical about synaptics.c. The bug I observed with the ALPS touchpad seems to be due to a kind of mismatch between the ALPS code in pms and the event handling in wsconscomm. The patch below contains the initial change as well as what was necessary to fix this. Do you think it is possible to fix the pms(4) driver instead of adding another quirk? ... Certainly that would be a better solution. For synaptics hardware there seems to be no specific W value that signals the end of a touch. If I understand it correctly, the hardware reports zero coordinates instead and the X driver adjusts its state accordingly. I will try to check soon whether this is correct and whether the ALPS code could be adapted.
Re: elantech-v4 clickpad support
Probably I was too sceptical about synaptics.c. The bug I observed with the ALPS touchpad seems to be due to a kind of mismatch between the ALPS code in pms and the event handling in wsconscomm. The patch below contains the initial change as well as what was necessary to fix this. diff --git a/wsconscomm.c b/wsconscomm.c index df3512d..9c5afe7 100644 --- a/wsconscomm.c +++ b/wsconscomm.c @@ -132,12 +132,6 @@ WSConsReadHwState(InputInfoPtr pInfo, struct wscons_event event; Bool v; -/* Reset cumulative values if buttons were not previously pressed */ -if (!hw-left !hw-right !hw-middle) { -hw-cumulative_dx = hw-x; -hw-cumulative_dy = hw-y; -} - while (WSConsReadEvent(pInfo, event)) { switch (event.type) { case WSCONS_EVENT_MOUSE_UP: @@ -187,9 +181,11 @@ WSConsReadHwState(InputInfoPtr pInfo, break; case WSCONS_EVENT_MOUSE_ABSOLUTE_X: hw-x = event.value; +hw-cumulative_dx = hw-x; break; case WSCONS_EVENT_MOUSE_ABSOLUTE_Y: hw-y = priv-maxy - event.value + priv-miny; +hw-cumulative_dy = hw-y; break; case WSCONS_EVENT_MOUSE_ABSOLUTE_Z: hw-z = event.value; @@ -204,8 +200,14 @@ WSConsReadHwState(InputInfoPtr pInfo, /* XXX magic number mapping which is mirrored in pms driver */ switch (event.value) { case 0: -hw-fingerWidth = 5; -hw-numFingers = 2; +if (priv-model != MODEL_ALPS) { +hw-fingerWidth = 5; +hw-numFingers = 2; +} else { +/* For ALPS models pms reports that w is 0 if (z = 0)? */ +hw-fingerWidth = 0; +hw-numFingers = 0; +} break; case 1: hw-fingerWidth = 5;
Re: elantech-v4 clickpad support
On 01/25/2015 04:07 PM, Alexandr Shadchin wrote: On Wed, Jan 14, 2015 at 12:23:13AM +0100, Ulf Brosziewski wrote: Currently pms and the wsconscomm module of the synaptics driver offer a somewhat limited support for Elantech clickpads with hardware version 4. Above all, I missed the options of performing click-and-drag operations with two fingers and of using a soft button area for the emulation of right button clicks (tap-and-drag and two-finger tapping are no alternatives for me, usually I don't enable tapping). I have written two patches that provide these options (I'm using them [...] Sorry for the long answer. I tested xenocara part on x201(synaptics touchpad) and x220(synaptics clickpad), this works, no regress, even works click-and-drag :) I have no other touchpads (ALPS, Elantech) and I can not test patch on them. Has anyone else tried this diff? [...] Thanks for the feedback. Meanwhile, I have tested the patch to the synaptics driver with an ALPS touchpad (ALPS Glidepoint, version 0x7321). As expected, it seems that the patch doesn't affect the driver's behaviour as long as clickpad support is disabled. However, when I enabled that support for testing purposes - there is no other reason to do that because the touchpad has two external buttons -, it showed inconsistencies. Making two successive touches while the left button is being pressed may produce cursor jumps. I haven't had the time to look at synaptics.c again, but I could check what a recent Linux version of the driver does with that touchpad: When the clickpad option is enabled, left clicks make the X cursor freeze. Perhaps the clickpad code of the driver wasn't meant to work seamlessly with all touchpads, and if this is the case, then the wsconscomm patch is too simplistic in this form. At least I think it shouldn't unmask such defects, even where the clickpad support makes no sense. I'm sorry that I had to draw these negative conclusions now. It is not clear to me whether these things could be fixed with reasonable means.
Re: elantech-v4 clickpad support
On 01/14/2015 02:03 AM, Alexey Suslikov wrote: Ulf Brosziewskiulf.brosziewskiat t-online.de writes: I have written two patches that provide these options (I'm using them on an Acer V5-131 netbook with OpenBSD 5.6/amd64, the clickpad hardware and firmware is identified as Elantech Clickpad, version 4, firmware 0x461f02). There is, however, an open question concerning wsconscomm. Should I try on bios0: ASUSTeK COMPUTER INC. X200CA pms0: Elantech Clickpad, version 4, firmware 0x361f01 or it is somewhat another hardware/firmware? Only the hardware version should play a role here, so this would make sense.