1use wayland_client::{
2 globals::GlobalList, protocol::wl_pointer, Connection, Dispatch, QueueHandle,
3};
4use wayland_protocols::wp::relative_pointer::zv1::client::{
5 zwp_relative_pointer_manager_v1, zwp_relative_pointer_v1,
6};
7
8use crate::{error::GlobalError, globals::GlobalData, registry::GlobalProxy};
9
10#[derive(Debug)]
11pub struct RelativePointerState {
12 relative_pointer_manager:
13 GlobalProxy<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1>,
14}
15
16impl RelativePointerState {
17 /// Bind `zwp_relative_pointer_manager_v1` global, if it exists
18 pub fn bind<D>(globals: &GlobalList, qh: &QueueHandle<D>) -> Self
19 where
20 D: Dispatch<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, GlobalData>
21 + 'static,
22 {
23 let relative_pointer_manager: GlobalProxy<{unknown}> = GlobalProxy::from(globals.bind(qh, version:1..=1, udata:GlobalData));
24 Self { relative_pointer_manager }
25 }
26
27 pub fn get_relative_pointer<D>(
28 &self,
29 pointer: &wl_pointer::WlPointer,
30 qh: &QueueHandle<D>,
31 ) -> Result<zwp_relative_pointer_v1::ZwpRelativePointerV1, GlobalError>
32 where
33 D: Dispatch<zwp_relative_pointer_v1::ZwpRelativePointerV1, RelativePointerData> + 'static,
34 {
35 let udata: RelativePointerData = RelativePointerData { wl_pointer: pointer.clone() };
36 Ok(self.relative_pointer_manager.get()?.get_relative_pointer(pointer, qh, udata))
37 }
38}
39
40#[derive(Debug)]
41pub struct RelativeMotionEvent {
42 /// (x, y) motion vector
43 pub delta: (f64, f64),
44 /// Unaccelerated (x, y) motion vector
45 pub delta_unaccel: (f64, f64),
46 /// Timestamp in microseconds
47 pub utime: u64,
48}
49
50pub trait RelativePointerHandler: Sized {
51 fn relative_pointer_motion(
52 &mut self,
53 conn: &Connection,
54 qh: &QueueHandle<Self>,
55 relative_pointer: &zwp_relative_pointer_v1::ZwpRelativePointerV1,
56 pointer: &wl_pointer::WlPointer,
57 event: RelativeMotionEvent,
58 );
59}
60
61#[doc(hidden)]
62#[derive(Debug)]
63pub struct RelativePointerData {
64 wl_pointer: wl_pointer::WlPointer,
65}
66
67impl<D> Dispatch<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, GlobalData, D>
68 for RelativePointerState
69where
70 D: Dispatch<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, GlobalData>
71 + RelativePointerHandler,
72{
73 fn event(
74 _data: &mut D,
75 _manager: &zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1,
76 _event: zwp_relative_pointer_manager_v1::Event,
77 _: &GlobalData,
78 _conn: &Connection,
79 _qh: &QueueHandle<D>,
80 ) {
81 unreachable!()
82 }
83}
84
85impl<D> Dispatch<zwp_relative_pointer_v1::ZwpRelativePointerV1, RelativePointerData, D>
86 for RelativePointerState
87where
88 D: Dispatch<zwp_relative_pointer_v1::ZwpRelativePointerV1, RelativePointerData>
89 + RelativePointerHandler,
90{
91 fn event(
92 data: &mut D,
93 relative_pointer: &zwp_relative_pointer_v1::ZwpRelativePointerV1,
94 event: zwp_relative_pointer_v1::Event,
95 udata: &RelativePointerData,
96 conn: &Connection,
97 qh: &QueueHandle<D>,
98 ) {
99 match event {
100 zwp_relative_pointer_v1::Event::RelativeMotion {
101 utime_hi,
102 utime_lo,
103 dx,
104 dy,
105 dx_unaccel,
106 dy_unaccel,
107 } => {
108 data.relative_pointer_motion(
109 conn,
110 qh,
111 relative_pointer,
112 &udata.wl_pointer,
113 RelativeMotionEvent {
114 utime: ((utime_hi as u64) << 32) | (utime_lo as u64),
115 delta: (dx, dy),
116 delta_unaccel: (dx_unaccel, dy_unaccel),
117 },
118 );
119 }
120 _ => unreachable!(),
121 }
122 }
123}
124
125#[macro_export]
126macro_rules! delegate_relative_pointer {
127 ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => {
128 $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
129 $crate::reexports::protocols::wp::relative_pointer::zv1::client::zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1: $crate::globals::GlobalData
130 ] => $crate::seat::relative_pointer::RelativePointerState);
131 $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [
132 $crate::reexports::protocols::wp::relative_pointer::zv1::client::zwp_relative_pointer_v1::ZwpRelativePointerV1: $crate::seat::relative_pointer::RelativePointerData
133 ] => $crate::seat::relative_pointer::RelativePointerState);
134 };
135}
136