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