evdev/
event_variants.rs

1//! The event_variants module contains new-type wrappers around [`InputEvent`]
2//! for each known [`EventType`].
3//!
4//! These event variants guarantee that the underlying `InputEvent` has the
5//! corresponding type. They may also contain additional methods for the
6//! specific type and convenient shortcut methods for event creation.
7//! An `InputEvent` can be converted to the corresponding event variant with
8//! the [`InputEvent::destructure()`] method. Each event variant implements
9//! `Into<InputEvent>` and `Deref<Target=InputEvent>` for easy back conversion.
10
11use std::fmt;
12use std::ops::Deref;
13use std::time::SystemTime;
14
15use crate::compat::input_event;
16use crate::constants::{
17    AbsoluteAxisCode, FFStatusCode, LedCode, MiscCode, OtherCode, PowerCode, RelativeAxisCode,
18    RepeatCode, SoundCode, SwitchCode, SynchronizationCode, UInputCode,
19};
20use crate::scancodes::KeyCode;
21use crate::{systime_to_timeval, EventType, FFEffectCode};
22use crate::{EventSummary, InputEvent};
23
24#[derive(Copy, Clone, Eq, PartialEq, Hash)]
25#[repr(transparent)]
26/// A bookkeeping event. Usually not important to applications.
27/// [`EventType::SYNCHRONIZATION`]
28pub struct SynchronizationEvent(InputEvent);
29
30#[derive(Copy, Clone, Eq, PartialEq, Hash)]
31#[repr(transparent)]
32/// [`EventType::KEY`]
33pub struct KeyEvent(InputEvent);
34
35#[derive(Copy, Clone, Eq, PartialEq, Hash)]
36#[repr(transparent)]
37/// [`EventType::RELATIVE`]
38pub struct RelativeAxisEvent(InputEvent);
39
40#[derive(Copy, Clone, Eq, PartialEq, Hash)]
41#[repr(transparent)]
42/// [`EventType::ABSOLUTE`]
43pub struct AbsoluteAxisEvent(InputEvent);
44
45#[derive(Copy, Clone, Eq, PartialEq, Hash)]
46#[repr(transparent)]
47/// [`EventType::MISC`]
48pub struct MiscEvent(InputEvent);
49
50#[derive(Copy, Clone, Eq, PartialEq, Hash)]
51#[repr(transparent)]
52/// [`EventType::SWITCH`]
53pub struct SwitchEvent(InputEvent);
54
55#[derive(Copy, Clone, Eq, PartialEq, Hash)]
56#[repr(transparent)]
57/// [`EventType::LED`]
58pub struct LedEvent(InputEvent);
59#[derive(Copy, Clone, Eq, PartialEq, Hash)]
60#[repr(transparent)]
61/// [`EventType::SOUND`]
62pub struct SoundEvent(InputEvent);
63
64#[derive(Copy, Clone, Eq, PartialEq, Hash)]
65#[repr(transparent)]
66/// [`EventType::REPEAT`]
67pub struct RepeatEvent(InputEvent);
68
69#[derive(Copy, Clone, Eq, PartialEq, Hash)]
70#[repr(transparent)]
71/// [`EventType::FORCEFEEDBACK`]
72pub struct FFEvent(InputEvent);
73
74#[derive(Copy, Clone, Eq, PartialEq, Hash)]
75#[repr(transparent)]
76/// [`EventType::POWER`]
77pub struct PowerEvent(InputEvent);
78
79#[derive(Copy, Clone, Eq, PartialEq, Hash)]
80#[repr(transparent)]
81/// [`EventType::FORCEFEEDBACKSTATUS`]
82pub struct FFStatusEvent(InputEvent);
83
84#[derive(Copy, Clone, Eq, PartialEq, Hash)]
85#[repr(transparent)]
86/// [`EventType::UINPUT`]
87pub struct UInputEvent(InputEvent);
88
89#[derive(Copy, Clone, Eq, PartialEq, Hash)]
90#[repr(transparent)]
91/// An event not covered by any other variant.
92pub struct OtherEvent(pub(crate) InputEvent);
93
94macro_rules! input_event_newtype {
95    ($name:ty) => {
96        impl AsRef<input_event> for $name {
97            fn as_ref(&self) -> &input_event {
98                &self.0.as_ref()
99            }
100        }
101        impl AsRef<InputEvent> for $name {
102            fn as_ref(&self) -> &InputEvent {
103                &self.0
104            }
105        }
106        // never implement the other direction!
107        impl From<$name> for InputEvent {
108            fn from(event: $name) -> Self {
109                event.0
110            }
111        }
112        impl Deref for $name {
113            type Target = InputEvent;
114            fn deref(&self) -> &InputEvent {
115                &self.0
116            }
117        }
118    };
119    ($name:ty, $evdev_type:path, $kind:path) => {
120        impl $name {
121            pub fn new($kind(code): $kind, value: i32) -> Self {
122                let raw = input_event {
123                    time: libc::timeval {
124                        tv_sec: 0,
125                        tv_usec: 0,
126                    },
127                    type_: $evdev_type.0,
128                    code,
129                    value,
130                };
131                Self::from_raw(raw)
132            }
133            pub fn new_now($kind(code): $kind, value: i32) -> Self {
134                let raw = input_event {
135                    time: systime_to_timeval(&SystemTime::now()),
136                    type_: $evdev_type.0,
137                    code,
138                    value,
139                };
140                Self::from_raw(raw)
141            }
142            pub fn destructure(&self) -> ($kind, i32) {
143                (self.code(), self.value())
144            }
145            pub fn code(&self) -> $kind {
146                $kind(self.0.code())
147            }
148            // must be kept internal
149            fn from_raw(raw: input_event) -> Self {
150                match EventType(raw.type_) {
151                    $evdev_type => Self(InputEvent(raw)),
152                    _ => unreachable!(),
153                }
154            }
155            // must be kept internal
156            pub(crate) fn from_event(event: InputEvent) -> Self {
157                match event.event_type() {
158                    $evdev_type => Self(event),
159                    _ => unreachable!(),
160                }
161            }
162        }
163        impl fmt::Debug for $name {
164            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
165                let mut debug = f.debug_struct(stringify!($name));
166                debug.field("time", &self.timestamp());
167                debug.field("code", &self.code());
168                debug.field("value", &self.value()).finish()
169            }
170        }
171        input_event_newtype!($name);
172    };
173    ($name:ty, $evdev_type:path, $kind:path, $summary:path) => {
174        impl From<$name> for EventSummary {
175            fn from(event: $name) -> EventSummary {
176                let (kind, value) = event.destructure();
177                $summary(event, kind, value)
178            }
179        }
180
181        input_event_newtype!($name, $evdev_type, $kind);
182    };
183}
184input_event_newtype!(
185    SynchronizationEvent,
186    EventType::SYNCHRONIZATION,
187    SynchronizationCode,
188    EventSummary::Synchronization
189);
190input_event_newtype!(KeyEvent, EventType::KEY, KeyCode, EventSummary::Key);
191input_event_newtype!(
192    RelativeAxisEvent,
193    EventType::RELATIVE,
194    RelativeAxisCode,
195    EventSummary::RelativeAxis
196);
197input_event_newtype!(
198    AbsoluteAxisEvent,
199    EventType::ABSOLUTE,
200    AbsoluteAxisCode,
201    EventSummary::AbsoluteAxis
202);
203input_event_newtype!(MiscEvent, EventType::MISC, MiscCode, EventSummary::Misc);
204input_event_newtype!(
205    SwitchEvent,
206    EventType::SWITCH,
207    SwitchCode,
208    EventSummary::Switch
209);
210input_event_newtype!(LedEvent, EventType::LED, LedCode, EventSummary::Led);
211input_event_newtype!(SoundEvent, EventType::SOUND, SoundCode, EventSummary::Sound);
212input_event_newtype!(
213    RepeatEvent,
214    EventType::REPEAT,
215    RepeatCode,
216    EventSummary::Repeat
217);
218input_event_newtype!(
219    FFEvent,
220    EventType::FORCEFEEDBACK,
221    FFEffectCode,
222    EventSummary::ForceFeedback
223);
224input_event_newtype!(PowerEvent, EventType::POWER, PowerCode, EventSummary::Power);
225input_event_newtype!(
226    FFStatusEvent,
227    EventType::FORCEFEEDBACKSTATUS,
228    FFStatusCode,
229    EventSummary::ForceFeedbackStatus
230);
231input_event_newtype!(
232    UInputEvent,
233    EventType::UINPUT,
234    UInputCode,
235    EventSummary::UInput
236);
237input_event_newtype!(OtherEvent);
238
239impl OtherEvent {
240    pub fn kind(&self) -> OtherCode {
241        OtherCode(self.event_type().0, self.code())
242    }
243    pub fn destructure(&self) -> (OtherCode, i32) {
244        (self.kind(), self.value())
245    }
246}
247impl From<OtherEvent> for EventSummary {
248    fn from(event: OtherEvent) -> Self {
249        let (kind, value) = event.destructure();
250        EventSummary::Other(event, kind, value)
251    }
252}
253impl fmt::Debug for OtherEvent {
254    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
255        let mut debug = f.debug_struct("OtherEvent");
256        debug.field("time", &self.timestamp());
257        debug.field("type", &self.event_type());
258        debug.field("code", &self.code());
259        debug.field("value", &self.value()).finish()
260    }
261}