qsk/device/
linux_evdev.rs1use futures::executor::block_on;
2use std::convert::TryFrom;
3use std::path::PathBuf;
4
5use evdev;
6use evdev::uinput;
7
8use crate::errors::{Error, Result};
9use crate::events;
10use crate::events::{EventCode, KeyCode, KeyState, SynCode};
11use crate::device::traits::{InputEventSink, InputEventSource};
12
13pub struct InputEvent(events::InputEvent);
14
15pub struct Device {
16 inner: evdev::EventStream,
17}
18
19impl Device {
20 pub fn from_path(path: PathBuf) -> Result<Device> {
21 let mut d = evdev::Device::open(&path)?;
22 d.grab()?;
23 Ok(Device {
24 inner: d.into_event_stream()?,
25 })
26 }
27
28 pub fn from_evdev_device(mut d: evdev::Device) -> Result<Device> {
29 d.grab()?;
30 Ok(Device {
31 inner: d.into_event_stream()?,
32 })
33 }
34
35 pub fn new_uinput_device(&self, name: String) -> Result<UInputDevice> {
36 let mut vdb = uinput::VirtualDeviceBuilder::new()?;
37 vdb = vdb.name(&name);
38 if let Some(sks) = self.inner.device().supported_keys() {
39 vdb = vdb.with_keys(sks)?;
40 } else {
41 return Err(Error::NoSupportedKeys);
42 }
43 Ok(UInputDevice {
44 inner: vdb.build()?,
45 })
46 }
47
48 pub fn list() -> Result<()> {
49 for (path, dev) in evdev::enumerate() {
50 if let Some(keys) = dev.supported_keys() {
51 let mut key_count = 0;
52 for _key in keys.iter() {
53 key_count += 1;
55 }
56 if key_count > 100 {
57 println!("{}", dev.name().unwrap_or("unknown"));
58 println!(" key_count: {}", key_count);
59 println!(
60 " physical path: {}",
61 dev.physical_path().unwrap_or("unknown")
62 );
63 println!(" system path: {}", path.display());
64 }
65 }
66 }
67 Ok(())
68 }
69}
70
71impl TryFrom<evdev::InputEvent> for InputEvent {
72 type Error = Error;
73
74 fn try_from(ev: evdev::InputEvent) -> Result<InputEvent> {
75 let ec = match ev.event_type() {
76 evdev::EventType::KEY => {
77 let kc: Option<KeyCode> = num::FromPrimitive::from_u16(ev.code() as u16);
78 match kc {
79 Some(code) => Some(EventCode::KeyCode(code)),
80 None => None,
81 }
82 }
83 evdev::EventType::SYNCHRONIZATION => {
84 let kc: Option<SynCode> = num::FromPrimitive::from_u16(ev.code() as u16);
85 match kc {
86 Some(code) => Some(EventCode::SynCode(code)),
87 None => None,
88 }
89 }
90 _ => None,
91 };
92 match ec {
93 Some(code) => Ok(InputEvent( events::InputEvent {
94 time: ev.timestamp(),
95 code,
96 state: i32_into_ks(ev.value()),
97 })),
98 None => Err(Error::UnrecognizedEvdevInputEvent { e: ev }),
99 }
100 }
101}
102
103impl TryFrom<InputEvent> for evdev::InputEvent {
104 type Error = Error;
105
106 fn try_from(ie: InputEvent) -> Result<evdev::InputEvent> {
107 let (ty, code) = match ie.0.code {
108 EventCode::KeyCode(c) => (evdev::EventType::SYNCHRONIZATION, c as i16),
109 EventCode::SynCode(c) => (evdev::EventType::KEY, c as i16),
110 };
111 Ok(evdev::InputEvent::new(ty, code as u16, ie.0.state as i32))
112 }
113}
114
115impl InputEventSource for Device {
116 fn recv(&mut self) -> Result<events::InputEvent> {
117 let ev = block_on(self.inner.next_event())?;
118 Ok(InputEvent::try_from(ev)?.0)
119 }
120}
121
122fn i32_into_ks(i: i32) -> KeyState {
123 match i {
124 0 => KeyState::Up,
125 1 => KeyState::Down,
126 2 => KeyState::Held,
127 _ => KeyState::NotImplemented,
128 }
129}
130
131pub struct UInputDevice {
132 inner: evdev::uinput::VirtualDevice,
133}
134
135impl InputEventSink for UInputDevice {
136 fn send(&mut self, ie: events::InputEvent) -> Result<()> {
137 let evdev_ie = evdev::InputEvent::try_from(InputEvent(ie))?;
138 self.inner.emit(&[evdev_ie])?;
139 Ok(())
140 }
141}