qsk/device/
linux.rs

1use std::convert::TryFrom;
2use std::fs::File;
3use std::path::PathBuf;
4use std::sync::Arc;
5use std::sync::Mutex;
6use std::time::{Duration, SystemTime, UNIX_EPOCH};
7
8use evdev_rs;
9use evdev_rs::enums;
10use evdev_rs::GrabMode;
11use evdev_rs::TimeVal;
12use log::error;
13
14use crate::errors::Error;
15use crate::errors::Result;
16
17use crate::events;
18use crate::events::{EventCode, KeyCode, KeyState, SynCode};
19use crate::device::traits::{InputEventSink, InputEventSource};
20
21pub struct InputEvent(events::InputEvent);
22
23pub struct Device {
24    inner: Arc<Mutex<evdev_rs::Device>>,
25}
26
27unsafe impl Send for Device {}
28
29impl TryFrom<evdev_rs::InputEvent> for InputEvent {
30    type Error = Error;
31
32    fn try_from(ev: evdev_rs::InputEvent) -> Result<InputEvent> {
33        let c = match ev.event_code {
34            enums::EventCode::EV_KEY(ref ec) => {
35                let kc: Option<KeyCode> = num::FromPrimitive::from_u16(ec.clone() as u16);
36                match kc {
37                    Some(code) => Some(EventCode::KeyCode(code)),
38                    None => None,
39                }
40            }
41            enums::EventCode::EV_SYN(ref ec) => {
42                let sc: Option<SynCode> = num::FromPrimitive::from_u16(ec.clone() as u16);
43                match sc {
44                    Some(code) => Some(EventCode::SynCode(code)),
45                    None => None,
46                }
47            }
48            _ => None,
49        };
50        match c {
51            Some(code) => Ok(InputEvent(events::InputEvent {
52                time: UNIX_EPOCH
53                    + Duration::new(ev.time.tv_sec as u64, ev.time.tv_usec as u32 * 1000 as u32),
54                code,
55                state: i32_into_ks(ev.value),
56            })),
57            None => Err(Error::UnrecognizedEvdevRSInputEvent { e: ev }),
58        }
59    }
60}
61
62impl TryFrom<InputEvent> for evdev_rs::InputEvent {
63    type Error = Error;
64
65    fn try_from(ie: InputEvent) -> Result<evdev_rs::InputEvent> {
66        let c = match ie.0.code {
67            EventCode::KeyCode(c) => match enums::int_to_ev_key(c as u32) {
68                Some(key) => Some(enums::EventCode::EV_KEY(key)),
69                None => None,
70            },
71            EventCode::SynCode(c) => match enums::int_to_ev_syn(c as u32) {
72                Some(key) => Some(enums::EventCode::EV_SYN(key)),
73                None => None,
74            },
75        };
76
77        let d = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
78        match c {
79            Some(event_code) => Ok(evdev_rs::InputEvent {
80                time: TimeVal {
81                    tv_sec: d.as_secs() as i64,
82                    tv_usec: d.subsec_micros() as i64,
83                },
84                event_code,
85                value: ie.0.state as i32,
86            }),
87            None => Err(Error::UnrecognizedInputEvent { e: ie.0 }),
88        }
89    }
90}
91
92impl Device {
93    pub fn from_path(path: PathBuf) -> Result<Device> {
94        let f = File::open(path)?;
95        let mut d = evdev_rs::Device::new_from_file(f).unwrap();
96        d.grab(GrabMode::Grab)?;
97        Ok(Device {
98            inner: Arc::new(Mutex::new(d)),
99        })
100    }
101
102    pub fn new_uinput_device(&self) -> Result<UInputDevice> {
103        let guard = match self.inner.lock() {
104            Ok(a) => a,
105            Err(p_err) => {
106                let g = p_err.into_inner();
107                error!("recovered Device");
108                g
109            }
110        };
111        let d = evdev_rs::UInputDevice::create_from_device(&*guard)?;
112        Ok(UInputDevice {
113            inner: Arc::new(Mutex::new(d)),
114        })
115    }
116}
117
118impl InputEventSource for Device {
119    fn recv(&mut self) -> Result<events::InputEvent> {
120        let guard = match self.inner.lock() {
121            Ok(a) => a,
122            Err(p_err) => {
123                let g = p_err.into_inner();
124                error!("recovered Device");
125                g
126            }
127        };
128        match guard.next_event(evdev_rs::ReadFlag::NORMAL | evdev_rs::ReadFlag::BLOCKING) {
129            Ok(ev) => match InputEvent::try_from(ev.1) {
130                Ok(ie) => Ok(ie.0),
131                Err(e) => Err(e),
132            },
133            Err(e) => Err(Error::IO(e)),
134        }
135    }
136}
137
138pub struct UInputDevice {
139    inner: Arc<Mutex<evdev_rs::UInputDevice>>,
140}
141
142unsafe impl Send for UInputDevice {}
143
144impl InputEventSink for UInputDevice {
145    fn send(&mut self, e: events::InputEvent) -> Result<()> {
146        let guard = match self.inner.lock() {
147            Ok(a) => a,
148            Err(p_err) => {
149                let g = p_err.into_inner();
150                error!("recovered Device");
151                g
152            }
153        };
154
155        let ie = evdev_rs::InputEvent::try_from(InputEvent(e))?;
156        match guard.write_event(&ie) {
157            Ok(_) => (),
158            Err(e) => return Err(Error::IO(e)),
159        };
160        let t: TimeVal;
161        match TimeVal::try_from(e.time) {
162            Ok(tv) => t = tv,
163            Err(e) => return Err(Error::SystemTimeError(e)),
164        }
165        match guard.write_event(&evdev_rs::InputEvent {
166            time: t,
167            event_code: enums::EventCode::EV_SYN(enums::EV_SYN::SYN_REPORT),
168            value: 0,
169        }) {
170            Ok(_) => return Ok(()),
171            Err(e) => return Err(Error::IO(e)),
172        }
173    }
174}
175
176fn i32_into_ks(i: i32) -> KeyState {
177    match i {
178        0 => KeyState::Up,
179        1 => KeyState::Down,
180        2 => KeyState::Held,
181        _ => KeyState::NotImplemented,
182    }
183}