Skip to content

Commit 1fa16c3

Browse files
committed
feat(server): add support for wp_game_controller_v1
1 parent 2238751 commit 1fa16c3

File tree

9 files changed

+447
-14
lines changed

9 files changed

+447
-14
lines changed

mm-server/src/compositor.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ impl Compositor {
192192
create_global::<zwp_pointer_constraints_v1::ZwpPointerConstraintsV1>(&dh, 1);
193193
create_global::<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1>(&dh, 1);
194194
create_global::<zwp_text_input_manager_v3::ZwpTextInputManagerV3>(&dh, 1);
195+
create_global::<wp_game_controller::WpGameControllerV1>(&dh, 1);
195196

196197
create_global::<wl_shm::WlShm>(&dh, 1);
197198
create_global::<zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1>(&dh, 5);
@@ -817,7 +818,7 @@ impl Compositor {
817818
self.state.new_display_params = Some(params);
818819
}
819820
ControlMessage::KeyboardInput {
820-
evdev_scancode,
821+
key_code: evdev_scancode,
821822
char,
822823
state,
823824
} => {
@@ -927,6 +928,26 @@ impl Compositor {
927928
ControlMessage::PointerLeft => {
928929
self.state.default_seat.lift_pointer(&self.state.serial);
929930
}
931+
// TODO: for now, we always assume a controller is plugged in.
932+
// ControlMessage::GamepadAvailable(_) => (),
933+
// ControlMessage::GamepadUnavailable(_) => (),
934+
ControlMessage::GamepadAxis {
935+
axis_code, value, ..
936+
} => {
937+
self.state.default_seat.gamepad_axis(axis_code, value);
938+
}
939+
ControlMessage::GamepadTrigger {
940+
trigger_code,
941+
value,
942+
..
943+
} => {
944+
self.state.default_seat.gamepad_trigger(trigger_code, value);
945+
}
946+
ControlMessage::GamepadInput {
947+
button_code, state, ..
948+
} => {
949+
self.state.default_seat.gamepad_input(button_code, state);
950+
}
930951
// Handled above.
931952
ControlMessage::Stop | ControlMessage::Attach { .. } => unreachable!(),
932953
}
@@ -938,10 +959,11 @@ impl Compositor {
938959
fn create_global<G: wayland_server::Resource + 'static>(
939960
dh: &wayland_server::DisplayHandle,
940961
version: u32,
941-
) where
962+
) -> wayland_server::backend::GlobalId
963+
where
942964
State: wayland_server::GlobalDispatch<G, ()>,
943965
{
944-
let _ = dh.create_global::<State, G, ()>(version, ());
966+
dh.create_global::<State, G, ()>(version, ())
945967
}
946968

947969
fn gen_socket_name() -> OsString {

mm-server/src/compositor/control.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crossbeam_channel::Sender;
77
use crate::{
88
codec::{AudioCodec, VideoCodec},
99
color::VideoProfile,
10+
compositor::ButtonState,
1011
pixel_scale::PixelScale,
1112
};
1213

@@ -47,7 +48,7 @@ pub enum ControlMessage {
4748
Detach(u64),
4849
UpdateDisplayParams(DisplayParams),
4950
KeyboardInput {
50-
evdev_scancode: u32,
51+
key_code: u32,
5152
state: super::KeyState,
5253
char: Option<char>,
5354
},
@@ -59,10 +60,27 @@ pub enum ControlMessage {
5960
x: f64,
6061
y: f64,
6162
button_code: u32,
62-
state: super::ButtonState,
63+
state: ButtonState,
6364
},
6465
PointerAxis(f64, f64),
6566
PointerAxisDiscrete(f64, f64),
67+
// GamepadAvailable(u64),
68+
// GamepadUnavailable(u64),
69+
GamepadAxis {
70+
_id: u64,
71+
axis_code: u32,
72+
value: f64,
73+
},
74+
GamepadTrigger {
75+
_id: u64,
76+
trigger_code: u32,
77+
value: f64,
78+
},
79+
GamepadInput {
80+
_id: u64,
81+
button_code: u32,
82+
state: ButtonState,
83+
},
6684
}
6785

6886
#[derive(Debug, Clone)]

mm-server/src/compositor/dispatch.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod wl_drm;
88
mod wl_output;
99
mod wl_seat;
1010
mod wl_shm;
11+
mod wp_game_controller;
1112
mod wp_linux_dmabuf;
1213
mod wp_pointer_constraints;
1314
mod wp_presentation;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2024 Colin Marc <[email protected]>
2+
//
3+
// SPDX-License-Identifier: BUSL-1.1
4+
5+
use crate::compositor::{wp_game_controller::wp_game_controller_v1, State};
6+
7+
impl wayland_server::GlobalDispatch<wp_game_controller_v1::WpGameControllerV1, ()> for State {
8+
fn bind(
9+
state: &mut Self,
10+
_handle: &wayland_server::DisplayHandle,
11+
_client: &wayland_server::Client,
12+
resource: wayland_server::New<wp_game_controller_v1::WpGameControllerV1>,
13+
_global_data: &(),
14+
data_init: &mut wayland_server::DataInit<'_, Self>,
15+
) {
16+
let global = data_init.init(resource, ());
17+
state.default_seat.add_gamepad(global);
18+
}
19+
}
20+
21+
impl wayland_server::Dispatch<wp_game_controller_v1::WpGameControllerV1, ()> for State {
22+
fn request(
23+
state: &mut Self,
24+
_client: &wayland_server::Client,
25+
resource: &wp_game_controller_v1::WpGameControllerV1,
26+
request: wp_game_controller_v1::Request,
27+
_data: &(),
28+
_dhandle: &wayland_server::DisplayHandle,
29+
_data_init: &mut wayland_server::DataInit<'_, Self>,
30+
) {
31+
match request {
32+
wp_game_controller_v1::Request::Destroy => {
33+
state.default_seat.destroy_gamepad(resource);
34+
}
35+
}
36+
}
37+
}

mm-server/src/compositor/protocols.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
// SPDX-License-Identifier: BUSL-1.1
44

55
pub mod wl_drm;
6+
pub mod wp_game_controller;
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<protocol name="game_controller_v1">
3+
<copyright>
4+
Copyright © 2023-2024 Collabora, Ltd.
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a
7+
copy of this software and associated documentation files (the "Software"),
8+
to deal in the Software without restriction, including without limitation
9+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
10+
and/or sell copies of the Software, and to permit persons to whom the
11+
Software is furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice (including the next
14+
paragraph) shall be included in all copies or substantial portions of the
15+
Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23+
DEALINGS IN THE SOFTWARE.
24+
</copyright>
25+
26+
<description summary="Wayland protocol for game controller devices">
27+
TODO high level documentation about game controllers and the input source
28+
</description>
29+
30+
<interface name="wp_game_controller_v1" version="1">
31+
<description summary="game controller input device">
32+
This interface represents a physical game controller, also known as a
33+
gamepad, held by the user in their hands.
34+
35+
The wp_game_controller_v1 interface generates events for every input
36+
sources present on the game controller. The client can also request
37+
haptic vibration, or rumble, if the hardware supports it.
38+
</description>
39+
40+
<request name="destroy" type="destructor">
41+
<description summary="release the memory for the game controller object">
42+
Destroy the game controller device.
43+
</description>
44+
</request>
45+
46+
<event name="name">
47+
<description summary="name of this game controller">
48+
User friendly device identification string. The game controller name
49+
is a UTF-8 string that should not be NULL.
50+
</description>
51+
<arg name="name" type="string" summary="game controller name"/>
52+
</event>
53+
54+
<enum name="theme">
55+
<description summary="button theme">
56+
Each vendor uses a different set of glyph on its controller's buttons.
57+
</description>
58+
<entry name="none" value="0" summary="default value"/>
59+
<entry name="playstation" value="1" summary="Sony controllers"/>
60+
<entry name="xbox" value="2" summary="Microsoft controllers"/>
61+
<entry name="nintendo" value="3" summary="Nintendo controllers"/>
62+
</enum>
63+
64+
<event name="theme_hint">
65+
<description summary="theme the client should use">
66+
Theme the client should follow to render the adequate glyph for matching
67+
the button on the physical controller.
68+
</description>
69+
<arg name="hint" type="uint" enum="theme" summary="theme hint"/>
70+
</event>
71+
72+
<event name="done">
73+
<description summary="all properties events are sent">
74+
This event is sent after all of the other properties event have been
75+
sent. No more property events will be sent to the client after this.
76+
</description>
77+
</event>
78+
79+
<event name="enter">
80+
<description summary="enter focus event">
81+
Notification that the gamepad is focused on a given surface.
82+
</description>
83+
<arg name="serial" type="uint" summary="serial number of the enter evenr"/>
84+
<arg name="surface" type="object" interface="wl_surface" summary="surface gaining gamepad focus"/>
85+
</event>
86+
87+
<event name="leave">
88+
<description summary="leave focus event">
89+
Notification that the gamepad is no longer focused on the given surface.
90+
</description>
91+
<arg name="serial" type="uint" summary="serial number of the leave event"/>
92+
<arg name="surface" type="object" interface="wl_surface" summary="surface loosing gamepad focus"/>
93+
</event>
94+
95+
<enum name="button_state">
96+
<description summary="physical input source state">
97+
Describes the physical state of a button on the game controller.
98+
</description>
99+
<entry name="released" value="0" summary="the input source is not pressed"/>
100+
<entry name="pressed" value="1" summary="the input source is pressed"/>
101+
</enum>
102+
103+
<event name="button">
104+
<description summary="game controller button event">
105+
game controller button click and release notification.
106+
107+
The source is a button code as defined in the Linux kernel's
108+
linux/input-event-codes.h header file.
109+
110+
The time argument is a timestamp in microseconds of the moment of the
111+
state changes
112+
</description>
113+
<arg name="source" type="uint" summary="source that produced the event"/>
114+
<arg name="state" type="uint" enum="button_state" summary="physical state of the button"/>
115+
<arg name="time" type="uint" summary="timestamp with microsecond granularity"/>
116+
</event>
117+
118+
<event name="trigger">
119+
<description summary="game controller trigger event">
120+
game controller trigger pressure notification, expressed with a value
121+
varying between 0.0 and 1.0, with 0.0 being the neutral state.
122+
123+
The source is a button code as defined in the Linux kernel's
124+
linux/input-event-codes.h header file.
125+
126+
The time argument is a timestamp in microseconds of the moment of the
127+
state changes
128+
</description>
129+
<arg name="source" type="uint" summary="source that produced the event"/>
130+
<arg name="value" type="fixed" summary="trigger value in the 0 to 1 range"/>
131+
<arg name="time" type="uint" summary="timestamp with microsecond granularity"/>
132+
</event>
133+
134+
<event name="axis">
135+
<description summary="game controller axis event">
136+
game controller axis position notification, expressed by a 2D
137+
position varying from -1.0 to 1.0, with 0.0 being the neutral state.
138+
139+
The source is a button code as defined in the Linux kernel's
140+
linux/input-event-codes.h header file.
141+
142+
The time argument is a timestamp in microseconds of the moment of the
143+
state changes
144+
</description>
145+
<arg name="source" type="uint" summary="source that produced the event"/>
146+
<arg name="value" type="fixed" summary="axis coordinate in the -1 to 1 range"/>
147+
<arg name="time" type="uint" summary="timestamp with microsecond granularity"/>
148+
</event>
149+
150+
<event name="frame">
151+
<description summary="end of a game controller event sequence">
152+
Indicates the end of a set of events that logically belong together.
153+
A client is expected to accumulate the data in all events within the
154+
frame before proceeding
155+
156+
All wp_game_controller_v1 events before a wp_game_controller_v1.frame
157+
event belong together.
158+
</description>
159+
</event>
160+
</interface>
161+
</protocol>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2024 Colin Marc <[email protected]>
2+
//
3+
// SPDX-License-Identifier: BUSL-1.1
4+
5+
#![allow(non_upper_case_globals)]
6+
#![allow(non_camel_case_types)]
7+
8+
use wayland_server;
9+
use wayland_server::protocol::*;
10+
11+
pub mod __interfaces {
12+
use wayland_server::backend as wayland_backend;
13+
use wayland_server::protocol::__interfaces::*;
14+
wayland_scanner::generate_interfaces!("src/compositor/protocols/game-controller-v1.xml");
15+
}
16+
17+
use self::__interfaces::*;
18+
wayland_scanner::generate_server_code!("src/compositor/protocols/game-controller-v1.xml");
19+
20+
pub use wp_game_controller_v1::*;

0 commit comments

Comments
 (0)