evdev_rs_tokio/
util.rs

1use crate::enums::*;
2use libc::{c_char, c_uint};
3use log::warn;
4use std::ffi::{CStr, CString};
5use std::fmt;
6
7use evdev_sys as raw;
8
9pub(crate) unsafe fn ptr_to_str(ptr: *const c_char) -> Option<&'static str> {
10    let slice = CStr::from_ptr(ptr.as_ref()?);
11    let buf = slice.to_bytes();
12    std::str::from_utf8(buf).ok()
13}
14
15pub struct EventTypeIterator {
16    current: EventType,
17}
18
19pub struct EventCodeIterator {
20    current: EventCode,
21}
22
23pub struct InputPropIterator {
24    current: InputProp,
25}
26
27pub fn event_code_to_int(event_code: &EventCode) -> (c_uint, c_uint) {
28    match *event_code {
29        EventCode::EV_SYN(code) => (EventType::EV_SYN as c_uint, code as c_uint),
30        EventCode::EV_KEY(code) => (EventType::EV_KEY as c_uint, code as c_uint),
31        EventCode::EV_REL(code) => (EventType::EV_REL as c_uint, code as c_uint),
32        EventCode::EV_ABS(code) => (EventType::EV_ABS as c_uint, code as c_uint),
33        EventCode::EV_MSC(code) => (EventType::EV_MSC as c_uint, code as c_uint),
34        EventCode::EV_SW(code) => (EventType::EV_SW as c_uint, code as c_uint),
35        EventCode::EV_LED(code) => (EventType::EV_LED as c_uint, code as c_uint),
36        EventCode::EV_SND(code) => (EventType::EV_SND as c_uint, code as c_uint),
37        EventCode::EV_REP(code) => (EventType::EV_REP as c_uint, code as c_uint),
38        EventCode::EV_FF(code) => (EventType::EV_FF as c_uint, code as c_uint),
39        EventCode::EV_FF_STATUS(code) => {
40            (EventType::EV_FF_STATUS as c_uint, code as c_uint)
41        }
42        EventCode::EV_UNK {
43            event_type,
44            event_code,
45        } => (event_type as c_uint, event_code as c_uint),
46        _ => {
47            warn!("Event code not found");
48            (0, 0)
49        }
50    }
51}
52
53pub fn int_to_event_code(event_type: c_uint, event_code: c_uint) -> EventCode {
54    let ev_type: EventType = int_to_event_type(event_type as u32).unwrap();
55    let code = event_code as u32;
56
57    let ev_code = match ev_type {
58        EventType::EV_SYN => int_to_ev_syn(code).map(EventCode::EV_SYN),
59        EventType::EV_KEY => int_to_ev_key(code).map(EventCode::EV_KEY),
60        EventType::EV_ABS => int_to_ev_abs(code).map(EventCode::EV_ABS),
61        EventType::EV_REL => int_to_ev_rel(code).map(EventCode::EV_REL),
62        EventType::EV_MSC => int_to_ev_msc(code).map(EventCode::EV_MSC),
63        EventType::EV_SW => int_to_ev_sw(code).map(EventCode::EV_SW),
64        EventType::EV_LED => int_to_ev_led(code).map(EventCode::EV_LED),
65        EventType::EV_SND => int_to_ev_snd(code).map(EventCode::EV_SND),
66        EventType::EV_REP => int_to_ev_rep(code).map(EventCode::EV_REP),
67        EventType::EV_FF => int_to_ev_ff(code).map(EventCode::EV_FF),
68        EventType::EV_PWR => Some(EventCode::EV_PWR),
69        EventType::EV_FF_STATUS => int_to_ev_ff(code).map(EventCode::EV_FF_STATUS),
70        EventType::EV_UNK => None,
71        EventType::EV_MAX => Some(EventCode::EV_MAX),
72    };
73
74    ev_code.unwrap_or(EventCode::EV_UNK {
75        event_type,
76        event_code,
77    })
78}
79
80impl fmt::Display for EventType {
81    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82        write!(
83            f,
84            "{}",
85            unsafe { ptr_to_str(raw::libevdev_event_type_get_name(*self as c_uint)) }
86                .unwrap_or("")
87        )
88    }
89}
90
91impl fmt::Display for EventCode {
92    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93        let (ev_type, ev_code) = event_code_to_int(self);
94        write!(
95            f,
96            "{}",
97            unsafe { ptr_to_str(raw::libevdev_event_code_get_name(ev_type, ev_code)) }
98                .unwrap_or("")
99        )
100    }
101}
102
103impl fmt::Display for InputProp {
104    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105        write!(
106            f,
107            "{}",
108            unsafe { ptr_to_str(raw::libevdev_property_get_name(*self as c_uint)) }
109                .unwrap_or("")
110        )
111    }
112}
113
114impl EventType {
115    pub fn iter(&self) -> EventTypeIterator {
116        EventTypeIterator { current: *self }
117    }
118
119    /// The given type constant for the passed name or Errno if not found.
120    pub fn from_str(name: &str) -> Option<EventType> {
121        let name = CString::new(name).unwrap();
122        let result = unsafe { raw::libevdev_event_type_from_name(name.as_ptr()) };
123
124        match result {
125            -1 => None,
126            k => int_to_event_type(k as u32),
127        }
128    }
129
130    /// The max value defined for the given event type, e.g. ABS_MAX for a type
131    /// of EV_ABS, or Errno for an invalid type.
132    pub fn get_max(ev_type: &EventType) -> Option<i32> {
133        let result = unsafe { raw::libevdev_event_type_get_max(*ev_type as c_uint) };
134
135        match result {
136            -1 => None,
137            k => Some(k),
138        }
139    }
140}
141
142impl EventCode {
143    pub fn iter(&self) -> EventCodeIterator {
144        EventCodeIterator { current: *self }
145    }
146
147    /// Look up an event code by its type and name. Event codes start with a fixed
148    /// prefix followed by their name (eg., "ABS_X"). The prefix must be included in
149    /// the name. It returns the constant assigned to the event code or Errno if not
150    /// found.
151    pub fn from_str(ev_type: &EventType, name: &str) -> Option<EventCode> {
152        let name = CString::new(name).unwrap();
153        let result = unsafe {
154            raw::libevdev_event_code_from_name(*ev_type as c_uint, name.as_ptr())
155        };
156
157        match result {
158            -1 => None,
159            k => Some(int_to_event_code(*ev_type as u32, k as u32)),
160        }
161    }
162}
163
164impl InputProp {
165    pub fn iter(&self) -> InputPropIterator {
166        InputPropIterator { current: *self }
167    }
168
169    /// Look up an input property by its name. Properties start with the fixed
170    /// prefix "INPUT_PROP_" followed by their name (eg., "INPUT_PROP_POINTER").
171    /// The prefix must be included in the name. It returns the constant assigned
172    /// to the property or Errno if not found.
173    pub fn from_str(name: &str) -> Option<InputProp> {
174        let name = CString::new(name).unwrap();
175        let result = unsafe { raw::libevdev_property_from_name(name.as_ptr()) };
176
177        match result {
178            -1 => None,
179            k => int_to_input_prop(k as u32),
180        }
181    }
182}
183
184// Iterator trait for the enum iterators
185impl Iterator for EventTypeIterator {
186    type Item = EventType;
187
188    fn next(&mut self) -> Option<EventType> {
189        match self.current {
190            EventType::EV_MAX => None,
191            _ => {
192                let mut raw_code = (self.current as u32) + 1;
193                loop {
194                    match int_to_event_type(raw_code) {
195                        // TODO: Find a way to iterate over Unknown types
196                        Some(EventType::EV_UNK) => raw_code += 1,
197                        Some(x) => {
198                            let code = self.current;
199                            self.current = x;
200                            return Some(code);
201                        }
202                        None => raw_code += 1,
203                    }
204                }
205            }
206        }
207    }
208}
209
210impl Iterator for EventCodeIterator {
211    type Item = EventCode;
212
213    fn next(&mut self) -> Option<EventCode> {
214        match self.current {
215            EventCode::EV_SYN(code) => match code {
216                EV_SYN::SYN_MAX => {
217                    let ev_code = self.current;
218                    self.current = EventCode::EV_KEY(EV_KEY::KEY_RESERVED);
219                    Some(ev_code)
220                }
221                _ => {
222                    let mut raw_code = (code as u32) + 1;
223                    loop {
224                        match int_to_ev_syn(raw_code) {
225                            Some(x) => {
226                                let ev_code = self.current;
227                                self.current = EventCode::EV_SYN(x);
228                                return Some(ev_code);
229                            }
230                            None => raw_code += 1,
231                        }
232                    }
233                }
234            },
235            EventCode::EV_KEY(code) => match code {
236                EV_KEY::KEY_MAX => {
237                    let ev_code = self.current;
238                    self.current = EventCode::EV_REL(EV_REL::REL_X);
239                    Some(ev_code)
240                }
241                _ => {
242                    let mut raw_code = (code as u32) + 1;
243                    loop {
244                        match int_to_ev_key(raw_code) {
245                            Some(x) => {
246                                let ev_code = self.current;
247                                self.current = EventCode::EV_KEY(x);
248                                return Some(ev_code);
249                            }
250                            None => raw_code += 1,
251                        }
252                    }
253                }
254            },
255            EventCode::EV_REL(code) => match code {
256                EV_REL::REL_MAX => {
257                    let ev_code = self.current;
258                    self.current = EventCode::EV_ABS(EV_ABS::ABS_X);
259                    Some(ev_code)
260                }
261                _ => {
262                    let mut raw_code = (code as u32) + 1;
263                    loop {
264                        match int_to_ev_rel(raw_code) {
265                            Some(x) => {
266                                let ev_code = self.current;
267                                self.current = EventCode::EV_REL(x);
268                                return Some(ev_code);
269                            }
270                            None => raw_code += 1,
271                        }
272                    }
273                }
274            },
275            EventCode::EV_ABS(code) => match code {
276                EV_ABS::ABS_MAX => {
277                    let ev_code = self.current;
278                    self.current = EventCode::EV_MSC(EV_MSC::MSC_SERIAL);
279                    Some(ev_code)
280                }
281                _ => {
282                    let mut raw_code = (code as u32) + 1;
283                    loop {
284                        match int_to_ev_abs(raw_code) {
285                            Some(x) => {
286                                let ev_code = self.current;
287                                self.current = EventCode::EV_ABS(x);
288                                return Some(ev_code);
289                            }
290                            None => raw_code += 1,
291                        }
292                    }
293                }
294            },
295            EventCode::EV_MSC(code) => match code {
296                EV_MSC::MSC_MAX => {
297                    let ev_code = self.current;
298                    self.current = EventCode::EV_SW(EV_SW::SW_LID);
299                    Some(ev_code)
300                }
301                _ => {
302                    let mut raw_code = (code as u32) + 1;
303                    loop {
304                        match int_to_ev_msc(raw_code) {
305                            Some(x) => {
306                                let ev_code = self.current;
307                                self.current = EventCode::EV_MSC(x);
308                                return Some(ev_code);
309                            }
310                            None => raw_code += 1,
311                        }
312                    }
313                }
314            },
315            EventCode::EV_SW(code) => match code {
316                EV_SW::SW_MAX => {
317                    let ev_code = self.current;
318                    self.current = EventCode::EV_LED(EV_LED::LED_NUML);
319                    Some(ev_code)
320                }
321                _ => {
322                    let mut raw_code = (code as u32) + 1;
323                    loop {
324                        match int_to_ev_sw(raw_code) {
325                            Some(x) => {
326                                let ev_code = self.current;
327                                self.current = EventCode::EV_SW(x);
328                                return Some(ev_code);
329                            }
330                            None => raw_code += 1,
331                        }
332                    }
333                }
334            },
335            EventCode::EV_LED(code) => match code {
336                EV_LED::LED_MAX => {
337                    let ev_code = self.current;
338                    self.current = EventCode::EV_SND(EV_SND::SND_CLICK);
339                    Some(ev_code)
340                }
341                _ => {
342                    let mut raw_code = (code as u32) + 1;
343                    loop {
344                        match int_to_ev_led(raw_code) {
345                            Some(x) => {
346                                let ev_code = self.current;
347                                self.current = EventCode::EV_LED(x);
348                                return Some(ev_code);
349                            }
350                            None => raw_code += 1,
351                        }
352                    }
353                }
354            },
355            EventCode::EV_SND(code) => match code {
356                EV_SND::SND_MAX => {
357                    let ev_code = self.current;
358                    self.current = EventCode::EV_REP(EV_REP::REP_DELAY);
359                    Some(ev_code)
360                }
361                _ => {
362                    let mut raw_code = (code as u32) + 1;
363                    loop {
364                        match int_to_ev_snd(raw_code) {
365                            Some(x) => {
366                                let ev_code = self.current;
367                                self.current = EventCode::EV_SND(x);
368                                return Some(ev_code);
369                            }
370                            None => raw_code += 1,
371                        }
372                    }
373                }
374            },
375            EventCode::EV_REP(code) => match code {
376                EV_REP::REP_MAX => {
377                    let ev_code = self.current;
378                    self.current = EventCode::EV_FF(EV_FF::FF_STATUS_STOPPED);
379                    Some(ev_code)
380                }
381                _ => {
382                    let mut raw_code = (code as u32) + 1;
383                    loop {
384                        match int_to_ev_rep(raw_code) {
385                            Some(x) => {
386                                let ev_code = self.current;
387                                self.current = EventCode::EV_REP(x);
388                                return Some(ev_code);
389                            }
390                            None => raw_code += 1,
391                        }
392                    }
393                }
394            },
395            EventCode::EV_FF(code) => match code {
396                EV_FF::FF_MAX => None,
397                _ => {
398                    let mut raw_code = (code as u32) + 1;
399                    loop {
400                        match int_to_ev_ff(raw_code) {
401                            Some(x) => {
402                                let ev_code = self.current;
403                                self.current = EventCode::EV_FF(x);
404                                return Some(ev_code);
405                            }
406                            None => raw_code += 1,
407                        }
408                    }
409                }
410            },
411            _ => None,
412        }
413    }
414}
415
416impl Iterator for InputPropIterator {
417    type Item = InputProp;
418
419    fn next(&mut self) -> Option<InputProp> {
420        match self.current {
421            InputProp::INPUT_PROP_MAX => None,
422            _ => {
423                let mut raw_enum = (self.current as u32) + 1;
424                loop {
425                    match int_to_input_prop(raw_enum) {
426                        Some(x) => {
427                            let prop = self.current;
428                            self.current = x;
429                            return Some(prop);
430                        }
431                        None => raw_enum += 1,
432                    }
433                }
434            }
435        }
436    }
437}