1
0
Fork 0
forked from wry/wry

backend: add syspath and devnode to input devices

This commit is contained in:
Julian Orth 2024-03-12 16:37:16 +01:00
parent 813f87faaa
commit 283e438d1b
9 changed files with 107 additions and 64 deletions

View file

@ -135,6 +135,9 @@ pub trait InputDevice {
} }
fn set_transform_matrix(&self, matrix: TransformMatrix); fn set_transform_matrix(&self, matrix: TransformMatrix);
fn name(&self) -> Rc<String>; fn name(&self) -> Rc<String>;
fn dev_t(&self) -> Option<c::dev_t> {
None
}
fn tap_enabled(&self) -> Option<bool> { fn tap_enabled(&self) -> Option<bool> {
None None
} }

View file

@ -281,7 +281,7 @@ pub async fn create(state: &Rc<State>) -> Result<Rc<MetalBackend>, MetalError> {
struct MetalInputDevice { struct MetalInputDevice {
slot: usize, slot: usize,
id: InputDeviceId, id: InputDeviceId,
_devnum: c::dev_t, devnum: c::dev_t,
fd: CloneCell<Option<Rc<OwnedFd>>>, fd: CloneCell<Option<Rc<OwnedFd>>>,
inputdev: CloneCell<Option<Rc<RegisteredDevice>>>, inputdev: CloneCell<Option<Rc<RegisteredDevice>>>,
devnode: CString, devnode: CString,
@ -509,6 +509,10 @@ impl InputDevice for MetalInputDevice {
self.name.get() self.name.get()
} }
fn dev_t(&self) -> Option<c::dev_t> {
Some(self.devnum)
}
fn set_tap_enabled(&self, enabled: bool) { fn set_tap_enabled(&self, enabled: bool) {
self.desired.tap_enabled.set(Some(enabled)); self.desired.tap_enabled.set(Some(enabled));
if let Some(dev) = self.inputdev.get() { if let Some(dev) = self.inputdev.get() {

View file

@ -278,7 +278,7 @@ impl MetalBackend {
let dev = Rc::new(MetalInputDevice { let dev = Rc::new(MetalInputDevice {
slot, slot,
id: device_id, id: device_id,
_devnum: devnum, devnum,
fd: Default::default(), fd: Default::default(),
inputdev: Default::default(), inputdev: Default::default(),
devnode: devnode.to_owned(), devnode: devnode.to_owned(),

View file

@ -1177,6 +1177,10 @@ impl InputDevice for XSeatKeyboard {
self.0.kb_name.clone() self.0.kb_name.clone()
} }
fn dev_t(&self) -> Option<dev_t> {
None
}
fn set_tap_enabled(&self, enabled: bool) { fn set_tap_enabled(&self, enabled: bool) {
let _ = enabled; let _ = enabled;
} }
@ -1242,6 +1246,10 @@ impl InputDevice for XSeatMouse {
self.0.mouse_name.clone() self.0.mouse_name.clone()
} }
fn dev_t(&self) -> Option<dev_t> {
None
}
fn set_tap_enabled(&self, enabled: bool) { fn set_tap_enabled(&self, enabled: bool) {
let _ = enabled; let _ = enabled;
} }

View file

@ -215,6 +215,8 @@ pub struct InputDeviceData {
pub id: InputDeviceId, pub id: InputDeviceId,
pub data: Rc<DeviceHandlerData>, pub data: Rc<DeviceHandlerData>,
pub async_event: Rc<AsyncEvent>, pub async_event: Rc<AsyncEvent>,
pub syspath: Option<String>,
pub devnode: Option<String>,
} }
pub struct DeviceHandlerData { pub struct DeviceHandlerData {

View file

@ -5,6 +5,7 @@ mod hardware_cursor;
mod idle; mod idle;
mod input_device; mod input_device;
mod slow_clients; mod slow_clients;
mod udev_utils;
use { use {
crate::{ crate::{

View file

@ -2,78 +2,24 @@ use {
crate::{ crate::{
backend::{BackendDrmDevice, DrmDeviceId, DrmEvent}, backend::{BackendDrmDevice, DrmDeviceId, DrmEvent},
state::{DrmDevData, State}, state::{DrmDevData, State},
udev::{Udev, UdevDeviceType}, tasks::udev_utils::udev_props,
utils::{asyncevent::AsyncEvent, errorfmt::ErrorFmt}, utils::asyncevent::AsyncEvent,
}, },
jay_config::PciId,
std::{cell::Cell, rc::Rc}, std::{cell::Cell, rc::Rc},
}; };
pub fn handle(state: &Rc<State>, dev: Rc<dyn BackendDrmDevice>) { pub fn handle(state: &Rc<State>, dev: Rc<dyn BackendDrmDevice>) {
let id = dev.id(); let id = dev.id();
let mut syspath = None; let props = udev_props(dev.dev_t(), 1);
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 data = Rc::new(DrmDevData { let data = Rc::new(DrmDevData {
dev: dev.clone(), dev: dev.clone(),
handler: Cell::new(None), handler: Cell::new(None),
connectors: Default::default(), connectors: Default::default(),
syspath, syspath: props.syspath,
devnode, devnode: props.devnode,
vendor, vendor: props.vendor,
model, model: props.model,
pci_id, pci_id: props.pci_id,
}); });
let oh = DrvDevHandler { let oh = DrvDevHandler {
id, id,

View file

@ -3,6 +3,7 @@ use {
backend::InputDevice, backend::InputDevice,
ifs::wl_seat::PX_PER_SCROLL, ifs::wl_seat::PX_PER_SCROLL,
state::{DeviceHandlerData, InputDeviceData, State}, state::{DeviceHandlerData, InputDeviceData, State},
tasks::udev_utils::{udev_props, UdevProps},
utils::asyncevent::AsyncEvent, utils::asyncevent::AsyncEvent,
}, },
std::{cell::Cell, rc::Rc}, std::{cell::Cell, rc::Rc},
@ -22,6 +23,10 @@ pub fn handle(state: &Rc<State>, dev: Rc<dyn InputDevice>) {
ae: ae.clone(), ae: ae.clone(),
}; };
let handler = state.eng.spawn(oh.handle()); 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( state.input_device_handlers.borrow_mut().insert(
dev.id(), dev.id(),
InputDeviceData { InputDeviceData {
@ -29,6 +34,8 @@ pub fn handle(state: &Rc<State>, dev: Rc<dyn InputDevice>) {
id: dev.id(), id: dev.id(),
data, data,
async_event: ae, async_event: ae,
syspath: props.syspath,
devnode: props.devnode,
}, },
); );
} }

72
src/tasks/udev_utils.rs Normal file
View file

@ -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<String>,
pub devnode: Option<String>,
pub vendor: Option<String>,
pub model: Option<String>,
pub pci_id: Option<PciId>,
}
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
}