[PATCH v3 wayland-protocols] Add the tablet protocol

Jason Gerecke killertofu at gmail.com
Tue Feb 2 02:38:36 UTC 2016

On Mon, Feb 1, 2016 at 4:55 PM, Peter Hutterer <peter.hutterer at who-t.net> wrote:
> On Mon, Feb 01, 2016 at 04:12:24PM -0800, Jason Gerecke wrote:
>> On Sun, Jan 31, 2016 at 2:27 PM, Peter Hutterer
>> <peter.hutterer at who-t.net> wrote:
>> > On Fri, Jan 29, 2016 at 11:40:44AM -0800, Jason Gerecke wrote:
>> >> On Thu, Jan 28, 2016 at 8:32 PM, Peter Hutterer
>> >> <peter.hutterer at who-t.net> wrote:
>> >> > Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>> >> > ---
>> >> > Changes to v2:
>> >> > - renamed hwserial to hardware_serial
>> >> > - renamed to hwid event to a hardware_id_wacom. no-one else uses this ID
>> >> >   type, so having a generic event with a wacom-specific type + enum is
>> >> >   optimistic. The next company may use a string instead, so it'll be
>> >> >   non-generic anyway. Might as well rename it to something specific now.
>> >> > - added slider, rotation and wheel axes
>> >> > - couple of documentation fixes
>> >
>> > [...]
>> >
>> >> > +
>> >> > +    <event name="distance">
>> >> > +      <description summary="distance change event">
>> >> > +       Sent whenever the distance axis on a tool changes. The value of this
>> >> > +       event is normalized to a value between 0 and 65535.
>> >> > +
>> >> > +       Note that distance may be nonzero even when a tool is not in logical
>> >> > +       contact. See the down and up events for more details.
>> >> > +      </description>
>> >> > +      <arg name="distance" type="uint" summary="The current distance value"/>
>> >> > +    </event>
>> >> > +
>> >> > +    <event name="tilt">
>> >> > +      <description summary="tilt change event">
>> >> > +       Sent whenever one or both of the tilt axes on a tool change. Each tilt
>> >> > +       value is normalized between -65535 and 65535.
>> >> > +      </description>
>> >> > +      <arg name="tilt_x" type="int" summary="The current value of the X tilt axis"/>
>> >> > +      <arg name="tilt_y" type="int" summary="The current value of the Y tilt axis"/>
>> >> > +    </event>
>> >> > +
>> >> > +    <event name="rotation">
>> >> > +      <description summary="z-rotation change event">
>> >> > +       Sent whenever the z-rotation axis on the tool changes. The
>> >> > +       rotation value is in 0.01 of a degree clockwise from the tool's
>> >> > +       logical neutral position.
>> >> > +      </description>
>> >>
>> >> From the protocol description: "Any extra axis is normalized, i.e. the
>> >> client knows the range as specified in the protocol (e.g. [0, 65535]),
>> >> the granularity however is unknown." This was chosen because we don't
>> >> always have the necessary information to translate a kernel value for
>> >> a given device's axis into a physical measurement, but we can always
>> >> report a normalized value that that gives clients a sense of its
>> >> relative magnitude.
>> >
>> > yeah, we did this for pressure and distance because we know we can't convert
>> > them into anything useful. rotation I thought was different and libinput
>> > advertises z-rotation in degrees as well. That means two things:
>> > * either we commit to degrees and fix it up per-device as needed in libinput
>> > * admit that we really can't even get degrees out of rotation and change
>> >   libinput's API to normalize into a [-1, 1] range. If so, we need to do
>> >   this *now*, I'm about to release it as a stable API.
>> >
>> > I am ok with the second option so it's your call really. You have better
>> > access to the hw. fwiw, adding degrees later if/when the HW gets more
>> > precise is easy enough.
>> >
>> I don't think precision (more correctly, accuracy) is really the issue
>> at hand. Its more about the difference between qualitative axes like
>> pressure and distance (where there are basically no information about
>> the physical values that even minimum and maximum correspond to) and
>> quantitative axes like position, tilt, and rotation (which have
>> varying degrees of accuracy but are at least specified to have a
>> conversion to physical units). Devices based on different technologies
>> may have different qualitative and quantitative axes, so reporting
>> normalized data as a least common denominator format can be useful.
>> I would have expected rotation and tilt to both be reported in the
>> same format -- either in degrees or normalized. I think both formats
>> are fine (since its hard for me to imagine either as a
>> merely-qualitative axis), though there are advantages to using the
>> normalized format like everything else.
> as for tilt: the reason it's reported in a normalized form is that I seem to
> vaguely remember that the accuracy isn't good enough, especially at the edge
> of the ranges. so tilt on the client side is closer to "you've tilted 50%
> out of a 100% range" rather than a "you've tilted 10 degrees"
> There's also the implied indication of a maximum tilt range, the value 1 is
> always 100% tilt, regardless what it's actual angle is.
> for rotation, the maximum range is naturally 360 degrees. Even if the pen
> may not be able to actually detect that range, it feels very odd to have a
> 0-1 rotation range.

I suppose it depends on what you define as "good enough". I feel its
good enough to be useful to applications, though I wouldn't use it as
a stand-in for my protractor. Of course, that statement only applies
to the tablets I have in front of me. Who knows if another device
(e.g. from another manufacturer, or based on some other technology, or
some future bit of hardware) would be better or worse...

Ultimately, the tilt information is almost universally used by
applications to set brush orientation. To do that, you have to use
some trig to transform the X and Y tilt values into something like
Alt-Az form. Tilt on a scale of 0-1 is fine for calculating the
azimuth, but you can't calculate the altitude angle without knowing
what 100% physically corresponds to. You can guess (e.g. assume it
corresponds to the reasonable physical limit of +-90 degrees), get a
horribly wrong answer (since the hardware limit is actually +-64
degrees), and then either ignore the discrepancy or fudge other bits
of the brush engine to not do nonsensical things. Actually, to be
fair, that's exactly how GIMP does things right now :P

> so in line with what you mention below: should we switch tilt to degrees
> then, and (in the near future) worry about providing the max ranges for
> tilt as a separate item?
> Cheers,
>    Peter

There's no need (well, outside of the odd application to debug pen
data I suppose) to provide max ranges for tilt if the API specifies
that it spits out data in degrees. You can just feed the output
straight into DEG2RAD() and then call trig functions until the cows
come home. On the other hand, if the API specifies that it spits out
normalized data, then its important to provide a way for applications
to get at the range so that they can correctly un-normalize the data
before doing any trig.

It's probably fine to either change the API to report degrees *or*
sometime in the future add a way to get at its range data. As I
mentioned in my last email, having the API specify physical units is
pretty common, so its not like you'd be doing something weird. On the
other hand, normalizing the data does let you use the same API for
both quantitative and qualitative axes, and to have any particular
axis behave as either depending on the device. Normalized "feels" a
little weird for tilt and rotation, but not excessively so.

Now instead of four in the eights place /
you’ve got three, ‘Cause you added one  /
(That is to say, eight) to the two,     /
But you can’t take seven from three,    /
So you look at the sixty-fours....

>> >> We do need to provide a way for clients to translate the normalized
>> >> values into physical measurements if possible though. I would suggest
>> >> adding the following event to the tool definition. Several could be
>> >> sent as part of the initial pre-"done" burst.
>> >>
>> >>  <event name="physical_range">
>> >>    <description summary="tool physical range notification">
>> >>      This event provides information about the physical range of one
>> >>      of the axes of the tool. This information can be used to translateIts a little difficult to imagine a merely-qualitative tilt axis
>> >>      the normalized values (0 to 65535, or -65535 to +65535) axis values
>> >>      sent by events into physical quantities.
>> >>
>> >>      Minimum and maximum values have units of gram-force for pressure,
>> >>      millimeters for distance, and degrees of arc for tilt and rotation.
>> >>      This event will not be sent for axes whose physical minimum and
>> >>      maximum is not known.
>> >
>> > from what I gathered: for distance the sensors aren't precise enough which
>> > is why we switched to normalised values. pressure I'm not sure, but I
>> > vaguely remember tilt is blurry and imprecise too.
>> >
>> > So I'm hesistant to add this event, it looks like we don't have hardware
>> > that would send this event. which means we don't have clients that use it.
>> > Which means we don't need it.
>> > Let's wait until we have a use-case and a clear conversion before adding
>> > extra events.
>> >
>> This would be used for tilt and rotation axes. The only reason I
>> mentioned distance and pressure were to provide you with a better idea
>> of how it might be used if we had the had the necessary information
>> for those axes (... I don't want to characterize the pressure curves
>> of the various pens, but it /could/ be done; or a more linear force
>> sensor used in some future pen ...).
>> The use case would be supporting most every toolkit out there. It
>> seems like everything except GTK specifies that tilt information is
>> reported in some kind of physical unit. Qt needs to be able to
>> transform the normalized data into degrees. I believe EFL is the same.
>> Android (on the odd chance Google decides to replace their input layer
>> with libinput :P) uses radians. I suppose they could all hardcode a
>> transformation that assumes every device has the same physical tilt
>> range, but that's fragile, ugly, and just plain wrong.
>> Jason
>> ---
>> Now instead of four in the eights place /
>> you’ve got three, ‘Cause you added one  /
>> (That is to say, eight) to the two,     /
>> But you can’t take seven from three,    /
>> So you look at the sixty-fours....
>> > From a technical POV, I'd do this as separate events (pressure_range,
>> > distance_range, ...). Gives us better control over what we're sending out
>> > and more flexible in the corner cases.
>> >
>> > Cheers,
>> >    Peter
>> >
>> >>    </description>
>> >>    <arg name="capability" type="uint" enum="capability" summary="the
>> >> capability"/>
>> >>    <arg name="minimum" type="fixed" summary="physical value of axis minimum"/>
>> >>    <arg name="maximum" type="fixed" summary="physical value of axis maximum"/>
>> >>  </event>

More information about the wayland-devel mailing list