use evdev::{Device as EvDevice, EventType, InputEventKind}; use std::{collections::HashMap, path::PathBuf}; pub struct Device { device: EvDevice, path: PathBuf, supported_events: HashMap<EventType, Vec<InputEventKind>>, } impl Device { pub fn query() -> Vec<Device> { evdev::enumerate() .map(|(path, device)| { let supported_events = device .supported_events() .iter() .map(|event| { let input_kind: Vec<InputEventKind> = match event { evdev::EventType::KEY => device .supported_keys() .map(|keys| { keys.iter().map(|key| InputEventKind::Key(key)).collect() }) .unwrap_or(Vec::new()), evdev::EventType::RELATIVE => device .supported_relative_axes() .map(|axes| { axes.iter() .map(|rel_axis| InputEventKind::RelAxis(rel_axis)) .collect() }) .unwrap_or(Vec::new()), evdev::EventType::ABSOLUTE => device .supported_absolute_axes() .map(|axes| { axes.iter() .map(|abs_axis| InputEventKind::AbsAxis(abs_axis)) .collect() }) .unwrap_or(Vec::new()), evdev::EventType::SWITCH => device .supported_switches() .map(|switches| { switches .iter() .map(|switch| InputEventKind::Switch(switch)) .collect() }) .unwrap_or(Vec::new()), evdev::EventType::MISC => device .misc_properties() .map(|miscs| { miscs .iter() .map(|misc| InputEventKind::Misc(misc)) .collect() }) .unwrap_or(Vec::new()), evdev::EventType::SOUND => device .supported_sounds() .map(|sounds| { sounds .iter() .map(|sound| InputEventKind::Sound(sound)) .collect() }) .unwrap_or(Vec::new()), evdev::EventType::FORCEFEEDBACK => device .supported_forcefeedback_effects() .map(|ffs| { ffs.iter() .map(|ff| InputEventKind::ForceFeedback(ff)) .collect() }) .unwrap_or(Vec::new()), _ => Vec::new(), }; (event, input_kind) }) .collect(); Device { device, path, supported_events, } }) .collect() } } impl std::fmt::Debug for Device { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Device") .field("name", &self.device.name()) .field("path", &self.path) .field("supported_events", &self.supported_events) .finish() } }