Re: wsmouse(4): multi-touch buttons again

2023-06-27 Thread Ulf Brosziewski
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

2023-05-22 Thread Ulf Brosziewski
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

2023-02-23 Thread Ulf Brosziewski
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

2023-02-21 Thread Ulf Brosziewski
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

2023-02-09 Thread Ulf Brosziewski
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

2023-02-07 Thread Ulf Brosziewski
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

2022-09-19 Thread Ulf Brosziewski
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

2022-09-13 Thread Ulf Brosziewski
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

2022-05-20 Thread Ulf Brosziewski
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

2022-05-06 Thread Ulf Brosziewski
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

2022-05-03 Thread Ulf Brosziewski
... 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

2022-05-03 Thread Ulf Brosziewski
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

2022-04-15 Thread Ulf Brosziewski
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

2021-03-23 Thread Ulf Brosziewski
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

2021-03-23 Thread Ulf Brosziewski
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

2021-03-23 Thread Ulf Brosziewski
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

2021-03-23 Thread Ulf Brosziewski
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

2021-03-22 Thread Ulf Brosziewski
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

2021-03-20 Thread Ulf Brosziewski
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

2021-03-01 Thread Ulf Brosziewski
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

2021-03-01 Thread Ulf Brosziewski
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

2021-02-15 Thread Ulf Brosziewski
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

2020-10-15 Thread Ulf Brosziewski
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

2020-10-14 Thread Ulf Brosziewski
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

2020-10-11 Thread Ulf Brosziewski
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

2020-09-29 Thread Ulf Brosziewski
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

2020-09-13 Thread Ulf Brosziewski
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

2020-05-18 Thread Ulf Brosziewski
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

2020-03-13 Thread Ulf Brosziewski
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

2019-09-16 Thread Ulf Brosziewski
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

2019-08-18 Thread Ulf Brosziewski
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

2019-08-13 Thread Ulf Brosziewski
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

2019-08-12 Thread Ulf Brosziewski
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

2019-03-22 Thread Ulf Brosziewski
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

2019-03-17 Thread Ulf Brosziewski
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

2019-03-13 Thread Ulf Brosziewski
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

2019-03-13 Thread Ulf Brosziewski
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

2019-03-12 Thread Ulf Brosziewski
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

2019-03-05 Thread Ulf Brosziewski
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

2019-03-05 Thread Ulf Brosziewski
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

2018-12-15 Thread Ulf Brosziewski
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

2018-12-04 Thread Ulf Brosziewski
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

2018-11-06 Thread Ulf Brosziewski
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

2018-11-04 Thread Ulf Brosziewski
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

2018-08-16 Thread Ulf Brosziewski
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

2018-07-29 Thread Ulf Brosziewski
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) ?

2018-06-17 Thread Ulf Brosziewski
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

2018-05-13 Thread Ulf Brosziewski
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

2017-10-29 Thread Ulf Brosziewski
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

2017-10-08 Thread Ulf Brosziewski
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)

2017-10-08 Thread Ulf Brosziewski
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

2017-09-19 Thread Ulf Brosziewski
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

2017-08-21 Thread Ulf Brosziewski
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

2017-03-09 Thread Ulf Brosziewski
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

2017-03-06 Thread Ulf Brosziewski
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

2016-09-08 Thread Ulf Brosziewski
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

2016-09-06 Thread Ulf Brosziewski
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

2016-07-16 Thread Ulf Brosziewski
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

2016-07-13 Thread Ulf Brosziewski
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

2016-07-12 Thread Ulf Brosziewski
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

2016-07-04 Thread Ulf Brosziewski
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

2016-06-06 Thread Ulf Brosziewski
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

2016-06-05 Thread Ulf Brosziewski
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

2016-06-05 Thread Ulf Brosziewski
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]

2016-06-05 Thread Ulf Brosziewski
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

2016-06-05 Thread Ulf Brosziewski
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]

2016-06-05 Thread Ulf Brosziewski
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

2016-05-31 Thread Ulf Brosziewski
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]

2016-05-31 Thread Ulf Brosziewski
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

2016-05-21 Thread Ulf Brosziewski
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

2016-05-14 Thread Ulf Brosziewski
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

2016-04-21 Thread Ulf Brosziewski
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

2016-04-16 Thread Ulf Brosziewski
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

2016-03-25 Thread Ulf Brosziewski
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

2016-03-25 Thread Ulf Brosziewski
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

2016-03-24 Thread Ulf Brosziewski

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

2016-03-20 Thread Ulf Brosziewski

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

2016-03-19 Thread Ulf Brosziewski

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

2016-03-19 Thread Ulf Brosziewski

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

2016-03-13 Thread Ulf Brosziewski

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

2016-03-13 Thread Ulf Brosziewski

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

2016-03-13 Thread Ulf Brosziewski

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

2015-12-16 Thread Ulf Brosziewski

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

2015-12-15 Thread Ulf Brosziewski

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

2015-12-07 Thread Ulf Brosziewski

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

2015-12-02 Thread Ulf Brosziewski

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

2015-11-29 Thread Ulf Brosziewski

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

2015-08-29 Thread Ulf Brosziewski

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

2015-08-28 Thread Ulf Brosziewski


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

2015-08-22 Thread Ulf Brosziewski

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

2015-08-14 Thread Ulf Brosziewski


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

2015-04-02 Thread Ulf Brosziewski

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

2015-04-01 Thread Ulf Brosziewski

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

2015-04-01 Thread Ulf Brosziewski

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)

2015-02-28 Thread Ulf Brosziewski

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

2015-02-03 Thread Ulf Brosziewski

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

2015-01-30 Thread Ulf Brosziewski

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

2015-01-29 Thread Ulf Brosziewski

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

2015-01-26 Thread Ulf Brosziewski

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

2015-01-13 Thread Ulf Brosziewski

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.



  1   2   >