Merge branch 'joystick' into 'main'

gamepad-v1: new protocol

See merge request wayland/wayland-protocols!244
This commit is contained in:
Simon Zeni 2025-12-16 08:22:24 -05:00
commit ada700c700
3 changed files with 288 additions and 0 deletions

View file

@ -63,6 +63,7 @@ staging_protocols = {
'ext-workspace': ['v1'], 'ext-workspace': ['v1'],
'fifo': ['v1'], 'fifo': ['v1'],
'fractional-scale': ['v1'], 'fractional-scale': ['v1'],
'gamepad': ['v1'],
'linux-drm-syncobj': ['v1'], 'linux-drm-syncobj': ['v1'],
'pointer-warp': ['v1'], 'pointer-warp': ['v1'],
'security-context': ['v1'], 'security-context': ['v1'],

4
staging/gamepad/README Normal file
View file

@ -0,0 +1,4 @@
game controller protocol
Maintainers:
Simon Zeni <simon@bl4ckb0ne.ca>

View file

@ -0,0 +1,283 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="gamepad_v1">
<copyright>
Copyright © 2023-2024 Collabora, Ltd.
Copyright © 2024 Colin Marc
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="Wayland protocol for gamepad devices">
This descriptions provides a high-level overview of the interplay between
the interfaces defined in this protocol. For details, see the protocol
specification.
To start receiving gamepad input events, a client must first bind the
global interface wp_gamepad_manager, which will be used to request a
seat-specific object, using get_gamepad_seat.
A wp_gamepad_seat object is used by the compositor to notify the client of
connected controllers, via the gamepad_available event. The wp_gamepad
object contained in that event is then used to send actual input events.
Which surface currently holds the focus of the gamepad, and therefore
receives input events from that controller, is maintained by the
compositor and communicated to the client with the enter and leave events.
Clients should watch for the wp_gamepad.removed event, which indicates a
device was unplugged. If the same device is then replugged, it results in
a new wp_gamepad_seat.gamepad_available event and a new wp_gamepad object.
Gamepads can be identified across hotplug events by their unique ID, sent
in the wp_gamepad.device_info event.
Warning! The protocol described in this file is experimental and backward
incompatible changes may be made. Backward compatible changes may be added
together with the corresponding interface version bump. Backward
incompatible changes are done by bumping the version number in the protocol
and interface names and resetting the interface version. Once the protocol
is to be declared stable, the 'z' prefix and the version number in the
protocol and interface names are removed and the interface version number
is reset.
</description>
<interface name="wp_gamepad_manager_v1" version="1">
<description summary="manager object for gamepads">
An object that provides access to connected gamepads.
</description>
<request name="destroy" type="destructor">
<description summary="destroy this object">
Destroy the wp_gamepad_manager object.
The objects created from this object are unaffected and should be
destroyed separately.
</description>
</request>
<request name="get_gamepad_seat">
<description summary="get gamepads for a seat">
Get the wp_gamepad_seat object for a given seat. This object provides
access to all gamepads in this seat.
</description>
<arg name="gamepad_seat" type="new_id" interface="wp_gamepad_seat_v1"/>
<arg name="seat" type="object" interface="wl_seat" summary="The wl_seat object for which to receive controller input" />
</request>
</interface>
<interface name="wp_gamepad_seat_v1" version="1">
<description summary="manager object for gamepads attached to a seat">
An object providing access to the gamepads available on this seat. After
binding to this interface, the compositor sends available gamepad through
gamepad_available event.
</description>
<request name="destroy" type="destructor">
<description summary="destroy this object">
Destroy the wp_gamepad_seat object.
The objects created from this object are unaffected and should be
destroyed separately.
</description>
</request>
<event name="gamepad_available">
<description summary="controller input is available">
This event is sent whenever a gamepad becomes available on this
seat.
</description>
<arg name="id" type="new_id" interface="wp_gamepad_v1" summary="the newly available gamepad"/>
</event>
</interface>
<interface name="wp_gamepad_v1" version="1">
<description summary="gamepad input device">
This interface represents a physical gamepad currently connected to the
system.
Upon binding to the interface, the compositor will advertise the
properties of the gamepad through the device_info event.
Input events are grouped by the wp_gamepad_v1.frame events. All events
received before the frame event should be considered part of the same
hardware state change.
</description>
<request name="destroy" type="destructor">
<description summary="destroy this object">
Destroy the wp_gamepad object.
</description>
</request>
<enum name="theme">
<description summary="button theme">
Each vendor uses a different set of glyph on its controller's buttons.
</description>
<entry name="none" value="0" summary="default value"/>
<entry name="playstation" value="1" summary="Sony controllers"/>
<entry name="xbox" value="2" summary="Microsoft controllers"/>
<entry name="nintendo" value="3" summary="Nintendo controllers"/>
<!-- Valve and Microsoft have the same button position -->
<entry name="steam" value="2" summary="Valve controllers"/>
</enum>
<event name="device_info">
<description summary="name of this gamepad">
Information about the gamepad. The name and uniq values are UTF-8
strings, the uniq value should not be NULL.
</description>
<arg name="name" type="string" summary="name of the gamepad"/>
<arg name="uniq" type="string" summary="unique ID of the gamepad"/>
<arg name="vendor_id" type="uint" summary="vendor ID of the gamepad" />
<arg name="product_id" type="uint" summary="product ID of the gamepad" />
<arg name="theme" type="uint" enum="theme" summary="theme hint"/>
</event>
<event name="enter">
<description summary="enter focus event">
Notification that the gamepad is focused on a given surface.
</description>
<arg name="serial" type="uint" summary="serial number of the enter evenr"/>
<arg name="surface" type="object" interface="wl_surface" summary="surface gaining gamepad focus"/>
</event>
<event name="leave">
<description summary="leave focus event">
Notification that the gamepad is no longer focused on the given surface.
</description>
<arg name="serial" type="uint" summary="serial number of the leave event"/>
<arg name="surface" type="object" interface="wl_surface" summary="surface losing gamepad focus"/>
</event>
<enum name="button">
<description summary="button source">
Describes the source of a button event.
</description>
<entry name="home" value="1"/>
<entry name="start" value="2"/>
<entry name="select" value="3"/>
<entry name="misc" value="4"/>
<entry name="north" value="5"/>
<entry name="south" value="6"/>
<entry name="east" value="7"/>
<entry name="west" value="8"/>
<entry name="up" value="9"/>
<entry name="down" value="10"/>
<entry name="left" value="11"/>
<entry name="right" value="12"/>
<entry name="lthumb" value="13" summary="left thumbstick"/>
<entry name="rthumb" value="14" summary="right thumbstick"/>
<entry name="lshoulder" value="15" summary="left shoulder"/>
<entry name="rshoulder" value="16" summary="right shoulder"/>
<entry name="ltrigger" value="17" summary="left trigger"/>
<entry name="rtrigger" value="18" summary="right trigger"/>
<entry name="p1" value="19" summary="back paddle 1"/>
<entry name="p2" value="20" summary="back paddle 2"/>
<entry name="p3" value="21" summary="back paddle 3"/>
<entry name="p4" value="22" summary="back paddle 4"/>
</enum>
<enum name="button_state">
<description summary="button source state">
Describes the physical state of a button on the gamepad.
</description>
<entry name="released" value="0" summary="the input source is not pressed"/>
<entry name="pressed" value="1" summary="the input source is pressed"/>
</enum>
<event name="button">
<description summary="gamepad button event">
Describes the gamepad button source press and release notification.
The time arguments is a timestamp in microseconds granularity with an
unknown base of the moment of the state changes
</description>
<arg name="source" type="uint" enum="button" summary="source that produced the event"/>
<arg name="state" type="uint" enum="button_state" summary="physical state of the button"/>
<arg name="time_hi" type="uint" summary="high 32 bits of a 64 bits timestamp with microsecond granularity"/>
<arg name="time_lo" type="uint" summary="low 32 bits of a 64 bits timestamp with microsecond granularity"/>
</event>
<event name="pressure">
<description summary="gamepad trigger event">
Describes gamepad button source pressure notification, expressed
with a value varying between 0.0 and 1.0, with 0.0 being the neutral
state.
The time arguments is a timestamp in microseconds granularity with an
unknown base of the moment of the state changes
</description>
<arg name="source" type="uint" enum="button" summary="source that produced the event"/>
<arg name="value" type="fixed" summary="trigger value in the 0 to 1 range"/>
<arg name="time_hi" type="uint" summary="high 32 bits of a 64 bits timestamp with microsecond granularity"/>
<arg name="time_lo" type="uint" summary="low 32 bits of a 64 bits timestamp with microsecond granularity"/>
</event>
<enum name="axis">
<description summary="axis source">
Describes the source of an axis event.
</description>
<entry name="left_x" value="0" summary="left thumbstick horizontal axis"/>
<entry name="left_y" value="1" summary="left thumbstick vertical axis"/>
<entry name="right_x" value="2" summary="right thumbstick horizontal axis"/>
<entry name="right_y" value="3" summary="right thumbstick vertical axis"/>
<entry name="left_trigger" value="0" summary="left trigger axis"/>
<entry name="right_trigger" value="0" summary="right trigger axis"/>
</enum>
<event name="axis">
<description summary="gamepad axis event">
Describes gamepad axis position notification.
Thumbstick axis value varies from -1.0 to 1.0 and trigger axis value
varies from 0.0 to 1.0, with 0.0 being the neutral state.
The time arguments is a timestamp in microseconds of the moment of the
state changes
</description>
<arg name="source" type="uint" enum="axis" summary="source that produced the event"/>
<arg name="value" type="fixed" summary="axis value in the -1 to 1 range"/>
<arg name="time_hi" type="uint" summary="high 32 bits of a 64 bits timestamp with microsecond granularity"/>
<arg name="time_lo" type="uint" summary="low 32 bits of a 64 bits timestamp with microsecond granularity"/>
</event>
<event name="frame">
<description summary="end of a gamepad 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_gamepad_v1 events before a wp_gamepad_v1.frame event belong
together.
</description>
</event>
<event name="removed">
<description summary="this gamepad has been unplugged">
This event indicates that the controller is not available and no more
events will follow. Upon receipt of this event, the client should
immediately destroy the wp_gamepad object.
</description>
</event>
</interface>
</protocol>