wl_tablet specification draft

Peter Hutterer peter.hutterer at who-t.net
Wed Jun 25 18:05:10 PDT 2014


On Wed, Jun 25, 2014 at 03:19:02PM +0300, Pekka Paalanen wrote:
> On Tue, 24 Jun 2014 21:56:09 -0400
> Chandler Paul <thatslyude at gmail.com> wrote:
> 
> > Hello! As you all know I've been working on adding drawing tablet
> > support to the Wayland protocol. Now that we've added support for
> > tablets to libinput, the next step is writing the actual protocol that
> > will be implemented by the compositor. Following this blurb is the
> > current draft of the tablet protocol we have. Feel free to critique it.
> > 
> > Cheers,
> > 	Lyude
> > 
> > ----------------------------------------------------------------------------
> > 
> >                            wl_tablet specifications
> > 
> > General notes:
> > - Many of the axis values in this are normalized to either 0-65535 or
> >   (-65535)-65535. I would leave the axis values as-is since libinput reports
> >   them as doubles, but since we only have 8 bits of precision we'd lose way
> >   too many values. 65535 seemed like the best choice since it's the maximum
> >   length of a signed short, it's a whole number, it's way higher then the
> >   range of any of the axes (with the exception of X and Y, but these aren't
> >   normalized anyway) and we can do just about any basic arithmatic with it
> >   without having to worry about overflowing. plus, all we have to do is
> >   multiply the value by 65535 after we get it from libinput.
> > 
> > Definitions:
> > - WL_TABLET_AXIS_MAX = 65535
> > - WL_TABLET_AXIS_MIN = (-65535)
> > 
> > Enumerators:
> > - wl_tablet_axis:
> >         - WL_TABLET_AXIS_X
> >         - WL_TABLET_AXIS_Y
> > 	  Represents the X and Y axes respectively. Only used in bitfields to
> > 	  indicate whether or not they've changed since the last event.
> > 
> >         - WL_TABLET_AXIS_DISTANCE
> >           Represents the distance axis on a tablet. Normalized from 0 to
> >           WL_TABLET_AXIS_MAX. For tablets that do not support reporting the
> >           distance, this will always be 0.
> > 
> >         - WL_TABLET_AXIS_PRESSURE
> >           Represents the pressure axis on a tablet. Normalized from 0 to
> >           WL_TABLET_AXIS_MAX. For tablets that do not support reporting the
> >           pressure, this will always be WL_TABLET_AXIS_MAX.
> > 
> >         - WL_TABLET_AXIS_TILT_VERTICAL
> >         - WL_TABLET_AXIS_TILT_HORIZONTAL
> >           Each represents the vertical and horizontal tilt axes respectfully.
> >           Normalized from WL_TABLET_AXIS_MIN to WL_TABLET_AXIS_MAX. For
> >           tablets that do not support this, this value will always be 0.
> > 
> >         - WL_TABLET_AXIS_CNT
> >           Represents the number of axes
> > - wl_tablet_tool_type:
> >         - pen
> >         - eraser
> >         - brush
> >         - pencil
> >         - airbrush
> >         - finger
> >         - mouse
> >         - lens
> > - wl_tablet_button_state
> >         - pressed
> >         - released
> > 
> > Events:
> > - proximity_in
> >   Sent when the tool comes into proximity above the client surface, either by
> >   the tool coming into proximity or a tool being in-proximity and moving to
> >   the client surface. If a tablet tool makes contact with the tablet at the
> >   same time that the tool comes into proximity, the proximity event comes
> >   first and the down event comes afterwards.
> >   Arguments:
> >         - Name: id
> >           Type: uint
> >           the id of the tablet sending this event.
> > 
> >         - Name: type
> >           Type: uint
> >           The type of tool that came into proximity, e.g. pen, airbrush, etc.
> > 
> >         - Name: serial
> >           Type: uint
> > 	  The serial number of the tool that came into proximity. On tablets
> > 	  where this isn't provided, this value will always be 0.
> > 
> >         - Name: x
> >           Type: fixed
> >           Surface relative x coordinate
> > 
> >         - Name: y
> >           Type: fixed
> >           Surface relative y coordinate
> > 
> >         - Name: surface
> >           Type: object
> >           Interface: wl_surface
> >           The current surface the tablet tool is over
> > 
> >         - Name: time
> >           Type: uint
> >           The time of the event with millisecond granularity.
> > 
> >         - Name: axes
> >           Type: array
> > 	  The current values of each of the tablet axes starting at
> > 	  WL_TABLET_AXIS_DISTANCE. The length of the array is equal to the
> > 	  number of axes that are reported. Any axes >= WL_TABLET_AXIS_CNT
> > 	  must be ignored. The size of the array remains fixed for the
> > 	  lifetime of the tablet.
> > 
> > - proximity_out
> >   Send whenever the tool leaves the proximity of the tablet or moves out of
> >   the client surface. When the tool goes out of proximity, a set of button
> >   release events are sent before the initial proximity_out event for each
> >   button that was held down before the tablet tool left proximity. In
> >   addition, axis updates always come before a proximity-out event.
> >   Arguments:
> >         - Name: id
> >           Type: uint
> >           The id of the tablet sending this event.
> > 
> >         - Name: time
> >           Type: uint
> >           The time of the event with millisecond granularity.
> > 
> > - axis
> >   Sent whenever an axis on the tool changes. This can include movement on the
> >   X and Y axis.
> >   Arguments:
> >         - Name: id
> >           Type: uint
> >           The id of the tablet sending this event.
> > 
> >         - Name: x
> >           Type: fixed
> >           Surface relative x coordinate
> > 
> >         - Name: y
> >           Type: fixed
> >           Surface relative y coordinate
> > 
> >         - Name: surface
> >           Type: object
> >           Interface: wl_surface
> >           The current surface the tablet tool is over
> 
> How about using enter/leave events telling the client which wl_surface
> the input device is targeting? That way you don't have to repeat the
> wl_surface argument in every event.

good point, thanks!
 
> >         - Name: time
> >           Type: uint
> >           The time of the event with millisecond granularity.
> > 
> >         - Name: changed_axes
> >           Type: bitfield
> >           Indicates which axes have changed.
> > 
> >         - Name: axes
> >           Type: array
> > 	  The current values of each of the tablet axes starting at
> > 	  WL_TABLET_AXIS_DISTANCE. The length of the array is equal to the
> > 	  number of axes that are reported. Any axes >= WL_TABLET_AXIS_CNT
> > 	  must be ignored.
> > 
> > - button
> >   Sent whenever a button on the tool is pressed or released.
> >   Arguments:
> >         - Name: id
> >           Type: uint
> >           The id of the tablet sending this event.
> > 
> >         - Name: button
> >           Type: uint
> >           The button whose state has changed
> > 
> >         - Name: state
> >           Type: uint
> >           Whether the button was pressed or released
> > 
> >         - Name: time
> >           Type: uint
> >           The time of the event with millisecond granularity.
> > 
> > - added
> >   Sent when a tablet device is added.
> >   Arguments:
> >         - Name: id
> >           Type: uint
> >           The id of the tablet sending this event.
> > 
> > - removed
> >   Sent when the tablet device has been removed.
> >   Arguments:
> >         - Name: id
> >           Type: uint
> >           The id of the tablet sending this event.
> > 
> > How tablet IDs are generated:
> > Tablet IDs are aggressively recycled, e.g. we always try to get the lowest
> > possible tablet ID. This means that the client can always assume that the ID
> > number for a new tablet will never be greater then the number of tablets
> > currently connected.
> 
> Hi,
> 
> using tablet IDs this way seems like this is a raw wire protocol, and
> not object oriented like Wayland usually is.
> 
> Could this be wrapped into an object like the following?
> 
> Define interface "wl_tablet" which represents one device (I assume
> aggregating makes no sense, just like with gamepads). Then you can drop
> the "id" argument from all events and requests, and just use the
> protocol object.

It's possible, look at this RFC from last september.
http://lists.freedesktop.org/archives/wayland-devel/2013-September/011173.html

The gist of that was that the wl_seat::get_tablet_manager request that
returned a tablet manager object. that object was then the one that sent
wl_tablet_manager::device_added events with the new tablet object. And that
object had the wl_tablet interface as above (without the IDs).

Lyude and I talked about this and couldn't decide which approach was the
correct-er one for wayland :)
 
> I'm not sure how you want to advertise and create the wl_tablet objects.
> How do tablet devices relate to wl_seat protocol objects?

tablets control the cursor, so we definitely need to couple them
with the seats somehow.
 
> While the protocol is experimental, you could have your own (temporary)
> global interface for advertising tablets, so that you don't need to
> modify the Wayland core protocol (wl_seat). Or you could advertise each
> tablet device as a separate global wl_tablet that a client can bind to.
> The proper approach finally depends on the relation to wl_seat once you
> are ready to set the protocol in stone.

good point, thanks.

> Would clients need some information to differentiate between multiple
> tablets in a human-friendly way? 

yes, we'll at least need to add PID/VID. From then on the clients can look
up all they need in libwacom. I don't think we need much more than that.

> Or should all clients always subscribe to all tablets?

Yes, I think that's the sensible option. in 99% of the cases there is only
one tablet anyway, sometimes there are 2 (laptops have wacom tablets
built-in or a Cintiq+Intuos combo), I haven't seen a real-world setup with 3
tablet yet.

Cheers,
   Peter


More information about the wayland-devel mailing list