[PATCH weston 21/25] protocol: add weston_touch_calibration

Pekka Paalanen ppaalanen at gmail.com
Fri Apr 13 07:51:37 UTC 2018


On Fri, 13 Apr 2018 14:31:39 +1000
Peter Hutterer <peter.hutterer at who-t.net> wrote:

> On Wed, Apr 11, 2018 at 02:00:49PM +0300, Pekka Paalanen wrote:
> > On Wed, 11 Apr 2018 10:16:46 +1000
> > Peter Hutterer <peter.hutterer at who-t.net> wrote:  

> > > > > > +  <interface name="weston_touch_calibrator" version="1">
> > > > > > +    <description summary="calibrator surface for a specific touch device">
> > > > > > +      On creation, this object is tied to a specific touch device. The
> > > > > > +      server sends a configure event which the client must obey with the
> > > > > > +      associated wl_surface.
> > > > > > +
> > > > > > +      Once the client has committed content to the surface, the server can
> > > > > > +      grab the touch input device, prevent it from emitting normal touch events,
> > > > > > +      show the surface on the correct output, and relay input events from the
> > > > > > +      touch device via this protocol object.
> > > > > > +
> > > > > > +      Touch events from other touch devices than the one tied to this object
> > > > > > +      must generate wrong_touch events on at least touch-down and must not
> > > > > > +      generate normal or calibration touch events.
> > > > > > +
> > > > > > +      At any time, the server can choose to cancel the calibration procedure by
> > > > > > +      sending the cancel_calibration event. This should also be used if the
> > > > > > +      touch device disappears or anything else prevents the calibration from
> > > > > > +      continuing on the server side.
> > > > > > +
> > > > > > +      If the wl_surface is destroyed, the server must cancel the calibration.
> > > > > > +
> > > > > > +      The touch event coordinates and conversion results are delivered in
> > > > > > +      calibration units. Calibration units are in the closed interval
> > > > > > +      [0.0, 1.0] mapped into 32-bit unsigned integers. An integer can be      
> > > > > 
> > > > > should probably add what 0.0 and 1.0 represent on each axis, i.e. nominal
> > > > > width and height of the device's sensor. Or is this something we need to
> > > > > hide?    
> > > > 
> > > > I'm not sure. The underlying assumption is that there is a finite and
> > > > closed range of values a sensor can output, and that is mapped to [0,
> > > > 1]. I don't know what nominal width and height are or can the values
> > > > extend to negative. It might be easier to define the calibration units
> > > > without defining those first.    
> > > 
> > > sorry, I used "nominal" before I rewrote to use "sensor", probably made it
> > > more confusing. On some devices, the sensor is larger than the screen so you
> > > can get coordinates outside the screen area. This is not a technical
> > > problem, just a user perception mismatch that doens't need to be exposed and
> > > after all that's what calibration is about.
> > > 
> > > Once you apply calibration though you can get real negative coordinates,
> > > especially if the device advertises a [n:m] range but then sends events less
> > > than n. For example, all synaptics touchpads (pre 2014, some after that) do
> > > that.  
> > 
> > But wait, if there are actually devices that report the range [n:m] but
> > can still send values less than n or greater than m, it means I cannot
> > transmit those with the encoding set up here, because
> > libinput_event_touch_get_x_transformed(touch_event, 1) can return
> > values outside of [0, 1] even when the loaded calibration matrix is
> > identity. Is that right?  
> 
> correct, that can happen.
> 
> > Do I need to find an encoding to cope with that, or can I just reject
> > such touches?
> > 
> > I mean, the range [n:m] is in raw input coordinates, before any
> > normalization or calibration in userspace, right?  
> 
> uhm. let me just detail this and you can pick which one was the answer to
> that question:
> - the kernel exposes [n:m] axis ranges for ABS_X/Y and the MT equivalents
> - libinput converts this into mm by default, see libinput_event_touch_get_x()
> - libinput converts this to a ranged value [0:N] when calling
>   libnput_event_touch_get_x_transformed(N). This is what weston uses to get
>   the screen coordinates.
> 
> Both libinput values have the calibration factored in already.
> 
> Weston doesn't ever see raw input coordinates. But if you use
> get_x_transformed, you can get values outside [0:N]. This happens when
> the [n:m] range is incorrect. Accommodating for some error margin, libinput
> will print a warning to the log when this happens.
> 
> The correct solution would be to warn the user that the device is garbage
> and make them put a 60-evdev.hwdb quirk in to fix the axis ranges.
> Depending on the device, this could be a generic solution but let's not bet
> on that...
> 
> The user-friendly solution would be to have two layers of mapping. By
> default, you map the libinput range into [0, 1]. Whenever you see negative
> values or values > 1 you notify the user that this screen is garbage. The
> only option you have now is to get the user to touch the furthest extents of
> all axes to get the lowest and highest values the axis provides (similar to
> the touchpad-edge-detector tool). Then you can map those into the libinput
> provided range so that e.g. libinput's -0.25 is normalized 0 and 1.25 is
> normalized 1.0.
> 
> Now you can restart calibration with that extra mapping on top. 
> 
> A few caveats, beyond the effort required:
> - even with the calibration matrix applied, the libinput ranges will still
>   be outside the [0:N] range. Only a real axis fix can fix that
> - you cannot know the true min/max until you get respective event from the
>   screen
> 
> So yeah, the situation is less than ideal...
> 
> I've considered auto-scaling libinput into the new axis range but this is
> likely going to hurt even more because it's undiscoverable and for most
> devices, a quirk in the hwdb file can solve this problem properly.

Thank you very much for the thorough explanation.

I think the appropriate solution for me here is to check whether the
normalized value I expect to be in [0, 1] falls outside of the range,
and if so, I will a) print a warning in Weston's log that the device
may need a quirk like you explained, and b) send the "invalid touch"
event instead of a touch event to the calibrator app.

This makes the calibrator app show a big red cross, so the user will
know something is strange if he thinks he did touch the correct spot.

Well, it does touch-downs at least. I think if motion event would end
up out of range, I'll send cancel event followed by invalid touch.
Whee, I found use for the cancel event!

> > > These devices are a problem because we rely on the coordinate range for the
> > > size and then on the calibration on top to normalize the input. So they may
> > > need two fixes, one for the range adjustment, one for calibration.  
> > 
> > If I can just transmit whatever values I get for "normalized" with
> > identity in the above, then the calibration matrix will automatically
> > account for any out-of-range values - I mean they become a non-issue,
> > because the compositor just tranforms them to the output or a global
> > coordinate system first and then clips to the actual output area. Or
> > doesn't clip, makes no difference.
> >   
> > > > It doesn't really matter, the important point is that when the
> > > > resulting matrix is loaded into libinput and then libinput is used
> > > > according to its API, the result is as expected. I'd be tempted to just
> > > > punt all this to libinput.    
> > > 
> > > libinput will sort-of punt it back :)
> > > https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-bounds
> > >   
> > 
> > I don't see a problem in that section. The goal of this calibration is
> > to match input event coordinates to output pixel coordinates in the
> > complete pipeline by adjusting the normalized calibration matrix in
> > libinput. It's ok for calibrated input coordinates go beyond any
> > limits, the input and output coordinate planes can be thought as
> > infinite.
> > 
> > Or do you refer to the functions returning positions in millimeters? I
> > never looked at those, they're not used with touchscreens. I don't even
> > know if a calibration matrix affects them.  
> 
> There's a corner-case with touchscreens and mm. Plenty of cheap touchscreens
> don't have a resolution set, so the mm value is calculated using the default
> resolution of 1.
> 
> The calibration matrix is applied to the mm as well. That's largely a
> side-effect for the matrix originally being used for rotation rather than
> scaling or translation.

Right. If someone needs this calibration method to work on devices that
user by millimeter units, I'll let them figure out what to fix if
anything. :-)


Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20180413/294931b7/attachment.sig>


More information about the wayland-devel mailing list