wl_tablet draft v2

Peter Hutterer peter.hutterer at who-t.net
Tue Aug 5 18:54:28 PDT 2014


On Tue, Aug 05, 2014 at 06:18:00PM -0700, Jason Gerecke wrote:
> On Sat, Aug 2, 2014 at 12:31 PM, Lyude <thatslyude at gmail.com> wrote:
> > I'm sorry I took so long to reply to this! I only just found this e-mail
> > while I was cleaning my inbox up.
> >
> > On Wed, 2014-07-30 at 17:33 -0700, Jason Gerecke wrote:
> >> On Tue, Jul 29, 2014 at 12:44 PM, Lyude <thatslyude at gmail.com> wrote:
> >> > I'm more then willing to add something to get the resolution
> >> > information, it wouldn't be too difficult to implement. I think I'm
> >> > missing or forgetting something here though; why wouldn't we be able to
> >> > get an actual value in degrees from the normalized values we're getting
> >> > from the compositor? The value should be mapped from (-65535.0) -
> >> > 65535.0 by the compositor (libinput is the portion that maps it from
> >> > (-1.0) - 1.0), couldn't we just map that to 0-180°? I would have thought
> >> > the max value tilt value on a tool should always be equal to 180°, and
> >> > the minimum 0°.
> >> >
> >> It is my understanding that libinput normalizes the values so that the
> >> minimum tilt => -1.0 and maximum tilt => +1.0. This data is then
> >> up-scaled by the compositor so that -1.0 => 65535 and +1.0 => +65535.
> >> This alone does not provide enough information to an application to
> >> recover the physical angle. One tablet may have a maximum tilt from
> >> vertical of 45°, another 60°, and yet another 90°. In each case
> >> maximum tilt would be represented by +1.0 or +65535, but there's no
> >> way an application can figure out how many degrees that corresponds
> >> to.
> > Okay, I had assumed that all tablets just provided values between 0° and
> > 180°.
> >
> >> One solution -- as you suggest -- is to have libinput/Wayland define a
> >> unit system and send what I call "canonicalized" instead of
> >> "normalized" data. You could define that in libinput -1.0 == 0° and
> >> +1.0 == 180°; in Wayland -65535 == 0° and +65535 == 180°. In this
> >> case, reports of 0.50/0.67/1.0 and 32768/43690/65535 would be sent
> >> when my hypothetical tablets above were at maximum tilt. As long as
> >> the correspondences were documented, a programmer would have enough
> >> information to convert the values to whatever values they want.
> >>
> >> Of course, the unit system you define for your canonical data is
> >> arbitrary, as you point out:
> >>
> >> > Also, since we're talking about getting the value in degrees, it might
> >> > be worth it just to have the Wayland protocol return the values in
> >> > degrees by default to save some time for the clients.
> >> >
> >>
> >> This is one of the downsides of canonical data. There's always someone
> >> out there who disagrees on units and so needs to perform a conversion.
> >> Degrees would make things easy for Qt and could be expressed directly
> >> in Wayland's 24.8 fixed-point format with a fair amount of precision.
> >> Radians are used natively by all the trigonometric functions, are the
> >> unit of choice for Android, and are the front-runner in designing
> >> Enlightenment's pen API. The "half-turn" is an uncommon units, but
> >> it's what GTK+ applications like GIMP and Inkscape assume they've been
> >> handed.
> >>
> >> There are other reasons I'm not a big fan of passing around data in
> >> canonical forms as well (can't send data from devices that don't
> >> advertise a resolution, inconsistent API, doesn't really cut down on
> >> the amount of data that needs to be exposed, etc.). As an alternative
> >> to the canonical route, you can leave the data normalized but provide
> >> a function that returns a scale factor defining what +1.0 (or +65535)
> >> means in physical units. Whatever program receives the value /may/ do
> >> a conversion if they wish, or can leave the value normalized for
> >> others further down the line.
> >>
> >> I wouldn't have libinput use degrees, but it might make some sense for
> >> Wayland. The downsides probably don't outweigh the ugliness involved
> >> with shuttling normalized data across the wire*.
> > I actually think using degrees might be a good idea if we have the
> > guarantee that they're accurate enough most of the time. To be honest,
> > the more that I think about it, I think it would be better to try to
> > avoid the use of normalized values when we can convert them to something
> > better. And, like you said, the number of clients that want the value in
> > something other than degrees is in the minority. Of course this brings
> > up the issue you just mentioned though: not all tablets report
> > resolution information, and this has the potential of limiting the API.
> >
> > So, I'm guessing there's two situations where we'd have a device that
> > can't advertise it's resolution:
> >      1. A device that can report it's resolution, but for whatever
> >         reason the kernel driver doesn't have support for this feature.
> >      2. A device that is physically incapable of reporting resolution
> >         information
> > For #1, I think we'd be better off not worrying about this. In
> > situations where we have a kernel driver for a device that doesn't
> > forward it's resolution, I think the best solution would be to fix the
> > kernel driver instead of trying to work around it.
> > For #2, I think that even if the device doesn't report a resolution,
> > that we could still figure out a resolution for the device just by
> > measuring it by hand. E.g., measure the max/min angle of the tablet,
> > come up with a scale for that to translate the raw values from the
> > tablet into degrees, and then have the kernel advertise that as the
> > resolution. Again though, this assumes that the device's tilt values are
> > reliable.
> >
> Although I agree that we should try to fix things in the kernel
> wherever possible, sometimes it isn't practical. The main issue I see
> is that oftentimes you are dealing with axes whose data happens to be
> *qualitative* rather than *quantitative*. Pressure on our tablets, for
> instance, is a qualitative measure and it would be impractical (at
> best) to characterize and correct for the force-response curve of
> every pen model. Although tilt is quantitative on our tablets, there's
> nothing preventing somebody else from releasing a tablet that had
> qualitative tilt values.

well, here's the problem: I'm all for real-world measurements because they
are harder to mis-interpret (or at least you know what's wrong easily).
but if we don't have any current hardware (and nothing we know of in the
pipe) that comes close to supporting the real-world measurement we're pretty
much screwed because we can't pretend we know the right values we're
promising. If you say that wacom tablets are accurate enough that formula X
gets us from the values to degrees within some reasonable error margin, then
that's good enough for me. if not, then normalized from "hardware-specific
min to max" is the better option.

wacom has enough of a market share in this field that your tablets matter:
if we can make it work well for yours, we can probably hack up the other
devices we encounter give us good-enough values too.

as for units, 24.8 lends itself to degrees more than anything.
 
> > So, for devices that we don't have any resolution information for yet,
> > we could report a range of 0-180° and add a flag to the
> > wl_tablet_manager::device_added event that tells the client that we
> > don't have any resolution information for this device, and that the
> > range we're reporting for the device may not be accurate.
> >
> > So, with each tablet we would specify the actual maximum and minimum it
> > can report in terms of degrees. Because we're reporting this, anyone who
> > needs the value in a normalized form would easily be able to calculate
> > it, and we'd still be able to report the values in degrees by default.
> >
> Do we extend this convention to other axes as well? That is, have all
> pressure and distance also use minimums and maximums (in e.g. newtons
> and meters) with their own flags? It would make the API (mostly)
> consistent, though I'm afraid that people wouldn't notice the
> "range_is_bogus" flags and assume that qualitative values are actually
> quantitative...

imo adding a flag that says "this unit is bogus" when it applies to
virtually 100% of the hardware out there is not overly helpful.
so either we can map pressure/distance into some meaningful units on current
hardware or we can't. if we can't we solve that problem if and when it
actually occurs.
 
> >> * Seriously, can anyone explain why the wire protocol doesn't have a
> >> floating-point type? Practically every system supports the 32-bit
> >> IEEE754 single-precision binary format, and to for those that don't,
> >> we can pull a play from the fixed-point playbook and define a
> >> "wl_single_t" and associated conversion functions (which would just do
> >> a cast unless you happen to be on one of those weird architectures).
> >> Should I just make a patch for this already? :P
> > I've asked Peter about this, and he's told me the reasons but I can't
> > remember them off the top of my head.
> >
> > Since we're sticking to fixed-width integers in the protocol, I think we
> > should add something like "wl_fraction_t", where we have 30 bits
> > dedicated to the fractional portion and 2 bits dedicated to the integer
> > portion, allowing us to represent the values -1.0 to 1.0 with
> > fixed-width numbers. This would be kind of a big change though, but it
> > would mean we wouldn't have to stick to values like (-65535)-65535.
> >
> Hopefully Peter can chime in if he's watching, because I'd really like
> to know. :( Some kind of wl_fraction_t type might be an interesting
> alternative, and would be more self-documenting than the normalized
> range we're using now.

Kristian may want to chime in here since he started it but afaict the main
reasons for using fixed-point are simplified (and somewhat more predictable)
mathematical operations, reduced storage and faster processing in general.

Cheers,
   Peter


More information about the wayland-devel mailing list