1 | //! Touch event types |
2 | |
3 | use super::EventTrait; |
4 | use crate::{ffi, AsRaw, Context, FromRaw, Libinput}; |
5 | |
6 | /// Common functions all Touch-Events implement. |
7 | pub trait TouchEventTrait: AsRaw<ffi::libinput_event_touch> + Context { |
8 | ffi_func!( |
9 | /// The event time for this event |
10 | fn time, ffi::libinput_event_touch_get_time, u32); |
11 | ffi_func!( |
12 | /// The event time for this event in microseconds |
13 | fn time_usec, ffi::libinput_event_touch_get_time_usec, u64); |
14 | |
15 | /// Convert into a general `TouchEvent` again |
16 | fn into_touch_event(self) -> TouchEvent |
17 | where |
18 | Self: Sized, |
19 | { |
20 | unsafe { TouchEvent::from_raw(self.as_raw_mut(), self.context()) } |
21 | } |
22 | } |
23 | |
24 | impl<T: AsRaw<ffi::libinput_event_touch> + Context> TouchEventTrait for T {} |
25 | |
26 | /// Touch slot related functions all TouchEvents implement, that can be mapped to slots. |
27 | /// |
28 | /// A touch slot is grouping all events related to a single gesture together. |
29 | pub trait TouchEventSlot: AsRaw<ffi::libinput_event_touch> { |
30 | ffi_func!( |
31 | /// Get the seat slot of the touch event. |
32 | /// |
33 | /// A seat slot is a non-negative seat wide unique identifier of an active |
34 | /// touch point. |
35 | /// |
36 | /// Events from single touch devices will be represented as one individual |
37 | /// touch point per device. |
38 | fn seat_slot, ffi::libinput_event_touch_get_seat_slot, u32); |
39 | |
40 | /// Get the slot of this touch event. |
41 | /// |
42 | /// See the kernel's multitouch protocol B documentation for more information. |
43 | /// |
44 | /// If the touch event has no assigned slot, for example if it is from a |
45 | /// single touch device, this function returns `None`. |
46 | fn slot(&self) -> Option<u32> { |
47 | match unsafe { ffi::libinput_event_touch_get_slot(self.as_raw_mut()) } { |
48 | x if x >= 0 => Some(x as u32), |
49 | -1 => None, |
50 | _ => panic!("libinput_event_touch_get_slot returned undocumentated value!" ), |
51 | } |
52 | } |
53 | } |
54 | |
55 | /// Position related functions all TouchEvents implement, that have a screen |
56 | /// position assigned to them. |
57 | pub trait TouchEventPosition: AsRaw<ffi::libinput_event_touch> { |
58 | ffi_func!( |
59 | /// Return the current absolute x coordinate of the touch event, in mm from |
60 | /// the top left corner of the device. |
61 | /// |
62 | /// To get the corresponding output screen coordinate, use `x_transformed`. |
63 | fn x, ffi::libinput_event_touch_get_x, f64); |
64 | ffi_func!( |
65 | /// Return the current absolute y coordinate of the touch event, in mm from |
66 | /// the top left corner of the device. |
67 | /// |
68 | /// To get the corresponding output screen coordinate, use `y_transformed`. |
69 | fn y, ffi::libinput_event_touch_get_y, f64); |
70 | |
71 | /// Return the current absolute x coordinate of the touch event, transformed |
72 | /// to screen coordinates. |
73 | /// |
74 | /// ## Arguments |
75 | /// |
76 | /// - width - The current output screen width |
77 | fn x_transformed(&self, width: u32) -> f64 { |
78 | unsafe { ffi::libinput_event_touch_get_x_transformed(self.as_raw_mut(), width) } |
79 | } |
80 | |
81 | /// Return the current absolute y coordinate of the touch event, transformed |
82 | /// to screen coordinates. |
83 | /// |
84 | /// ## Arguments |
85 | /// |
86 | /// - height - The current output screen height |
87 | fn y_transformed(&self, height: u32) -> f64 { |
88 | unsafe { ffi::libinput_event_touch_get_y_transformed(self.as_raw_mut(), height) } |
89 | } |
90 | } |
91 | |
92 | /// A touch related `Event` |
93 | #[derive (Debug, PartialEq, Eq, Hash)] |
94 | #[non_exhaustive ] |
95 | pub enum TouchEvent { |
96 | /// An event related to resting the finger on the screen |
97 | Down(TouchDownEvent), |
98 | /// An event related to lifting the finger on the screen |
99 | Up(TouchUpEvent), |
100 | /// An event related to moving a finger on the screen |
101 | Motion(TouchMotionEvent), |
102 | /// An event cancelling previous events on this slot |
103 | Cancel(TouchCancelEvent), |
104 | /// Signals the end of a set of touchpoints at one device sample time. |
105 | Frame(TouchFrameEvent), |
106 | } |
107 | |
108 | impl EventTrait for TouchEvent { |
109 | #[doc (hidden)] |
110 | fn as_raw_event(&self) -> *mut ffi::libinput_event { |
111 | match self { |
112 | TouchEvent::Down(event: &TouchDownEvent) => event.as_raw_event(), |
113 | TouchEvent::Up(event: &TouchUpEvent) => event.as_raw_event(), |
114 | TouchEvent::Motion(event: &TouchMotionEvent) => event.as_raw_event(), |
115 | TouchEvent::Cancel(event: &TouchCancelEvent) => event.as_raw_event(), |
116 | TouchEvent::Frame(event: &TouchFrameEvent) => event.as_raw_event(), |
117 | } |
118 | } |
119 | } |
120 | |
121 | impl FromRaw<ffi::libinput_event_touch> for TouchEvent { |
122 | unsafe fn try_from_raw( |
123 | event: *mut ffi::libinput_event_touch, |
124 | context: &Libinput, |
125 | ) -> Option<Self> { |
126 | let base = ffi::libinput_event_touch_get_base_event(event); |
127 | match ffi::libinput_event_get_type(base) { |
128 | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_DOWN => Some(TouchEvent::Down( |
129 | TouchDownEvent::try_from_raw(event, context)?, |
130 | )), |
131 | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_UP => { |
132 | Some(TouchEvent::Up(TouchUpEvent::try_from_raw(event, context)?)) |
133 | } |
134 | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_MOTION => Some(TouchEvent::Motion( |
135 | TouchMotionEvent::try_from_raw(event, context)?, |
136 | )), |
137 | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_CANCEL => Some(TouchEvent::Cancel( |
138 | TouchCancelEvent::try_from_raw(event, context)?, |
139 | )), |
140 | ffi::libinput_event_type_LIBINPUT_EVENT_TOUCH_FRAME => Some(TouchEvent::Frame( |
141 | TouchFrameEvent::try_from_raw(event, context)?, |
142 | )), |
143 | _ => None, |
144 | } |
145 | } |
146 | unsafe fn from_raw(event: *mut ffi::libinput_event_touch, context: &Libinput) -> Self { |
147 | Self::try_from_raw(event, context).expect("Unknown touch event type" ) |
148 | } |
149 | } |
150 | |
151 | impl AsRaw<ffi::libinput_event_touch> for TouchEvent { |
152 | fn as_raw(&self) -> *const ffi::libinput_event_touch { |
153 | match self { |
154 | TouchEvent::Down(event: &TouchDownEvent) => event.as_raw(), |
155 | TouchEvent::Up(event: &TouchUpEvent) => event.as_raw(), |
156 | TouchEvent::Motion(event: &TouchMotionEvent) => event.as_raw(), |
157 | TouchEvent::Cancel(event: &TouchCancelEvent) => event.as_raw(), |
158 | TouchEvent::Frame(event: &TouchFrameEvent) => event.as_raw(), |
159 | } |
160 | } |
161 | } |
162 | |
163 | impl Context for TouchEvent { |
164 | fn context(&self) -> &Libinput { |
165 | match self { |
166 | TouchEvent::Down(event: &TouchDownEvent) => event.context(), |
167 | TouchEvent::Up(event: &TouchUpEvent) => event.context(), |
168 | TouchEvent::Motion(event: &TouchMotionEvent) => event.context(), |
169 | TouchEvent::Cancel(event: &TouchCancelEvent) => event.context(), |
170 | TouchEvent::Frame(event: &TouchFrameEvent) => event.context(), |
171 | } |
172 | } |
173 | } |
174 | |
175 | ffi_event_struct!( |
176 | /// An event related to resting the finger on the screen |
177 | struct TouchDownEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event); |
178 | |
179 | impl TouchEventSlot for TouchDownEvent {} |
180 | |
181 | impl TouchEventPosition for TouchDownEvent {} |
182 | |
183 | ffi_event_struct!( |
184 | /// An event related to lifting the finger on the screen |
185 | struct TouchUpEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event); |
186 | |
187 | impl TouchEventSlot for TouchUpEvent {} |
188 | |
189 | ffi_event_struct!( |
190 | /// An event related to moving a finger on the screen |
191 | struct TouchMotionEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event); |
192 | |
193 | impl TouchEventSlot for TouchMotionEvent {} |
194 | |
195 | impl TouchEventPosition for TouchMotionEvent {} |
196 | |
197 | ffi_event_struct!( |
198 | /// An event cancelling previous events on this slot |
199 | struct TouchCancelEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event); |
200 | |
201 | impl TouchEventSlot for TouchCancelEvent {} |
202 | |
203 | ffi_event_struct!( |
204 | /// Signals the end of a set of touchpoints at one device sample time. |
205 | struct TouchFrameEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event); |
206 | |