1//! Touch event types
23use super::EventTrait;
4use crate::{ffi, AsRaw, Context, FromRaw, Libinput};
56/// Common functions all Touch-Events implement.
7pub trait TouchEventTrait: AsRaw<ffi::libinput_event_touch> + Context {
8ffi_func!(
9/// The event time for this event
10fn time, ffi::libinput_event_touch_get_time, u32);
11ffi_func!(
12/// The event time for this event in microseconds
13fn time_usec, ffi::libinput_event_touch_get_time_usec, u64);
1415/// Convert into a general `TouchEvent` again
16fn into_touch_event(self) -> TouchEvent
17where
18Self: Sized,
19 {
20unsafe { TouchEvent::from_raw(self.as_raw_mut(), self.context()) }
21 }
22}
2324impl<T: AsRaw<ffi::libinput_event_touch> + Context> TouchEventTrait for T {}
2526/// 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.
29pub trait TouchEventSlot: AsRaw<ffi::libinput_event_touch> {
30ffi_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.
38fn seat_slot, ffi::libinput_event_touch_get_seat_slot, u32);
3940/// 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`.
46fn slot(&self) -> Option<u32> {
47match 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}
5455/// Position related functions all TouchEvents implement, that have a screen
56/// position assigned to them.
57pub trait TouchEventPosition: AsRaw<ffi::libinput_event_touch> {
58ffi_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`.
63fn x, ffi::libinput_event_touch_get_x, f64);
64ffi_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`.
69fn y, ffi::libinput_event_touch_get_y, f64);
7071/// 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
77fn x_transformed(&self, width: u32) -> f64 {
78unsafe { ffi::libinput_event_touch_get_x_transformed(self.as_raw_mut(), width) }
79 }
8081/// 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
87fn y_transformed(&self, height: u32) -> f64 {
88unsafe { ffi::libinput_event_touch_get_y_transformed(self.as_raw_mut(), height) }
89 }
90}
9192/// A touch related `Event`
93#[derive(Debug, PartialEq, Eq, Hash)]
94#[non_exhaustive]
95pub enum TouchEvent {
96/// An event related to resting the finger on the screen
97Down(TouchDownEvent),
98/// An event related to lifting the finger on the screen
99Up(TouchUpEvent),
100/// An event related to moving a finger on the screen
101Motion(TouchMotionEvent),
102/// An event cancelling previous events on this slot
103Cancel(TouchCancelEvent),
104/// Signals the end of a set of touchpoints at one device sample time.
105Frame(TouchFrameEvent),
106}
107108impl EventTrait for TouchEvent {
109#[doc(hidden)]
110fn as_raw_event(&self) -> *mut ffi::libinput_event {
111match self {
112 TouchEvent::Down(event) => event.as_raw_event(),
113 TouchEvent::Up(event) => event.as_raw_event(),
114 TouchEvent::Motion(event) => event.as_raw_event(),
115 TouchEvent::Cancel(event) => event.as_raw_event(),
116 TouchEvent::Frame(event) => event.as_raw_event(),
117 }
118 }
119}
120121impl FromRaw<ffi::libinput_event_touch> for TouchEvent {
122unsafe fn try_from_raw(
123 event: *mut ffi::libinput_event_touch,
124 context: &Libinput,
125 ) -> Option<Self> {
126let base = ffi::libinput_event_touch_get_base_event(event);
127match 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 => {
132Some(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 }
146unsafe fn from_raw(event: *mut ffi::libinput_event_touch, context: &Libinput) -> Self {
147Self::try_from_raw(event, context).expect("Unknown touch event type")
148 }
149}
150151impl AsRaw<ffi::libinput_event_touch> for TouchEvent {
152fn as_raw(&self) -> *const ffi::libinput_event_touch {
153match self {
154 TouchEvent::Down(event) => event.as_raw(),
155 TouchEvent::Up(event) => event.as_raw(),
156 TouchEvent::Motion(event) => event.as_raw(),
157 TouchEvent::Cancel(event) => event.as_raw(),
158 TouchEvent::Frame(event) => event.as_raw(),
159 }
160 }
161}
162163impl Context for TouchEvent {
164fn context(&self) -> &Libinput {
165match self {
166 TouchEvent::Down(event) => event.context(),
167 TouchEvent::Up(event) => event.context(),
168 TouchEvent::Motion(event) => event.context(),
169 TouchEvent::Cancel(event) => event.context(),
170 TouchEvent::Frame(event) => event.context(),
171 }
172 }
173}
174175ffi_event_struct!(
176/// An event related to resting the finger on the screen
177struct TouchDownEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event);
178179impl TouchEventSlot for TouchDownEvent {}
180181impl TouchEventPosition for TouchDownEvent {}
182183ffi_event_struct!(
184/// An event related to lifting the finger on the screen
185struct TouchUpEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event);
186187impl TouchEventSlot for TouchUpEvent {}
188189ffi_event_struct!(
190/// An event related to moving a finger on the screen
191struct TouchMotionEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event);
192193impl TouchEventSlot for TouchMotionEvent {}
194195impl TouchEventPosition for TouchMotionEvent {}
196197ffi_event_struct!(
198/// An event cancelling previous events on this slot
199struct TouchCancelEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event);
200201impl TouchEventSlot for TouchCancelEvent {}
202203ffi_event_struct!(
204/// Signals the end of a set of touchpoints at one device sample time.
205struct TouchFrameEvent, ffi::libinput_event_touch, ffi::libinput_event_touch_get_base_event);