| 1 | use wayland_client::{ |
| 2 | globals::GlobalList, protocol::wl_pointer, Connection, Dispatch, QueueHandle, |
| 3 | }; |
| 4 | use wayland_protocols::wp::relative_pointer::zv1::client::{ |
| 5 | zwp_relative_pointer_manager_v1, zwp_relative_pointer_v1, |
| 6 | }; |
| 7 | |
| 8 | use crate::{error::GlobalError, globals::GlobalData, registry::GlobalProxy}; |
| 9 | |
| 10 | #[derive (Debug)] |
| 11 | pub struct RelativePointerState { |
| 12 | relative_pointer_manager: |
| 13 | GlobalProxy<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1>, |
| 14 | } |
| 15 | |
| 16 | impl 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)] |
| 41 | pub 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 | |
| 50 | pub 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)] |
| 63 | pub struct RelativePointerData { |
| 64 | wl_pointer: wl_pointer::WlPointer, |
| 65 | } |
| 66 | |
| 67 | impl<D> Dispatch<zwp_relative_pointer_manager_v1::ZwpRelativePointerManagerV1, GlobalData, D> |
| 68 | for RelativePointerState |
| 69 | where |
| 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 | |
| 85 | impl<D> Dispatch<zwp_relative_pointer_v1::ZwpRelativePointerV1, RelativePointerData, D> |
| 86 | for RelativePointerState |
| 87 | where |
| 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 ] |
| 126 | macro_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 | |