chore: refresco desde el monorepo (pin tawasuyu.git v0.2.0)
1//! Utilities for relative pointer support
2//!
3//! [PointerHandle::relative_motion] sends relative pointer events to any
4//! [ZwpRelativePointerV1] objects created by the client.
5//!
6//! ```
7//! extern crate wayland_server;
8//! extern crate smithay;
9//!
10//! use smithay::wayland::relative_pointer::RelativePointerManagerState;
11//! use smithay::delegate_relative_pointer;
12//! # use smithay::backend::input::KeyState;
13//! # use smithay::input::{
14//! # pointer::{PointerTarget, AxisFrame, MotionEvent, ButtonEvent, RelativeMotionEvent,
15//! # GestureSwipeBeginEvent, GestureSwipeUpdateEvent, GestureSwipeEndEvent,
16//! # GesturePinchBeginEvent, GesturePinchUpdateEvent, GesturePinchEndEvent,
17//! # GestureHoldBeginEvent, GestureHoldEndEvent},
18//! # keyboard::{KeyboardTarget, KeysymHandle, ModifiersState},
19//! # touch::{DownEvent, UpEvent, MotionEvent as TouchMotionEvent, ShapeEvent, OrientationEvent, TouchTarget},
20//! # Seat, SeatHandler, SeatState,
21//! # };
22//! # use smithay::utils::{IsAlive, Serial};
23//!
24//! # #[derive(Debug, Clone, PartialEq)]
25//! # struct Target;
26//! # impl IsAlive for Target {
27//! # fn alive(&self) -> bool { true }
28//! # }
29//! # impl PointerTarget<State> for Target {
30//! # fn enter(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
31//! # fn motion(&self, seat: &Seat<State>, data: &mut State, event: &MotionEvent) {}
32//! # fn relative_motion(&self, seat: &Seat<State>, data: &mut State, event: &RelativeMotionEvent) {}
33//! # fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) {}
34//! # fn axis(&self, seat: &Seat<State>, data: &mut State, frame: AxisFrame) {}
35//! # fn frame(&self, seat: &Seat<State>, data: &mut State) {}
36//! # fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) {}
37//! # fn gesture_swipe_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeBeginEvent) {}
38//! # fn gesture_swipe_update(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeUpdateEvent) {}
39//! # fn gesture_swipe_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureSwipeEndEvent) {}
40//! # fn gesture_pinch_begin(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchBeginEvent) {}
41//! # fn gesture_pinch_update(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchUpdateEvent) {}
42//! # fn gesture_pinch_end(&self, seat: &Seat<State>, data: &mut State, event: &GesturePinchEndEvent) {}
43//! # fn gesture_hold_begin(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldBeginEvent) {}
44//! # fn gesture_hold_end(&self, seat: &Seat<State>, data: &mut State, event: &GestureHoldEndEvent) {}
45//! # }
46//! # impl KeyboardTarget<State> for Target {
47//! # fn enter(&self, seat: &Seat<State>, data: &mut State, keys: Vec<KeysymHandle<'_>>, serial: Serial) {}
48//! # fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial) {}
49//! # fn key(
50//! # &self,
51//! # seat: &Seat<State>,
52//! # data: &mut State,
53//! # key: KeysymHandle<'_>,
54//! # state: KeyState,
55//! # serial: Serial,
56//! # time: u32,
57//! # ) {}
58//! # fn modifiers(&self, seat: &Seat<State>, data: &mut State, modifiers: ModifiersState, serial: Serial) {}
59//! # }
60//! # impl TouchTarget<State> for Target {
61//! # fn down(&self, seat: &Seat<State>, data: &mut State, event: &DownEvent, seq: Serial) {}
62//! # fn up(&self, seat: &Seat<State>, data: &mut State, event: &UpEvent, seq: Serial) {}
63//! # fn motion(&self, seat: &Seat<State>, data: &mut State, event: &TouchMotionEvent, seq: Serial) {}
64//! # fn frame(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
65//! # fn cancel(&self, seat: &Seat<State>, data: &mut State, seq: Serial) {}
66//! # fn shape(&self, seat: &Seat<State>, data: &mut State, event: &ShapeEvent, seq: Serial) {}
67//! # fn orientation(&self, seat: &Seat<State>, data: &mut State, event: &OrientationEvent, seq: Serial) {}
68//! # }
69//! # struct State {
70//! # seat_state: SeatState<Self>,
71//! # };
72//! # let mut display = wayland_server::Display::<State>::new().unwrap();
73//! # impl SeatHandler for State {
74//! # type KeyboardFocus = Target;
75//! # type PointerFocus = Target;
76//! # type TouchFocus = Target;
77//! #
78//! # fn seat_state(&mut self) -> &mut SeatState<Self> {
79//! # &mut self.seat_state
80//! # }
81//! # }
82//! let state = RelativePointerManagerState::new::<State>(&display.handle());
83//!
84//! delegate_relative_pointer!(State);
85//! ```
86
87use std::sync::{atomic::Ordering, Arc, Mutex};
88
89use atomic_float::AtomicF64;
90use wayland_protocols::wp::relative_pointer::zv1::server::{
91 zwp_relative_pointer_manager_v1::{self, ZwpRelativePointerManagerV1},
92 zwp_relative_pointer_v1::{self, ZwpRelativePointerV1},
93};
94use wayland_server::{
95 backend::{ClientId, GlobalId},
96 protocol::wl_surface::WlSurface,
97 Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
98};
99
100use crate::{
101 input::{
102 pointer::{PointerHandle, RelativeMotionEvent},
103 SeatHandler,
104 },
105 wayland::seat::PointerUserData,
106};
107
108const MANAGER_VERSION: u32 = 1;
109
110#[derive(Debug, Default)]
111pub(crate) struct WpRelativePointerHandle {
112 known_relative_pointers: Mutex<Vec<ZwpRelativePointerV1>>,
113}
114
115impl WpRelativePointerHandle {
116 fn new_relative_pointer(&self, pointer: ZwpRelativePointerV1) {
117 self.known_relative_pointers.lock().unwrap().push(pointer);
118 }
119
120 pub(super) fn relative_motion<D: SeatHandler + 'static>(
121 &self,
122 surface: &WlSurface,
123 event: &RelativeMotionEvent,
124 ) {
125 self.for_each_focused_pointer(surface, |ptr| {
126 let client_scale = ptr
127 .data::<RelativePointerUserData<D>>()
128 .unwrap()
129 .client_scale
130 .load(Ordering::Acquire);
131 let delta = event.delta.to_client(client_scale);
132 let delta_unaccel = event.delta_unaccel.to_client(client_scale);
133
134 let utime_hi = (event.utime >> 32) as u32;
135 let utime_lo = (event.utime & 0xffffffff) as u32;
136 ptr.relative_motion(
137 utime_hi,
138 utime_lo,
139 delta.x,
140 delta.y,
141 delta_unaccel.x,
142 delta_unaccel.y,
143 );
144 })
145 }
146
147 fn for_each_focused_pointer(&self, surface: &WlSurface, mut f: impl FnMut(ZwpRelativePointerV1)) {
148 let inner = self.known_relative_pointers.lock().unwrap();
149 for ptr in &*inner {
150 if ptr.id().same_client_as(&surface.id()) {
151 f(ptr.clone())
152 }
153 }
154 }
155}
156
157/// User data of ZwpRelativePointerV1 object
158#[derive(Debug)]
159pub struct RelativePointerUserData<D: SeatHandler> {
160 handle: Option<PointerHandle<D>>,
161 client_scale: Arc<AtomicF64>,
162}
163
164/// State of the relative pointer manager
165#[derive(Debug)]
166pub struct RelativePointerManagerState {
167 global: GlobalId,
168}
169
170impl RelativePointerManagerState {
171 /// Register new [ZwpRelativePointerV1] global
172 pub fn new<D>(display: &DisplayHandle) -> Self
173 where
174 D: GlobalDispatch<ZwpRelativePointerManagerV1, ()>,
175 D: Dispatch<ZwpRelativePointerManagerV1, ()>,
176 D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
177 D: SeatHandler,
178 D: 'static,
179 {
180 let global = display.create_global::<D, ZwpRelativePointerManagerV1, _>(MANAGER_VERSION, ());
181
182 Self { global }
183 }
184
185 /// [ZwpRelativePointerV1] GlobalId getter
186 pub fn global(&self) -> GlobalId {
187 self.global.clone()
188 }
189}
190
191impl<D> Dispatch<ZwpRelativePointerManagerV1, (), D> for RelativePointerManagerState
192where
193 D: Dispatch<ZwpRelativePointerManagerV1, ()>,
194 D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
195 D: SeatHandler,
196 D: 'static,
197{
198 fn request(
199 _state: &mut D,
200 _client: &wayland_server::Client,
201 _relative_pointer_manager: &ZwpRelativePointerManagerV1,
202 request: zwp_relative_pointer_manager_v1::Request,
203 _data: &(),
204 _dh: &DisplayHandle,
205 data_init: &mut wayland_server::DataInit<'_, D>,
206 ) {
207 match request {
208 zwp_relative_pointer_manager_v1::Request::GetRelativePointer { id, pointer } => {
209 let data = pointer.data::<PointerUserData<D>>().unwrap();
210 let user_data = RelativePointerUserData {
211 handle: data.handle.clone(),
212 client_scale: data.client_scale.clone(),
213 };
214 let pointer = data_init.init(id, user_data);
215 if let Some(handle) = &data.handle {
216 handle.wp_relative.new_relative_pointer(pointer);
217 }
218 }
219 zwp_relative_pointer_manager_v1::Request::Destroy => {}
220 _ => unreachable!(),
221 }
222 }
223}
224
225impl<D> GlobalDispatch<ZwpRelativePointerManagerV1, (), D> for RelativePointerManagerState
226where
227 D: GlobalDispatch<ZwpRelativePointerManagerV1, ()>
228 + Dispatch<ZwpRelativePointerManagerV1, ()>
229 + SeatHandler
230 + 'static,
231{
232 fn bind(
233 _state: &mut D,
234 _dh: &DisplayHandle,
235 _client: &Client,
236 resource: New<ZwpRelativePointerManagerV1>,
237 _global_data: &(),
238 data_init: &mut DataInit<'_, D>,
239 ) {
240 data_init.init(resource, ());
241 }
242}
243
244impl<D> Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>, D> for RelativePointerManagerState
245where
246 D: Dispatch<ZwpRelativePointerV1, RelativePointerUserData<D>>,
247 D: SeatHandler,
248 D: 'static,
249{
250 fn request(
251 _state: &mut D,
252 _client: &wayland_server::Client,
253 _relative_pointer: &ZwpRelativePointerV1,
254 request: zwp_relative_pointer_v1::Request,
255 _data: &RelativePointerUserData<D>,
256 _dh: &DisplayHandle,
257 _data_init: &mut wayland_server::DataInit<'_, D>,
258 ) {
259 match request {
260 zwp_relative_pointer_v1::Request::Destroy => {}
261 _ => unreachable!(),
262 }
263 }
264
265 fn destroyed(
266 _state: &mut D,
267 _: ClientId,
268 object: &ZwpRelativePointerV1,
269 data: &RelativePointerUserData<D>,
270 ) {
271 if let Some(ref handle) = data.handle {
272 handle
273 .wp_relative
274 .known_relative_pointers
275 .lock()
276 .unwrap()
277 .retain(|p| p.id() != object.id());
278 }
279 }
280}
281
282/// Macro to delegate implementation of the relative pointer protocol
283#[macro_export]
284macro_rules! delegate_relative_pointer {
285 ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
286 $crate::reexports::wayland_server::delegate_global_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
287 $crate::reexports::wayland_protocols::wp::relative_pointer::zv1::server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1: ()
288 ] => $crate::wayland::relative_pointer::RelativePointerManagerState);
289 $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
290 $crate::reexports::wayland_protocols::wp::relative_pointer::zv1::server::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1: ()
291 ] => $crate::wayland::relative_pointer::RelativePointerManagerState);
292 $crate::reexports::wayland_server::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
293 $crate::reexports::wayland_protocols::wp::relative_pointer::zv1::server::zwp_relative_pointer_v1::ZwpRelativePointerV1: $crate::wayland::relative_pointer::RelativePointerUserData<Self>
294 ] => $crate::wayland::relative_pointer::RelativePointerManagerState);
295 };
296}