use { crate::{ backend::{InputDevice, InputDeviceCapability, InputEvent, KeyState}, ifs::wl_seat::PX_PER_SCROLL, state::{DeviceHandlerData, InputDeviceData, State}, tasks::udev_utils::{UdevProps, udev_props}, utils::{asyncevent::AsyncEvent, event_listener::EventListener}, }, jay_config::protocol::DEFAULT_SEAT_NAME, std::{ cell::Cell, rc::{Rc, Weak}, }, }; pub fn handle(state: &Rc, dev: Rc) { let props = match dev.dev_t() { None => UdevProps::default(), Some(dev_t) => udev_props(dev_t, 3), }; let data = Rc::new_cyclic(|slf: &Weak| DeviceHandlerData { keyboard_id: state.physical_keyboard_ids.next(), seat: Default::default(), px_per_scroll_wheel: Cell::new(PX_PER_SCROLL), device: dev.clone(), syspath: props.syspath, devnode: props.devnode, keymap: Default::default(), output: Default::default(), tablet_init: dev.tablet_info(), tablet_pad_init: dev.tablet_pad_info(), is_touch: dev.has_capability(InputDeviceCapability::Touch), is_kb: dev.has_capability(InputDeviceCapability::Keyboard), mods_listener: EventListener::new(slf.clone()), }); let ae = Rc::new(AsyncEvent::default()); let oh = DeviceHandler { state: state.clone(), dev: dev.clone(), data: data.clone(), ae: ae.clone(), }; let handler = state.eng.spawn("input dev handler", oh.handle()); state.input_device_handlers.borrow_mut().insert( dev.id(), InputDeviceData { _handler: handler, id: dev.id(), data, async_event: ae, }, ); } struct DeviceHandler { state: Rc, dev: Rc, data: Rc, ae: Rc, } impl DeviceHandler { pub async fn handle(self) { { let ae = self.ae.clone(); self.dev.on_change(Rc::new(move || ae.trigger())); } for seat in self.state.globals.seats.lock().values() { if seat.seat_name() == DEFAULT_SEAT_NAME { self.data.set_seat(&self.state, Some(seat.clone())); break; } } if let Some(config) = self.state.config.get() { config.new_input_device(self.dev.id()); } loop { if self.dev.removed() { break; } if let Some(seat) = self.data.seat.get() { let mut any_events = false; let mut key_press = false; let mut mouse_move = false; while let Some(event) = self.dev.event() { let (is_key_press, is_mouse_move) = dpms_wake_triggers_for(&event); key_press |= is_key_press; mouse_move |= is_mouse_move; if is_key_press || is_mouse_move { self.state.input_occurred(is_key_press, is_mouse_move); } seat.event(&self.data, event); any_events = true; } if any_events { seat.mark_last_active(); self.state.input_occurred(key_press, mouse_move); } } else { while self.dev.event().is_some() { // nothing } } self.ae.triggered().await; } if let Some(config) = self.state.config.get() { config.del_input_device(self.dev.id()); } self.state .input_device_handlers .borrow_mut() .remove(&self.dev.id()); self.data.set_seat(&self.state, None); } } fn dpms_wake_triggers_for(event: &InputEvent) -> (bool, bool) { match event { InputEvent::Key { state: KeyState::Pressed, .. } => (true, false), InputEvent::ConnectorPosition { .. } | InputEvent::Motion { .. } | InputEvent::MotionAbsolute { .. } => (false, true), _ => (false, false), } }