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}