1use 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)]
26pub struct SynchronizationEvent(InputEvent);
29
30#[derive(Copy, Clone, Eq, PartialEq, Hash)]
31#[repr(transparent)]
32pub struct KeyEvent(InputEvent);
34
35#[derive(Copy, Clone, Eq, PartialEq, Hash)]
36#[repr(transparent)]
37pub struct RelativeAxisEvent(InputEvent);
39
40#[derive(Copy, Clone, Eq, PartialEq, Hash)]
41#[repr(transparent)]
42pub struct AbsoluteAxisEvent(InputEvent);
44
45#[derive(Copy, Clone, Eq, PartialEq, Hash)]
46#[repr(transparent)]
47pub struct MiscEvent(InputEvent);
49
50#[derive(Copy, Clone, Eq, PartialEq, Hash)]
51#[repr(transparent)]
52pub struct SwitchEvent(InputEvent);
54
55#[derive(Copy, Clone, Eq, PartialEq, Hash)]
56#[repr(transparent)]
57pub struct LedEvent(InputEvent);
59#[derive(Copy, Clone, Eq, PartialEq, Hash)]
60#[repr(transparent)]
61pub struct SoundEvent(InputEvent);
63
64#[derive(Copy, Clone, Eq, PartialEq, Hash)]
65#[repr(transparent)]
66pub struct RepeatEvent(InputEvent);
68
69#[derive(Copy, Clone, Eq, PartialEq, Hash)]
70#[repr(transparent)]
71pub struct FFEvent(InputEvent);
73
74#[derive(Copy, Clone, Eq, PartialEq, Hash)]
75#[repr(transparent)]
76pub struct PowerEvent(InputEvent);
78
79#[derive(Copy, Clone, Eq, PartialEq, Hash)]
80#[repr(transparent)]
81pub struct FFStatusEvent(InputEvent);
83
84#[derive(Copy, Clone, Eq, PartialEq, Hash)]
85#[repr(transparent)]
86pub struct UInputEvent(InputEvent);
88
89#[derive(Copy, Clone, Eq, PartialEq, Hash)]
90#[repr(transparent)]
91pub 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 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 fn from_raw(raw: input_event) -> Self {
150 match EventType(raw.type_) {
151 $evdev_type => Self(InputEvent(raw)),
152 _ => unreachable!(),
153 }
154 }
155 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}