[PATCH v2 wayland-protocols] Add pad support to the tablet protocol

Jason Gerecke killertofu at gmail.com
Fri Apr 22 00:46:24 UTC 2016


On Mon, Apr 18, 2016 at 10:00 PM, Peter Hutterer
<peter.hutterer at who-t.net> wrote:
> From: Carlos Garnacho <carlosg at gnome.org>
>
> The pad's interface is similar to the tool interface, a client is notified of
> the pad after the tablet_added event.
>
> The pad has three functionalities: buttons, rings and strips.
> Buttons are fairly straightforward, rings and strips are separate interfaces
> with a pointer-axis-like source/value/frame events.
> The two interfaces are effectively identical but for the actual value they
> send (degrees vs normalized position).
>
> Specific to the pad device is the set_feedback request which enables a client
> to set a user-defined string to display for an OSD on the current mappings.
> This request is available for buttons, rings and strips.
>
> Finally, the pad supports "modes", effectively sets of button/ring/strip
> configurations.
>
> Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
> Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> ---
> Changes to v1:
> - typos fixed
>
>  unstable/tablet/tablet-unstable-v1.xml | 423 ++++++++++++++++++++++++++++++++-
>  1 file changed, 421 insertions(+), 2 deletions(-)
>
> diff --git a/unstable/tablet/tablet-unstable-v1.xml b/unstable/tablet/tablet-unstable-v1.xml
> index 907126c..36b9ae8 100644
> --- a/unstable/tablet/tablet-unstable-v1.xml
> +++ b/unstable/tablet/tablet-unstable-v1.xml
> @@ -115,7 +115,7 @@
>      interface version number is reset.
>    </description>
>
> -  <interface name="zwp_tablet_manager_v1" version="1">
> +  <interface name="zwp_tablet_manager_v1" version="2">
>      <description summary="controller object for graphic tablet devices">
>        An object that provides access to the graphics tablets available on this
>        system. All tablets are associated with a seat, to get access to the
> @@ -139,7 +139,7 @@
>      </request>
>    </interface>
>
> -  <interface name="zwp_tablet_seat_v1" version="1">
> +  <interface name="zwp_tablet_seat_v1" version="2">
>      <description summary="controller object for graphic tablet devices of a seat">
>        An object that provides access to the graphics tablets available on this
>        seat. After binding to this interface, the compositor sends a set of
> @@ -172,6 +172,23 @@
>        </description>
>        <arg name="id" type="new_id" interface="zwp_tablet_tool_v1" summary="the newly added tablet tool"/>
>      </event>
> +
> +    <!-- version 2 additions -->
> +
> +    <event name="pad_added" since="2">
> +      <description summary="new pad notification">
> +       This event is sent whenever a new pad is known to the system. Typically,
> +       pads are physically attached to tablets and a pad_added event is
> +       sent immediately after the wp_tablet_seat.tablet_added.
> +       However, some standalone pad devices logically attach to tablets at
> +       runtime, the client must wait for wp_tablet_pad.enter to know the
> +       tablet a pad is attached to.
> +

If a compositor wanted to support "bare" pad devices, I'm assuming
they'd have to fake one or more wp_tablet objects for that use,
correct?

> +       This event only provides the object id of the pad, any further features
> +       (buttons, strips, rings) is sent through the wp_tablet_pad interface.
> +      </description>
> +      <arg name="id" type="new_id" interface="zwp_tablet_pad_v1" summary="the newly added pad"/>
> +    </event>
>    </interface>
>
>    <interface name="zwp_tablet_tool_v1" version="1">
> @@ -638,4 +655,406 @@
>      </event>
>    </interface>
>
> +  <interface name="zwp_tablet_pad_ring_v1" version="2">
> +    <description summary="pad ring">
> +      A circular interaction area.
> +
> +      Events on a ring are logically grouped by the wl_tablet_pad_ring.frame
> +      event.
> +    </description>
> +
> +    <request name="set_feedback" since="2">
> +      <description summary="set compositor feedback">
> +       Requests the compositor to use the provided feedback UTF-8 encoded
> +       string associated with this ring.
> +
> +       Clients are encouraged to provide context-aware descriptions for
> +       the actions associated with the ring, compositors may use this
> +       information to offer visual feedback about the button layout
> +       (eg. on-screen displays).
> +
> +       The string offered is considered user visible; general
> +       internationalization rules apply.
> +
> +       This request should be issued immediately after a
> +       wp_tablet_pad.enter, or whenever the ring is mapped to a different
> +       action.
> +      </description>
> +      <arg name="description" type="string" summary="ring description"/>
> +    </request>
> +
> +    <request name="destroy" type="destructor" since="2">
> +      <description summary="destroy the ring object">
> +       This destroys the client's resource for this ring object.
> +      </description>
> +    </request>
> +
> +    <enum name="source">
> +      <description summary="ring axis source">
> +       Describes the source types for ring events. This indicates to the
> +       client how a ring event was physically generated; a client may
> +       adjust the user interface accordingly. For example, events
> +       from a "finger" source may trigger kinetic scrolling.
> +      </description>
> +      <entry name="finger" value="1" summary="finger"/>
> +    </enum>
> +
> +    <event name="source" since="2">
> +      <description summary="ring event source">
> +       Source information for ring events.
> +
> +       This event does not occur on its own. It is sent before a
> +       wp_tablet_pad_ring.frame event and carries the source information
> +       for all events within that frame.
> +
> +       The source specifies how this event was generated. If the source is
> +       wp_tablet_pad_ring.source.finger, a wp_tablet_pad_ring.stop event
> +       will be sent when the user lifts the finger off the device.
> +
> +       This event is optional. If the source is unknown for an interaction,
> +       no event is sent.
> +      </description>
> +      <arg name="source" type="uint" summary="the event source"/>
> +    </event>
> +
> +    <event name="angle" since="2">
> +      <description summary="angle changed">
> +       Sent whenever the angle on a ring changes.
> +
> +       The angle is provided in 0.01 of a degree clockwise from the logical
> +       north of the ring in the pad's current rotation.
> +      </description>
> +      <arg name="angle" type="uint" summary="The current angle"/>

I assume this will be updated to use the "fixed" type (along with pen
tilt and rotation) in a subsequent patch?

> +    </event>
> +
> +    <event name="stop" since="2">
> +      <description summary="interaction stopped">
> +       Stop notification for ring events.
> +
> +       For some wp_tablet_pad_ring.source types, a wp_tablet_pad_ring.stop
> +       event is sent to notify a client that the interaction with the ring
> +       has terminated.
> +       This enables the client to implement kinetic scrolling.
> +       See the wp_tablet_pad_ring.source documentation for information on
> +       when this event may be generated.
> +
> +       Any wp_tablet_pad_ring.angle events with the same source after this
> +       event should be considered as the start of a new interaction.
> +      </description>
> +      <arg name="source" type="uint" enum="source" summary="the event source"/>
> +    </event>
> +
> +    <event name="frame" since="2">
> +      <description summary="end of a ring event sequence">
> +       Indicates the end of a set of events that logically belong together.
> +       A client is expected to accumulate the data in all events within the
> +       frame before proceeding.
> +
> +       All wp_tablet_pad_ring events before a wp_tablet_pad_ring.frame event belong
> +       logically together. For example, on termination of a finger interaction
> +       on a ring the compositor will send wp_tablet_pad_ring.source event,
> +       a wp_tablet_pad_ring.stop event and a wp_tablet_pad_ring.frame
> +       event.
> +
> +       A wp_tablet_pad_ring.frame event is sent for every logical event
> +       group, even if the group only contains a single wp_tablet_pad_ring
> +       event.  Specifically, a client may get a sequence: angle, frame,
> +       angle, frame, etc.
> +      </description>

This is a little confusing. At first I read this to mean that the
frames bracket the entire ring interaction, but the the final
paragraph instead makes it sound like frames act the same as they do
for a stylus (i.e., basically acting the same as the kernel's
SYN_REPORT event). I imagine the latter interpretation is intended,
but a little rewording of the first paragraph (esp. "set of events
that logically belong together") might be a good idea.

> +      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
> +    </event>
> +  </interface>
> +
> +  <interface name="zwp_tablet_pad_strip_v1" version="2">
> +    <description summary="pad strip">
> +      A linear interaction area.
> +
> +      Events on a strip are logically grouped by the wl_tablet_pad_strip.frame
> +      event.
> +    </description>
> +
> +    <request name="set_feedback" since="2">
> +      <description summary="set compositor feedback">
> +       Requests the compositor to use the provided feedback UTF-8 encoded
> +       string associated with this strip.
> +
> +       Clients are encouraged to provide context-aware descriptions for
> +       the actions associated with the strip, compositors may use this
> +       information to offer visual feedback about the button layout
> +       (eg. on-screen displays).
> +
> +       The string offered is considered user visible; general
> +       internationalization rules apply.
> +
> +       This request should be issued immediately after a
> +       wp_tablet_pad.enter, or whenever the strip is mapped to a different
> +       action.
> +      </description>
> +      <arg name="description" type="string" summary="strip description"/>
> +    </request>
> +
> +    <request name="destroy" type="destructor" since="2">
> +      <description summary="destroy the strip object">
> +       This destroys the client's resource for this strip object.
> +      </description>
> +    </request>
> +
> +    <enum name="source">
> +      <description summary="strip axis source">
> +       Describes the source types for strip events. This indicates to the
> +       client how a strip event was physically generated; a client may
> +       adjust the user interface accordingly. For example, events
> +       from a "finger" source may trigger kinetic scrolling.
> +      </description>
> +      <entry name="finger" value="1" summary="finger"/>
> +    </enum>
> +
> +    <event name="source" since="2">
> +      <description summary="strip event source">
> +       Source information for strip events.
> +
> +       This event does not occur on its own. It is sent before a
> +       wp_tablet_pad_strip.frame event and carries the source information
> +       for all events within that frame.
> +
> +       The source specifies how this event was generated. If the source is
> +       wp_tablet_pad_strip.source.finger, a wp_tablet_pad_strip.stop event
> +       will be sent when the user lifts their finger off the device.
> +
> +       This event is optional. If the source is unknown for an interaction,
> +       no event is sent.
> +      </description>
> +      <arg name="source" type="uint" summary="the event source"/>
> +    </event>
> +
> +    <event name="position" since="2">
> +      <description summary="position changed">
> +       Sent whenever the position on a strip changes.
> +
> +       The position is normalized to a range of [0, 0xFFFF], the 0-value

Elsewhere in the protocol "[0, 65535]" is used. I think it would be
good to use one or the other for style reasons.

> +       represents the top-most and/or left-most position of the strip in
> +       the pad's current rotation.
> +      </description>
> +      <arg name="position" type="uint" summary="The current position"/>
> +    </event>
> +
> +    <event name="stop" since="2">
> +      <description summary="interaction stopped">
> +       Stop notification for strip events.
> +
> +       For some wp_tablet_pad_strip.source types, a wp_tablet_pad_strip.stop
> +       event is sent to notify a client that the interaction with the strip
> +       has terminated.
> +       This enables the client to implement kinetic scrolling.
> +       See the wp_tablet_pad_strip.source documentation for information on
> +       when this event may be generated.
> +
> +       Any wp_tablet_pad_strip.position events with the same source after this
> +       event should be considered as the start of a new interaction.
> +      </description>
> +      <arg name="source" type="uint" enum="source" summary="the event source"/>
> +    </event>
> +
> +    <event name="frame" since="2">
> +      <description summary="end of a strip event sequence">
> +       Indicates the end of a set of events that logically belong together.
> +       A client is expected to accumulate the data in all events within the
> +       frame before proceeding.
> +
> +       All wp_tablet_pad_strip events before a wp_tablet_pad_strip.frame event belong
> +       logically together. For example, on termination of a finger interaction
> +       on a strip the compositor will send wp_tablet_pad_strip.source event,
> +       a wp_tablet_pad_strip.stop event and a wp_tablet_pad_strip.frame
> +       event.
> +
> +       A wp_tablet_pad_strip.frame event is sent for every logical event
> +       group, even if the group only contains a single wp_tablet_pad_strip
> +       event.  Specifically, a client may get a sequence: position, frame,
> +       position, frame, etc.
> +      </description>

Same comments as for the ring.

> +      <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
> +    </event>
> +  </interface>
> +
> +  <interface name="zwp_tablet_pad_v1" version="2">
> +    <description summary="a set of buttons, rings and strips">
> +      A pad device is a set of buttons, rings and strips
> +      usually physically present on the tablet device itself. Some
> +      exceptions exist where the pad device is physically detached, e.g. the
> +      Wacom ExpressKey Remote.
> +
> +      Pad devices have no axes that control the cursor and are generally
> +      auxiliary devices to the tool devices used on the tablet surface.
> +
> +      A pad device has a number of static characteristics, e.g. the number
> +      of rings. These capabilities are sent in an event sequence after the
> +      wp_tablet_seat.pad_added event before any actual events from this pad.
> +      This initial event sequence is terminated by a wp_tablet_pad.done
> +      event.
> +    </description>
> +
> +    <request name="set_feedback" since="2">
> +      <description summary="set compositor feedback">
> +       Requests the compositor to use the provided feedback UTF-8 encoded
> +       string associated with this button.
> +
> +       Clients are encouraged to provide context-aware descriptions for
> +       the actions associated with each button, compositors may use this
> +       information to offer visual feedback on the button layout
> +       (e.g. on-screen displays).
> +
> +       The feedback string is considered user visible; general
> +       internationalization rules apply.
> +
> +       This request should be issued immediately after a
> +       wp_tablet_pad.enter event or whenever a button is mapped to a
> +       different action.
> +      </description>
> +      <arg name="button" type="uint" summary="button code"/>
> +      <arg name="description" type="string" summary="button description"/>
> +    </request>
> +
> +    <request name="destroy" type="destructor" since="2">
> +      <description summary="destroy the pad object">
> +       Destroy the wp_tablet_pad object. Objects created from this object
> +       are unaffected and should be destroyed separately.
> +      </description>
> +    </request>
> +
> +    <event name="ring" since="2">
> +      <description summary="ring announced">
> +       Sent on wp_tablet_pad initialization to announce available rings.
> +       One event is sent for each ring available on this pad.
> +
> +       This event is sent in the initial burst of events before the
> +       wp_tablet_tool.done event.
> +      </description>
> +      <arg name="ring" type="new_id" interface="zwp_tablet_seat_ring_v1"/>
> +    </event>
> +
> +    <event name="strip" since="2">
> +      <description summary="strip announced">
> +       Sent on wp_tablet_pad initialization to announce available strips.
> +       One event is sent for each strip available on this pad.
> +
> +       This event is sent in the initial burst of events before the
> +       wp_tablet_tool.done event.
> +      </description>
> +      <arg name="strip" type="new_id" interface="zwp_tablet_seat_strip_v1"/>
> +    </event>
> +
> +    <event name="buttons" since="2">
> +      <description summary="buttons announced">
> +       Sent on wp_tablet_pad initialization to announce the available buttons.
> +       Compositors may consume some buttons for global actions, those
> +       will not be announced in this event (e.g. the button to switch
> +       between modes, if any).
> +
> +       This event is sent in the initial burst of events before the
> +       wp_tablet_tool.done event.
> +      </description>

Do we need to have the ability to change the set of announced buttons
on the fly? Its possible the compositor would want to change which
buttons it reserves by user request. For example, right now it is
possible to configure GNOME to have a button pop up an OSD of button
assignments (which is a global compositor action). The choice of the
button is up to the user, and if the user later changes their mind
then applications will have to be informed that the set of available
buttons has changed. I might be thinking about this case
wrong-headedly and that there's no need for the list of available
buttons to change, but I don't think so...

Its also not entirely clear to me what the array that would be
received is supposed to contain or how clients are supposed to
interpret it.

> +      <arg name="buttons" type="array" summary="the available buttons"/>
> +    </event>
> +
> +    <event name="modes" since="2">
> +      <description summary="buttons announced">
> +       Sent on wp_tablet_pad initialization to announce that the pad
> +       may switch between modes. A client may use a mode to store a
> +       specific configuration for buttons, rings and strips and use the
> +       wl_tablet_pad.mode event to toggle between these configurations.
> +
> +       Switching modes is compositor-dependent. See the wp_tablet_pad.mode
> +       event for more details.
> +
> +       This event is sent in the initial burst of events before the
> +       wp_tablet_tool.done event.
> +      </description>
> +      <arg name="buttons" type="array" summary="the available buttons"/>
> +    </event>
> +
> +    <event name="done" since="2">
> +      <description summary="pad description event sequence complete">
> +       This event signals the end of the initial burst of descriptive
> +       events. A client may consider the static description of the pad to
> +       be complete and finalize initialization of the pad.
> +      </description>
> +    </event>
> +
> +    <enum name="button_state" since="2">
> +      <description summary="physical button state">
> +       Describes the physical state of a button which provoked the button
> +       event.
> +      </description>
> +      <entry name="released" value="0" summary="The button is not pressed"/>
> +      <entry name="pressed" value="1" summary="The button is pressed"/>
> +    </enum>
> +
> +    <event name="button" since="2">
> +      <description summary="physical button state">
> +       Sent whenever the physical state of a button changes.
> +      </description>
> +      <arg name="time" type="uint" summary="The time of the event with millisecond granularity"/>
> +      <arg name="button" type="uint" summary="button pressed"/>
> +      <arg name="state" type="uint" enum="button_state"/>
> +    </event>
> +
> +    <event name="mode" since="2">
> +      <description summary="mode switch event">
> +       Notification that the mode was switched.
> +
> +       A mode applies to all buttons, rings and strips but a client is not
> +       required to assign different actions for each mode. For example, a
> +       client may have mode-specific button mappings but map the ring to
> +       vertical scrolling in all modes.
> +
> +       Switching modes is compositor-dependent. The compositor may provide
> +       visual cues to the client about the mode, e.g. by toggling LEDs on
> +       the tablet device. Mode-switching may be software-controlled or by
> +       assigning one or more physical buttons. For example, on a Wacom
> +       Intuos Pro, the button inside the ring may be assigned to switch
> +       between modes.
> +
> +       If a button action in the new mode differs from the action in the
> +       previous mode, the client should immediately issue a
> +       wp_tablet_pad.set_feedback request for each changed button.
> +
> +       If a ring or button action in the new mode differs from the action
> +       in the previous mode, the client should immediately issue a
> +       wp_tablet_ring.set_feedback or wp_tablet_strip.set_feedback request
> +       for each changed ring or strip.
> +      </description>
> +      <arg name="time" type="uint" summary="The time of the event with millisecond granularity"/>
> +      <arg name="serial" type="uint"/>
> +      <arg name="mode" type="uint"/>
> +    </event>
> +
> +    <event name="enter" since="2">
> +      <description summary="enter event">
> +       Notification that this pad is focused on the specified surface.
> +      </description>
> +      <arg name="serial" type="uint"/>
> +      <arg name="tablet" type="object" interface="zwp_tablet_v1" summary="The tablet the pad is attached to"/>
> +      <arg name="surface" type="object" interface="wl_surface"/>
> +    </event>
> +
> +    <event name="leave" since="2">
> +      <description summary="enter event">
> +       Notification that this pad is no longer focused on the specified
> +       surface.
> +      </description>
> +      <arg name="serial" type="uint"/>
> +      <arg name="surface" type="object" interface="wl_surface"/>
> +    </event>
> +
> +    <event name="removed" since="2">
> +      <description summary="pad removed event">
> +       Sent when the pad has been removed from the system. When a tablet
> +       is removed, its pad(s) will be removed too.
> +
> +       When this event is received, the client must wp_tablet_pad.destroy
> +       the object, and wp_tablet_pad_strip.destroy/wp_tablet_pad_ring.destroy
> +        on all strips/rings offered by this pad.
> +      </description>
> +    </event>
> +  </interface>
>  </protocol>
> --
> 2.5.5
>


More information about the wayland-devel mailing list