qsk/device/
linux_evdev.rs

1use 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                    //println!("  key: {:?}", key);
54                    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}