From 283e438d1b08dff97a78c74391f50e243ee16051 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Tue, 12 Mar 2024 16:37:16 +0100 Subject: [PATCH] backend: add syspath and devnode to input devices --- src/backend.rs | 3 ++ src/backends/metal.rs | 6 ++- src/backends/metal/monitor.rs | 2 +- src/backends/x.rs | 8 ++++ src/state.rs | 2 + src/tasks.rs | 1 + src/tasks/drmdev.rs | 70 ++++------------------------------ src/tasks/input_device.rs | 7 ++++ src/tasks/udev_utils.rs | 72 +++++++++++++++++++++++++++++++++++ 9 files changed, 107 insertions(+), 64 deletions(-) create mode 100644 src/tasks/udev_utils.rs diff --git a/src/backend.rs b/src/backend.rs index 1e2119b4..704f31b3 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -135,6 +135,9 @@ pub trait InputDevice { } fn set_transform_matrix(&self, matrix: TransformMatrix); fn name(&self) -> Rc; + fn dev_t(&self) -> Option { + None + } fn tap_enabled(&self) -> Option { None } diff --git a/src/backends/metal.rs b/src/backends/metal.rs index 0f11d34c..d4fbfd80 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -281,7 +281,7 @@ pub async fn create(state: &Rc) -> Result, MetalError> { struct MetalInputDevice { slot: usize, id: InputDeviceId, - _devnum: c::dev_t, + devnum: c::dev_t, fd: CloneCell>>, inputdev: CloneCell>>, devnode: CString, @@ -509,6 +509,10 @@ impl InputDevice for MetalInputDevice { self.name.get() } + fn dev_t(&self) -> Option { + Some(self.devnum) + } + fn set_tap_enabled(&self, enabled: bool) { self.desired.tap_enabled.set(Some(enabled)); if let Some(dev) = self.inputdev.get() { diff --git a/src/backends/metal/monitor.rs b/src/backends/metal/monitor.rs index 3f20e07b..425c5a11 100644 --- a/src/backends/metal/monitor.rs +++ b/src/backends/metal/monitor.rs @@ -278,7 +278,7 @@ impl MetalBackend { let dev = Rc::new(MetalInputDevice { slot, id: device_id, - _devnum: devnum, + devnum, fd: Default::default(), inputdev: Default::default(), devnode: devnode.to_owned(), diff --git a/src/backends/x.rs b/src/backends/x.rs index 6aaeb5ae..77a35c81 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -1177,6 +1177,10 @@ impl InputDevice for XSeatKeyboard { self.0.kb_name.clone() } + fn dev_t(&self) -> Option { + None + } + fn set_tap_enabled(&self, enabled: bool) { let _ = enabled; } @@ -1242,6 +1246,10 @@ impl InputDevice for XSeatMouse { self.0.mouse_name.clone() } + fn dev_t(&self) -> Option { + None + } + fn set_tap_enabled(&self, enabled: bool) { let _ = enabled; } diff --git a/src/state.rs b/src/state.rs index ee6ae0a2..31062e8b 100644 --- a/src/state.rs +++ b/src/state.rs @@ -215,6 +215,8 @@ pub struct InputDeviceData { pub id: InputDeviceId, pub data: Rc, pub async_event: Rc, + pub syspath: Option, + pub devnode: Option, } pub struct DeviceHandlerData { diff --git a/src/tasks.rs b/src/tasks.rs index 7df2c4fa..ccaf6812 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -5,6 +5,7 @@ mod hardware_cursor; mod idle; mod input_device; mod slow_clients; +mod udev_utils; use { crate::{ diff --git a/src/tasks/drmdev.rs b/src/tasks/drmdev.rs index f5c58ff3..993c4aee 100644 --- a/src/tasks/drmdev.rs +++ b/src/tasks/drmdev.rs @@ -2,78 +2,24 @@ use { crate::{ backend::{BackendDrmDevice, DrmDeviceId, DrmEvent}, state::{DrmDevData, State}, - udev::{Udev, UdevDeviceType}, - utils::{asyncevent::AsyncEvent, errorfmt::ErrorFmt}, + tasks::udev_utils::udev_props, + utils::asyncevent::AsyncEvent, }, - jay_config::PciId, std::{cell::Cell, rc::Rc}, }; pub fn handle(state: &Rc, dev: Rc) { let id = dev.id(); - let mut syspath = None; - let mut devnode = None; - let mut vendor = None; - let mut model = None; - let mut pci_id = None; - 'properties: { - let udev = match Udev::new() { - Ok(udev) => Rc::new(udev), - Err(e) => { - log::error!("Could not create a udev instance: {}", e); - break 'properties; - } - }; - let odev = match udev.create_device_from_devnum(UdevDeviceType::Character, dev.dev_t()) { - Ok(dev) => dev, - Err(e) => { - log::error!("{}", ErrorFmt(e)); - break 'properties; - } - }; - let dev = match odev.parent() { - Ok(dev) => dev, - Err(e) => { - log::error!("{}", ErrorFmt(e)); - break 'properties; - } - }; - syspath = dev.syspath().map(|s| s.to_string_lossy().into_owned()); - vendor = dev.vendor().map(|s| s.to_string_lossy().into_owned()); - model = dev.model().map(|s| s.to_string_lossy().into_owned()); - devnode = odev.devnode().map(|s| s.to_string_lossy().into_owned()); - 'get_pci_id: { - let id = match dev.pci_id() { - Some(id) => id, - _ => break 'get_pci_id, - }; - let id = id.to_string_lossy(); - let colon = match id.find(':') { - Some(pos) => pos, - _ => break 'get_pci_id, - }; - let vendor = &id[..colon]; - let model = &id[colon + 1..]; - let vendor = match u32::from_str_radix(vendor, 16) { - Ok(v) => v, - _ => break 'get_pci_id, - }; - let model = match u32::from_str_radix(model, 16) { - Ok(v) => v, - _ => break 'get_pci_id, - }; - pci_id = Some(PciId { vendor, model }); - } - } + let props = udev_props(dev.dev_t(), 1); let data = Rc::new(DrmDevData { dev: dev.clone(), handler: Cell::new(None), connectors: Default::default(), - syspath, - devnode, - vendor, - model, - pci_id, + syspath: props.syspath, + devnode: props.devnode, + vendor: props.vendor, + model: props.model, + pci_id: props.pci_id, }); let oh = DrvDevHandler { id, diff --git a/src/tasks/input_device.rs b/src/tasks/input_device.rs index 4901eb86..2d7601d5 100644 --- a/src/tasks/input_device.rs +++ b/src/tasks/input_device.rs @@ -3,6 +3,7 @@ use { backend::InputDevice, ifs::wl_seat::PX_PER_SCROLL, state::{DeviceHandlerData, InputDeviceData, State}, + tasks::udev_utils::{udev_props, UdevProps}, utils::asyncevent::AsyncEvent, }, std::{cell::Cell, rc::Rc}, @@ -22,6 +23,10 @@ pub fn handle(state: &Rc, dev: Rc) { ae: ae.clone(), }; let handler = state.eng.spawn(oh.handle()); + let props = match dev.dev_t() { + None => UdevProps::default(), + Some(dev_t) => udev_props(dev_t, 3), + }; state.input_device_handlers.borrow_mut().insert( dev.id(), InputDeviceData { @@ -29,6 +34,8 @@ pub fn handle(state: &Rc, dev: Rc) { id: dev.id(), data, async_event: ae, + syspath: props.syspath, + devnode: props.devnode, }, ); } diff --git a/src/tasks/udev_utils.rs b/src/tasks/udev_utils.rs new file mode 100644 index 00000000..f825254f --- /dev/null +++ b/src/tasks/udev_utils.rs @@ -0,0 +1,72 @@ +use { + crate::{ + udev::{Udev, UdevDeviceType}, + utils::errorfmt::ErrorFmt, + }, + jay_config::PciId, + std::rc::Rc, + uapi::c, +}; + +#[derive(Default, Debug)] +pub struct UdevProps { + pub syspath: Option, + pub devnode: Option, + pub vendor: Option, + pub model: Option, + pub pci_id: Option, +} + +pub fn udev_props(dev_t: c::dev_t, depth: usize) -> UdevProps { + let mut res = UdevProps::default(); + let udev = match Udev::new() { + Ok(udev) => Rc::new(udev), + Err(e) => { + log::error!("Could not create a udev instance: {}", e); + return res; + } + }; + let mut dev = match udev.create_device_from_devnum(UdevDeviceType::Character, dev_t) { + Ok(dev) => dev, + Err(e) => { + log::error!("{}", ErrorFmt(e)); + return res; + } + }; + res.devnode = dev.devnode().map(|s| s.to_string_lossy().into_owned()); + for _ in 0..depth { + dev = match dev.parent() { + Ok(dev) => dev, + Err(e) => { + log::error!("{}", ErrorFmt(e)); + return res; + } + } + } + res.syspath = dev.syspath().map(|s| s.to_string_lossy().into_owned()); + res.vendor = dev.vendor().map(|s| s.to_string_lossy().into_owned()); + res.model = dev.model().map(|s| s.to_string_lossy().into_owned()); + { + let id = match dev.pci_id() { + Some(id) => id, + _ => return res, + }; + let id = id.to_string_lossy(); + let colon = match id.find(':') { + Some(pos) => pos, + _ => return res, + }; + let vendor = &id[..colon]; + let model = &id[colon + 1..]; + let vendor = match u32::from_str_radix(vendor, 16) { + Ok(v) => v, + _ => return res, + }; + let model = match u32::from_str_radix(model, 16) { + Ok(v) => v, + _ => return res, + }; + res.pci_id = Some(PciId { vendor, model }); + } + res +}