From 03997724672e2df34fa22c74553c003542d73651 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 9 Mar 2022 17:51:17 +0100 Subject: [PATCH] autocommit 2022-03-09 17:51:17 CET --- default-config/src/lib.rs | 22 ++-- i4config/src/_private/client.rs | 4 +- i4config/src/_private/ipc.rs | 4 +- i4config/src/embedded.rs | 4 +- i4config/src/lib.rs | 11 +- src/async_engine.rs | 2 - src/backend.rs | 25 ++--- src/backends/dummy.rs | 12 --- src/backends/metal.rs | 62 ++++++++--- src/backends/metal/input.rs | 69 +++++++++--- src/backends/metal/monitor.rs | 17 ++- src/backends/mod.rs | 1 - src/backends/xorg.rs | 91 +++++++++------- src/config.rs | 24 ++--- src/config/handler.rs | 44 +++----- src/dbus.rs | 2 + src/dbus/socket.rs | 3 + src/ifs/wl_seat/event_handling.rs | 20 ++-- src/libinput.rs | 6 +- src/libinput/device.rs | 16 ++- src/libinput/event.rs | 40 +++++-- src/libinput/sys.rs | 10 +- src/logind.rs | 4 +- src/main.rs | 14 +-- src/state.rs | 24 ++--- src/tasks/backend.rs | 5 +- src/tasks/device.rs | 174 ------------------------------ src/tasks/input_device.rs | 69 ++++++++++++ src/tasks/mod.rs | 4 +- src/tasks/start_backend.rs | 17 +++ src/udev.rs | 12 ++- src/utils/bitfield.rs | 2 + src/utils/mod.rs | 1 + src/utils/syncqueue.rs | 29 +++++ src/xwayland/xwm.rs | 8 +- 35 files changed, 429 insertions(+), 423 deletions(-) delete mode 100644 src/backends/dummy.rs delete mode 100644 src/tasks/device.rs create mode 100644 src/tasks/input_device.rs create mode 100644 src/tasks/start_backend.rs create mode 100644 src/utils/syncqueue.rs diff --git a/default-config/src/lib.rs b/default-config/src/lib.rs index cefad122..853117f8 100644 --- a/default-config/src/lib.rs +++ b/default-config/src/lib.rs @@ -1,4 +1,4 @@ -use i4config::embedded::grab_keyboard; +use i4config::embedded::grab_input_device; use i4config::keyboard::mods::{Modifiers, ALT, CTRL, SHIFT}; use i4config::keyboard::syms::{ SYM_Super_L, SYM_b, SYM_comma, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_p, SYM_period, @@ -8,7 +8,7 @@ use i4config::theme::{get_title_height, set_title_color, set_title_height, Color use i4config::Axis::{Horizontal, Vertical}; use i4config::Direction::{Down, Left, Right, Up}; use i4config::{ - config, create_seat, input_devices, on_new_input_device, Command, InputDevice, Seat, + config, create_seat, input_devices, on_new_input_device, Command, Seat, }; use rand::Rng; @@ -73,14 +73,12 @@ fn configure_seat(s: Seat) { fn do_grab(s: Seat, grab: bool) { for device in s.input_devices() { - if let InputDevice::Keyboard(kb) = device { - log::info!( - "{}rabbing keyboard {:?}", - if grab { "G" } else { "Ung" }, - kb.0 - ); - grab_keyboard(kb, grab); - } + log::info!( + "{}rabbing keyboard {:?}", + if grab { "G" } else { "Ung" }, + device.0 + ); + grab_input_device(device, grab); } if grab { s.unbind(SYM_y); @@ -99,7 +97,9 @@ pub fn configure() { for device in input_devices() { device.set_seat(seat); } - on_new_input_device(move |device| device.set_seat(seat)); + on_new_input_device(move |device| { + device.set_seat(seat) + }); } config!(configure); diff --git a/i4config/src/_private/client.rs b/i4config/src/_private/client.rs index b39b98b9..2b00fb16 100644 --- a/i4config/src/_private/client.rs +++ b/i4config/src/_private/client.rs @@ -2,7 +2,7 @@ use crate::_private::ipc::{ClientMessage, InitMessage, Response, ServerMessage}; use crate::_private::{bincode_ops, logging, Config, ConfigEntry, ConfigEntryGen, VERSION}; use crate::keyboard::keymap::Keymap; use crate::theme::Color; -use crate::{Axis, Command, Direction, InputDevice, Keyboard, LogLevel, ModifiedKeySym, Seat}; +use crate::{Axis, Command, Direction, InputDevice, LogLevel, ModifiedKeySym, Seat}; use std::cell::{Cell, RefCell}; use std::collections::hash_map::Entry; use std::collections::HashMap; @@ -141,7 +141,7 @@ impl Client { }); } - pub fn grab(&self, kb: Keyboard, grab: bool) { + pub fn grab(&self, kb: InputDevice, grab: bool) { self.send(&ClientMessage::GrabKb { kb, grab }); } diff --git a/i4config/src/_private/ipc.rs b/i4config/src/_private/ipc.rs index 7c4b17d7..84047874 100644 --- a/i4config/src/_private/ipc.rs +++ b/i4config/src/_private/ipc.rs @@ -2,7 +2,7 @@ use crate::keyboard::keymap::Keymap; use crate::keyboard::mods::Modifiers; use crate::keyboard::syms::KeySym; use crate::theme::Color; -use crate::{Axis, Direction, InputDevice, Keyboard, LogLevel, Seat}; +use crate::{Axis, Direction, InputDevice, LogLevel, Seat}; use bincode::{BorrowDecode, Decode, Encode}; #[derive(Encode, BorrowDecode, Debug)] @@ -92,7 +92,7 @@ pub enum ClientMessage<'a> { direction: Direction, }, GrabKb { - kb: Keyboard, + kb: InputDevice, grab: bool, }, GetTitleHeight, diff --git a/i4config/src/embedded.rs b/i4config/src/embedded.rs index c64e5617..54a81f54 100644 --- a/i4config/src/embedded.rs +++ b/i4config/src/embedded.rs @@ -1,5 +1,5 @@ -use crate::Keyboard; +use crate::InputDevice; -pub fn grab_keyboard(kb: Keyboard, grab: bool) { +pub fn grab_input_device(kb: InputDevice, grab: bool) { get!().grab(kb, grab); } diff --git a/i4config/src/lib.rs b/i4config/src/lib.rs index 32428a76..f9e186f7 100644 --- a/i4config/src/lib.rs +++ b/i4config/src/lib.rs @@ -42,16 +42,7 @@ impl Seat { } #[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)] -pub struct Keyboard(pub u64); - -#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)] -pub struct Mouse(pub u64); - -#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)] -pub enum InputDevice { - Keyboard(Keyboard), - Mouse(Mouse), -} +pub struct InputDevice(pub u64); impl InputDevice { pub fn set_seat(self, seat: Seat) { diff --git a/src/async_engine.rs b/src/async_engine.rs index 5a8bc4d5..f12b9b99 100644 --- a/src/async_engine.rs +++ b/src/async_engine.rs @@ -21,8 +21,6 @@ pub enum AsyncError { WheelError(#[from] WheelError), #[error("The event loop caused an error: {0}")] EventLoopError(#[from] EventLoopError), - #[error("The file descriptor is in an error state")] - FdError, } #[derive(Copy, Clone, Eq, PartialEq)] diff --git a/src/backend.rs b/src/backend.rs index 4664affc..3d86b32d 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -3,8 +3,7 @@ use std::fmt::Debug; use std::rc::Rc; linear_ids!(OutputIds, OutputId); -linear_ids!(KeyboardIds, KeyboardId); -linear_ids!(MouseIds, MouseId); +linear_ids!(InputDeviceIds, InputDeviceId); pub trait Backend {} @@ -16,25 +15,17 @@ pub trait Output { fn on_change(&self, cb: Rc); } -pub trait Keyboard { - fn id(&self) -> KeyboardId; +pub trait InputDevice { + fn id(&self) -> InputDeviceId; fn removed(&self) -> bool; - fn event(&self) -> Option; + fn event(&self) -> Option; fn on_change(&self, cb: Rc); fn grab(&self, grab: bool); } -pub trait Mouse { - fn id(&self) -> MouseId; - fn removed(&self) -> bool; - fn event(&self) -> Option; - fn on_change(&self, cb: Rc); -} - pub enum BackendEvent { NewOutput(Rc), - NewKeyboard(Rc), - NewMouse(Rc), + NewInputDevice(Rc), } #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -50,12 +41,8 @@ pub enum ScrollAxis { } #[derive(Debug)] -pub enum KeyboardEvent { +pub enum InputEvent { Key(u32, KeyState), -} - -#[derive(Debug)] -pub enum MouseEvent { OutputPosition(OutputId, Fixed, Fixed), #[allow(dead_code)] Motion(Fixed, Fixed), diff --git a/src/backends/dummy.rs b/src/backends/dummy.rs deleted file mode 100644 index 9f8605ac..00000000 --- a/src/backends/dummy.rs +++ /dev/null @@ -1,12 +0,0 @@ -use crate::backend::Backend; -use std::rc::Rc; - -pub struct DummyBackend {} - -impl DummyBackend { - pub fn new() -> Rc { - Rc::new(Self {}) - } -} - -impl Backend for DummyBackend {} diff --git a/src/backends/metal.rs b/src/backends/metal.rs index 8db4b3af..3e5cbab1 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -8,12 +8,15 @@ use crate::libinput::{LibInput, LibInputAdapter, LibInputError}; use crate::logind::{LogindError, Session}; use crate::udev::{UdevError, UdevMonitor}; use crate::utils::copyhashmap::CopyHashMap; -use crate::{AsyncQueue, CloneCell, ErrorFmt, NumCell, State, Udev}; +use crate::{CloneCell, State, Udev}; use std::cell::{Cell, RefCell}; use std::ffi::{CStr, CString}; +use std::future::pending; use std::rc::Rc; use thiserror::Error; use uapi::{c, OwnedFd}; +use crate::backend::{Backend, InputDevice, InputDeviceId, InputEvent}; +use crate::utils::syncqueue::SyncQueue; #[derive(Debug, Error)] pub enum MetalError { @@ -31,11 +34,14 @@ pub enum MetalError { LibInput(#[from] LibInputError), #[error("Dupfd failed")] Dup(#[source] crate::utils::oserror::OsError), + #[error("Metal backend terminated unexpectedly")] + UnexpectedTermination, } -pub async fn run(state: Rc) { - if let Err(e) = run_(state).await { - log::error!("{}", ErrorFmt(e)); +pub async fn run(state: Rc) -> MetalError { + match run_(state).await { + Err(e) => e, + _ => MetalError::UnexpectedTermination, } } @@ -48,7 +54,10 @@ struct MetalBackend { libinput_fd: AsyncFd, device_holder: Rc, session: Session, - ids: NumCell, +} + +impl Backend for MetalBackend { + } async fn run_(state: Rc) -> Result<(), MetalError> { @@ -89,26 +98,26 @@ async fn run_(state: Rc) -> Result<(), MetalError> { libinput_fd, device_holder, session, - ids: Default::default(), }); let _monitor = state.eng.spawn(metal.clone().monitor_devices()); let _events = state.eng.spawn(metal.clone().handle_libinput_events()); if let Err(e) = metal.enumerate_devices() { return Err(MetalError::Enumerate(Box::new(e))); } - let queue = AsyncQueue::::new(); - queue.pop().await; - Ok(()) + pending().await } struct MetalDevice { slot: usize, - device_id: u64, + id: InputDeviceId, devnum: c::dev_t, fd: CloneCell>>, inputdev: Cell>, devnode: CString, - sysname: CString, + _sysname: CString, + removed: Cell, + events: SyncQueue, + cb: CloneCell>>, } struct DeviceHolder { @@ -135,8 +144,33 @@ impl LibInputAdapter for DeviceHolder { } } -impl MetalBackend { - fn id(&self) -> u64 { - self.ids.fetch_add(1) +impl InputDevice for MetalDevice { + fn id(&self) -> InputDeviceId { + self.id + } + + fn removed(&self) -> bool { + self.removed.get() + } + + fn event(&self) -> Option { + self.events.pop() + } + + fn on_change(&self, cb: Rc) { + self.cb.set(Some(cb)); + } + + fn grab(&self, _grab: bool) { + log::warn!("Metal backend does not support grabbing devices"); + } +} + +impl MetalDevice { + fn event(&self, event: InputEvent) { + self.events.push(event); + if let Some(cb) = self.cb.get() { + cb(); + } } } diff --git a/src/backends/metal/input.rs b/src/backends/metal/input.rs index ed3320e4..f15a59b3 100644 --- a/src/backends/metal/input.rs +++ b/src/backends/metal/input.rs @@ -1,9 +1,36 @@ use crate::async_engine::FdStatus; -use crate::libinput::consts::LIBINPUT_EVENT_KEYBOARD_KEY; use crate::libinput::event::LibInputEvent; use crate::metal::MetalBackend; use crate::ErrorFmt; use std::rc::Rc; +use crate::backend::{InputEvent, KeyState}; +use crate::libinput::consts::LIBINPUT_KEY_STATE_PRESSED; + +macro_rules! unpack { + ($slf:expr, $ev:expr) => { + { + let slot = match $ev.device().slot() { + Some(s) => s, + _ => return, + }; + let data = match $slf.device_holder.input_devices_.borrow_mut().get(slot).cloned().and_then(|v| v) { + Some(d) => d, + _ => return, + }; + data + } + }; + ($slf:expr, $ev:expr, $conv:ident) => { + { + let event = match $ev.$conv() { + Some(e) => e, + _ => return, + }; + let data = unpack!($slf, $ev); + (event, data) + } + }; +} impl MetalBackend { pub async fn handle_libinput_events(self: Rc) { @@ -34,22 +61,40 @@ impl MetalBackend { } fn handle_event(self: &Rc, event: LibInputEvent) { + use crate::libinput::consts as c; + match event.ty() { - LIBINPUT_EVENT_KEYBOARD_KEY => self.handle_keyboard_event(event), + c::LIBINPUT_EVENT_DEVICE_ADDED => self.handle_device_added(event), + c::LIBINPUT_EVENT_DEVICE_REMOVED => self.handle_device_removed(event), + c::LIBINPUT_EVENT_KEYBOARD_KEY => self.handle_keyboard_key(event), + c::LIBINPUT_EVENT_POINTER_MOTION => self.handle_pointer_motion(event), _ => {} } } - fn handle_keyboard_event(self: &Rc, event: LibInputEvent) { - let event = match event.keyboard_event() { - Some(event) => event, - _ => return, + fn handle_device_added(self: &Rc, _event: LibInputEvent) { + // let dev = unpack!(self, event); + } + + fn handle_device_removed(self: &Rc, event: LibInputEvent) { + let dev = unpack!(self, event); + self.device_holder.input_devices.remove(&dev.devnum); + self.device_holder.input_devices_.borrow_mut()[dev.slot] = None; + event.device().unset_slot(); + } + + fn handle_keyboard_key(self: &Rc, event: LibInputEvent) { + let (event, dev) = unpack!(self, event, keyboard_event); + let state = if event.key_state() == LIBINPUT_KEY_STATE_PRESSED { + KeyState::Pressed + } else { + KeyState::Released }; - log::info!( - "key: {}, state: {:?}, time: {}", - event.key(), - event.key_state(), - event.time_usec() - ); + dev.event(InputEvent::Key(event.key(), state)); + } + + fn handle_pointer_motion(self: &Rc, event: LibInputEvent) { + let (event, dev) = unpack!(self, event, pointer_event); + dev.event(InputEvent::Motion(event.dx().into(), event.dy().into())); } } diff --git a/src/backends/metal/monitor.rs b/src/backends/metal/monitor.rs index 5f7425f0..10b5621b 100644 --- a/src/backends/metal/monitor.rs +++ b/src/backends/metal/monitor.rs @@ -1,9 +1,11 @@ +use std::cell::Cell; use crate::async_engine::FdStatus; use crate::dbus::TRUE; use crate::metal::{MetalBackend, MetalDevice, MetalError}; use crate::udev::UdevDevice; use crate::ErrorFmt; use std::rc::Rc; +use crate::backend::BackendEvent; impl MetalBackend { pub async fn monitor_devices(self: Rc) { @@ -54,8 +56,11 @@ impl MetalBackend { } fn add_input_device(self: &Rc, dev: &UdevDevice) { + if !dev.is_initialized() { + return; + } let slf = self.clone(); - let device_id = self.id(); + let device_id = self.state.input_device_ids.next(); let devnum = dev.devnum(); let devnode = match dev.devnode() { Ok(n) => n, @@ -83,12 +88,15 @@ impl MetalBackend { }; let dev = Rc::new(MetalDevice { slot, - device_id, + id: device_id, devnum, fd: Default::default(), inputdev: Default::default(), devnode: devnode.to_owned(), - sysname: sysname.to_owned(), + _sysname: sysname.to_owned(), + removed: Cell::new(false), + events: Default::default(), + cb: Default::default(), }); slots[slot] = Some(dev.clone()); self.device_holder.input_devices.set(devnum, dev); @@ -97,7 +105,7 @@ impl MetalBackend { let mut slots = slf.device_holder.input_devices_.borrow_mut(); let dev = 'dev: { if let Some(dev) = id.get(&devnum) { - if dev.device_id == device_id { + if dev.id == device_id { break 'dev dev; } } @@ -126,6 +134,7 @@ impl MetalBackend { }; inputdev.device().set_slot(slot); dev.inputdev.set(Some(inputdev)); + slf.state.backend_events.push(BackendEvent::NewInputDevice(dev.clone())); }); } } diff --git a/src/backends/mod.rs b/src/backends/mod.rs index 4888f27d..2b5ff444 100644 --- a/src/backends/mod.rs +++ b/src/backends/mod.rs @@ -1,3 +1,2 @@ -pub mod dummy; pub mod metal; pub mod xorg; diff --git a/src/backends/xorg.rs b/src/backends/xorg.rs index 33a9c6f4..98d336db 100644 --- a/src/backends/xorg.rs +++ b/src/backends/xorg.rs @@ -1,7 +1,4 @@ -use crate::backend::{ - Backend, BackendEvent, KeyState, Keyboard, KeyboardEvent, KeyboardId, Mouse, MouseEvent, - MouseId, Output, OutputId, ScrollAxis, -}; +use crate::backend::{Backend, BackendEvent, KeyState, InputEvent, Output, OutputId, ScrollAxis, InputDeviceId, InputDevice}; use crate::drm::drm::{Drm, DrmError}; use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING}; use crate::drm::{ModifiedFormat, INVALID_MODIFIER}; @@ -26,11 +23,13 @@ use thiserror::Error; use uapi::{c, OwnedFd}; use xcb_dl::{ffi, Xcb, XcbDri3, XcbPresent, XcbRender, XcbXinput, XcbXkb}; use xcb_dl_util::cursor::{XcbCursorContext, XcbCursorImage}; -use xcb_dl_util::error::{XcbError, XcbErrorParser}; +use xcb_dl_util::error::{XcbConnectionError, XcbError, XcbErrorParser}; use xcb_dl_util::xcb_box::XcbBox; #[derive(Debug, Error)] pub enum XorgBackendError { + #[error("Could not connect to the X server")] + CannotConnect(#[source] XcbConnectionError), #[error("The xcb connection is in an error state")] ErrorEvent, #[error("The drm subsystem returned an error")] @@ -97,6 +96,10 @@ impl XcbCon { let render = Box::new(XcbRender::load_loose()?); let c = xcb.xcb_connect(ptr::null(), ptr::null_mut()); + match xcb.xcb_connection_has_error(c) { + 0 => { }, + n => return Err(XorgBackendError::CannotConnect(n.into())), + } let errors = XcbErrorParser::new(&xcb, c); let mut con = Self { @@ -554,8 +557,8 @@ impl XorgBackend { ); } let seat = Rc::new(XorgSeat { - kb_id: self.state.kb_ids.next(), - mouse_id: self.state.mouse_ids.next(), + kb_id: self.state.input_device_ids.next(), + mouse_id: self.state.input_device_ids.next(), backend: self.clone(), kb: info.deviceid, mouse: info.attachment, @@ -571,10 +574,10 @@ impl XorgBackend { self.mouse_seats.set(info.attachment, seat.clone()); self.state .backend_events - .push(BackendEvent::NewMouse(seat.clone())); + .push(BackendEvent::NewInputDevice(Rc::new(XorgSeatMouse(seat.clone())))); self.state .backend_events - .push(BackendEvent::NewKeyboard(seat.clone())); + .push(BackendEvent::NewInputDevice(Rc::new(XorgSeatKeyboard(seat.clone())))); } } @@ -766,7 +769,7 @@ impl XorgBackend { 7 => (ScrollAxis::Horizontal, 15), _ => unreachable!(), }; - seat.mouse_event(MouseEvent::Scroll(val, axis)); + seat.mouse_event(InputEvent::Scroll(val, axis)); } } else { const BTN_LEFT: u32 = 0x110; @@ -780,7 +783,7 @@ impl XorgBackend { 3 => BTN_RIGHT, n => BTN_SIDE + n - 8, }; - seat.mouse_event(MouseEvent::Button(button, state)); + seat.mouse_event(InputEvent::Button(button, state)); } } Ok(()) @@ -800,7 +803,7 @@ impl XorgBackend { let event = unsafe { (event as *const _ as *const ffi::xcb_input_key_press_event_t).deref() }; if let Some(seat) = self.seats.get(&event.deviceid) { - seat.kb_event(KeyboardEvent::Key(event.detail - 8, state)); + seat.kb_event(InputEvent::Key(event.detail - 8, state)); } Ok(()) } @@ -843,7 +846,7 @@ impl XorgBackend { self.outputs.get(&event.event), self.mouse_seats.get(&event.deviceid), ) { - seat.mouse_event(MouseEvent::OutputPosition( + seat.mouse_event(InputEvent::OutputPosition( win.id, Fixed::from_1616(event.event_x), Fixed::from_1616(event.event_y), @@ -864,7 +867,7 @@ impl XorgBackend { (Some(a), Some(b)) => (a, b), _ => return Ok(()), }; - seat.mouse_event(MouseEvent::OutputPosition( + seat.mouse_event(InputEvent::OutputPosition( win.id, Fixed::from_1616(event.event_x), Fixed::from_1616(event.event_y), @@ -997,19 +1000,23 @@ impl Output for XorgOutput { } struct XorgSeat { - kb_id: KeyboardId, - mouse_id: MouseId, + kb_id: InputDeviceId, + mouse_id: InputDeviceId, backend: Rc, kb: ffi::xcb_input_device_id_t, mouse: ffi::xcb_input_device_id_t, removed: Cell, kb_cb: CloneCell>>, mouse_cb: CloneCell>>, - kb_events: RefCell>, - mouse_events: RefCell>, + kb_events: RefCell>, + mouse_events: RefCell>, button_map: CopyHashMap, } +struct XorgSeatKeyboard(Rc); + +struct XorgSeatMouse(Rc); + impl XorgSeat { fn kb_changed(&self) { if let Some(cb) = self.kb_cb.get() { @@ -1023,12 +1030,12 @@ impl XorgSeat { } } - fn mouse_event(&self, event: MouseEvent) { + fn mouse_event(&self, event: InputEvent) { self.mouse_events.borrow_mut().push_back(event); self.mouse_changed(); } - fn kb_event(&self, event: KeyboardEvent) { + fn kb_event(&self, event: InputEvent) { self.kb_events.borrow_mut().push_back(event); self.kb_changed(); } @@ -1066,26 +1073,26 @@ impl XorgSeat { } } -impl Keyboard for XorgSeat { - fn id(&self) -> KeyboardId { - self.kb_id +impl InputDevice for XorgSeatKeyboard { + fn id(&self) -> InputDeviceId { + self.0.kb_id } fn removed(&self) -> bool { - self.removed.get() + self.0.removed.get() } - fn event(&self) -> Option { - self.kb_events.borrow_mut().pop_front() + fn event(&self) -> Option { + self.0.kb_events.borrow_mut().pop_front() } fn on_change(&self, cb: Rc) { - self.kb_cb.set(Some(cb)); + self.0.kb_cb.set(Some(cb)); } fn grab(&self, grab: bool) { unsafe { - let con = &self.backend.con; + let con = &self.0.backend.con; let mut err = ptr::null_mut(); if grab { let res = con.input.xcb_input_xi_grab_device( @@ -1093,7 +1100,7 @@ impl Keyboard for XorgSeat { con.screen.root, 0, 0, - self.kb, + self.0.kb, ffi::XCB_GRAB_MODE_ASYNC as _, ffi::XCB_GRAB_MODE_ASYNC as _, 1, @@ -1106,39 +1113,43 @@ impl Keyboard for XorgSeat { let res = match con.check(res, err) { Ok(r) => r, Err(e) => { - log::error!("Could not grab device {}: {}", self.kb, ErrorFmt(e)); + log::error!("Could not grab device {}: {}", self.0.kb, ErrorFmt(e)); return; } }; if res.status != ffi::XCB_GRAB_STATUS_SUCCESS as _ { - log::error!("Could not grab device {}: status = {}", self.kb, res.status); + log::error!("Could not grab device {}: status = {}", self.0.kb, res.status); } } else { let cookie = con .input - .xcb_input_xi_ungrab_device_checked(con.c, 0, self.kb); + .xcb_input_xi_ungrab_device_checked(con.c, 0, self.0.kb); if let Err(e) = con.check_cookie(cookie) { - log::error!("Could not ungrab device {}: {}", self.kb, ErrorFmt(e)); + log::error!("Could not ungrab device {}: {}", self.0.kb, ErrorFmt(e)); } } } } } -impl Mouse for XorgSeat { - fn id(&self) -> MouseId { - self.mouse_id +impl InputDevice for XorgSeatMouse { + fn id(&self) -> InputDeviceId { + self.0.mouse_id } fn removed(&self) -> bool { - self.removed.get() + self.0.removed.get() } - fn event(&self) -> Option { - self.mouse_events.borrow_mut().pop_front() + fn event(&self) -> Option { + self.0.mouse_events.borrow_mut().pop_front() } fn on_change(&self, cb: Rc) { - self.mouse_cb.set(Some(cb)); + self.0.mouse_cb.set(Some(cb)); + } + + fn grab(&self, _grab: bool) { + log::error!("Cannot grab xorg mouse"); } } diff --git a/src/config.rs b/src/config.rs index 3fc88bf0..fefaea87 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,5 @@ mod handler; -use crate::backend::{KeyboardId, MouseId}; use crate::config::handler::ConfigProxyHandler; use crate::ifs::wl_seat::SeatId; use crate::utils::ptr_ext::PtrExt; @@ -8,12 +7,13 @@ use crate::{NumCell, State}; use i4config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage}; use i4config::_private::{bincode_ops, ConfigEntry, VERSION}; use i4config::keyboard::ModifiedKeySym; -use i4config::{InputDevice, Keyboard, Mouse, Seat}; +use i4config::{InputDevice, Seat}; use libloading::Library; use std::cell::Cell; use std::ptr; use std::rc::Rc; use thiserror::Error; +use crate::backend::InputDeviceId; #[derive(Debug, Error)] pub enum ConfigError { @@ -36,27 +36,15 @@ impl ConfigProxy { }); } - pub fn new_keyboard(&self, kb: KeyboardId) { + pub fn new_input_device(&self, dev: InputDeviceId) { self.handler.send(&ServerMessage::NewInputDevice { - device: InputDevice::Keyboard(Keyboard(kb.raw() as _)), + device: InputDevice(dev.raw() as _), }); } - pub fn new_mouse(&self, mouse: MouseId) { - self.handler.send(&ServerMessage::NewInputDevice { - device: InputDevice::Mouse(Mouse(mouse.raw() as _)), - }); - } - - pub fn del_keyboard(&self, kb: KeyboardId) { + pub fn del_input_device(&self, dev: InputDeviceId) { self.handler.send(&ServerMessage::DelInputDevice { - device: InputDevice::Keyboard(Keyboard(kb.raw() as _)), - }); - } - - pub fn del_mouse(&self, mouse: MouseId) { - self.handler.send(&ServerMessage::DelInputDevice { - device: InputDevice::Mouse(Mouse(mouse.raw() as _)), + device: InputDevice(dev.raw() as _), }); } } diff --git a/src/config/handler.rs b/src/config/handler.rs index 31cd0645..b7bb2bd4 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -1,4 +1,3 @@ -use crate::backend::{KeyboardId, MouseId}; use crate::ifs::wl_seat::{SeatId, WlSeatGlobal}; use crate::state::DeviceHandlerData; use crate::tree::walker::NodeVisitorBase; @@ -14,12 +13,13 @@ use i4config::_private::ipc::{ClientMessage, Response, ServerMessage}; use i4config::keyboard::keymap::Keymap; use i4config::keyboard::mods::Modifiers; use i4config::keyboard::syms::KeySym; -use i4config::{Axis, Direction, InputDevice, Keyboard, LogLevel, Mouse, Seat}; +use i4config::{Axis, Direction, InputDevice, LogLevel, Seat}; use libloading::Library; use log::Level; use std::cell::Cell; use std::rc::Rc; use thiserror::Error; +use crate::backend::InputDeviceId; pub(super) struct ConfigProxyHandler { pub client_data: Cell<*const u8>, @@ -156,20 +156,12 @@ impl ConfigProxyHandler { &self, device: InputDevice, ) -> Result, CphError> { - let data = match device { - InputDevice::Keyboard(kb) => self + let data = self .state - .kb_handlers + .input_device_handlers .borrow_mut() - .get(&KeyboardId::from_raw(kb.0 as _)) - .map(|d| d.data.clone()), - InputDevice::Mouse(mouse) => self - .state - .mouse_handlers - .borrow_mut() - .get(&MouseId::from_raw(mouse.0 as _)) - .map(|d| d.data.clone()), - }; + .get(&InputDeviceId::from_raw(device.0 as _)) + .map(|d| d.data.clone()); match data { Some(d) => Ok(d), _ => Err(CphError::DeviceDoesNotExist(device)), @@ -186,11 +178,11 @@ impl ConfigProxyHandler { Err(CphError::SeatDoesNotExist(seat)) } - fn get_kb(&self, kb: Keyboard) -> Result, CphError> { - let kbs = self.state.kb_handlers.borrow_mut(); - match kbs.get(&(KeyboardId::from_raw(kb.0 as _))) { + fn get_kb(&self, kb: InputDevice) -> Result, CphError> { + let kbs = self.state.input_device_handlers.borrow_mut(); + match kbs.get(&(InputDeviceId::from_raw(kb.0 as _))) { None => Err(CphError::KeyboardDoesNotExist(kb)), - Some(kb) => Ok(kb.kb.clone()), + Some(kb) => Ok(kb.device.clone()), } } @@ -267,18 +259,10 @@ impl ConfigProxyHandler { }; let mut res = vec![]; { - let devs = self.state.kb_handlers.borrow_mut(); + let devs = self.state.input_device_handlers.borrow_mut(); for dev in devs.values() { if matches(&dev.data) { - res.push(InputDevice::Keyboard(Keyboard(dev.id.raw() as _))); - } - } - } - { - let devs = self.state.mouse_handlers.borrow_mut(); - for dev in devs.values() { - if matches(&dev.data) { - res.push(InputDevice::Mouse(Mouse(dev.id.raw() as _))); + res.push(InputDevice(dev.id.raw() as _)); } } } @@ -314,7 +298,7 @@ impl ConfigProxyHandler { Ok(()) } - fn handle_grab(&self, kb: Keyboard, grab: bool) -> Result<(), GrabError> { + fn handle_grab(&self, kb: InputDevice, grab: bool) -> Result<(), GrabError> { let kb = self.get_kb(kb)?; kb.grab(grab); Ok(()) @@ -532,7 +516,7 @@ enum CphError { #[error("Seat {0:?} does not exist")] SeatDoesNotExist(Seat), #[error("Keyboard {0:?} does not exist")] - KeyboardDoesNotExist(Keyboard), + KeyboardDoesNotExist(InputDevice), #[error("Could not parse the message")] ParsingFailed(#[source] DecodeError), } diff --git a/src/dbus.rs b/src/dbus.rs index f65eb522..46025301 100644 --- a/src/dbus.rs +++ b/src/dbus.rs @@ -192,7 +192,9 @@ const MSG_ERROR: u8 = 3; const MSG_SIGNAL: u8 = 4; const NO_REPLY_EXPECTED: u8 = 0x1; +#[allow(dead_code)] const NO_AUTO_START: u8 = 0x2; +#[allow(dead_code)] const ALLOW_INTERACTIVE_AUTHORIZATION: u8 = 0x4; pub const BUS_DEST: &'static str = "org.freedesktop.DBus"; diff --git a/src/dbus/socket.rs b/src/dbus/socket.rs index ed9d8a41..c9650bd1 100644 --- a/src/dbus/socket.rs +++ b/src/dbus/socket.rs @@ -30,6 +30,7 @@ impl DbusSocket { } } + #[allow(dead_code)] pub fn call_noreply<'a, T: MethodCall<'a>>(&self, destination: &str, path: &str, msg: T) { if !self.dead.get() { self.send_call(path, destination, NO_REPLY_EXPECTED, &msg); @@ -89,6 +90,7 @@ impl DbusSocket { } } + #[allow(dead_code)] pub fn get(&self, destination: &str, path: &str, f: F) where T: Property, @@ -120,6 +122,7 @@ impl DbusSocket { } } + #[allow(dead_code)] pub fn handle_signal( self: &Rc, sender: Option<&str>, diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index e88c490b..33f10ae7 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -1,4 +1,4 @@ -use crate::backend::{KeyState, KeyboardEvent, MouseEvent, OutputId, ScrollAxis}; +use crate::backend::{KeyState, InputEvent, OutputId, ScrollAxis}; use crate::client::{Client, ClientId}; use crate::fixed::Fixed; use crate::ifs::ipc; @@ -114,18 +114,13 @@ impl NodeSeatState { } impl WlSeatGlobal { - pub fn kb_event(self: &Rc, event: KeyboardEvent) { + pub fn event(self: &Rc, event: InputEvent) { match event { - KeyboardEvent::Key(k, s) => self.key_event(k, s), - } - } - - pub fn mouse_event(self: &Rc, event: MouseEvent) { - match event { - MouseEvent::OutputPosition(o, x, y) => self.output_position_event(o, x, y), - MouseEvent::Motion(dx, dy) => self.motion_event(dx, dy), - MouseEvent::Button(b, s) => self.pointer_owner.button(self, b, s), - MouseEvent::Scroll(d, a) => self.pointer_owner.scroll(self, d, a), + InputEvent::Key(k, s) => self.key_event(k, s), + InputEvent::OutputPosition(o, x, y) => self.output_position_event(o, x, y), + InputEvent::Motion(dx, dy) => self.motion_event(dx, dy), + InputEvent::Button(b, s) => self.pointer_owner.button(self, b, s), + InputEvent::Scroll(d, a) => self.pointer_owner.scroll(self, d, a), } } @@ -141,6 +136,7 @@ impl WlSeatGlobal { } fn motion_event(self: &Rc, dx: Fixed, dy: Fixed) { + log::info!("motion: {}x{}", dx, dy); let (x, y) = self.pos.get(); self.set_new_position(x + dx, y + dy); } diff --git a/src/libinput.rs b/src/libinput.rs index 485200a0..fc3337f8 100644 --- a/src/libinput.rs +++ b/src/libinput.rs @@ -78,7 +78,7 @@ pub enum LibInputError { } pub struct LibInput { - data: Box, + _data: Box, li: *mut libinput, } @@ -102,7 +102,7 @@ impl LibInput { }; libinput_log_set_priority(li, priority.raw() as _); } - Ok(Self { data: ud, li }) + Ok(Self { _data: ud, li }) } pub fn fd(&self) -> c::c_int { @@ -122,7 +122,7 @@ impl LibInput { libinput_device_ref(res); } Ok(RegisteredDevice { - li: self.clone(), + _li: self.clone(), dev: res, }) } diff --git a/src/libinput/device.rs b/src/libinput/device.rs index bed4ca6d..44475706 100644 --- a/src/libinput/device.rs +++ b/src/libinput/device.rs @@ -1,7 +1,4 @@ -use crate::libinput::sys::{ - libinput_device, libinput_device_set_user_data, libinput_device_unref, - libinput_path_remove_device, -}; +use crate::libinput::sys::{libinput_device, libinput_device_get_user_data, libinput_device_set_user_data, libinput_device_unref, libinput_path_remove_device}; use crate::libinput::LibInput; use std::marker::PhantomData; use std::rc::Rc; @@ -12,7 +9,7 @@ pub struct LibInputDevice<'a> { } pub struct RegisteredDevice { - pub(super) li: Rc, + pub(super) _li: Rc, pub(super) dev: *mut libinput_device, } @@ -30,6 +27,15 @@ impl<'a> LibInputDevice<'a> { libinput_device_set_user_data(self.dev, slot as _); } } + + pub fn slot(&self) -> Option { + let res = unsafe { libinput_device_get_user_data(self.dev) as usize }; + if res == 0 { + None + } else { + Some(res - 1) + } + } } impl RegisteredDevice { diff --git a/src/libinput/event.rs b/src/libinput/event.rs index 3df51e69..39e870ef 100644 --- a/src/libinput/event.rs +++ b/src/libinput/event.rs @@ -1,11 +1,6 @@ use crate::libinput::consts::{EventType, KeyState}; use crate::libinput::device::LibInputDevice; -use crate::libinput::sys::{ - libinput_event, libinput_event_destroy, libinput_event_get_device, - libinput_event_get_keyboard_event, libinput_event_get_type, libinput_event_keyboard, - libinput_event_keyboard_get_key, libinput_event_keyboard_get_key_state, - libinput_event_keyboard_get_time_usec, -}; +use crate::libinput::sys::{libinput_event, libinput_event_destroy, libinput_event_get_device, libinput_event_get_keyboard_event, libinput_event_get_pointer_event, libinput_event_get_type, libinput_event_keyboard, libinput_event_keyboard_get_key, libinput_event_keyboard_get_key_state, libinput_event_keyboard_get_time_usec, libinput_event_pointer, libinput_event_pointer_get_dx, libinput_event_pointer_get_dy, libinput_event_pointer_get_time_usec}; use std::marker::PhantomData; pub struct LibInputEvent<'a> { @@ -18,6 +13,11 @@ pub struct LibInputEventKeyboard<'a> { pub(super) _phantom: PhantomData<&'a ()>, } +pub struct LibInputEventPointer<'a> { + pub(super) event: *mut libinput_event_pointer, + pub(super) _phantom: PhantomData<&'a ()>, +} + impl<'a> Drop for LibInputEvent<'a> { fn drop(&mut self) { unsafe { @@ -49,6 +49,18 @@ impl<'a> LibInputEvent<'a> { }) } } + + pub fn pointer_event(&self) -> Option { + let res = unsafe { libinput_event_get_pointer_event(self.event) }; + if res.is_null() { + None + } else { + Some(LibInputEventPointer { + event: res, + _phantom: Default::default(), + }) + } + } } impl<'a> LibInputEventKeyboard<'a> { @@ -60,7 +72,23 @@ impl<'a> LibInputEventKeyboard<'a> { unsafe { KeyState(libinput_event_keyboard_get_key_state(self.event)) } } + #[allow(dead_code)] pub fn time_usec(&self) -> u64 { unsafe { libinput_event_keyboard_get_time_usec(self.event) } } } + +impl<'a> LibInputEventPointer<'a> { + pub fn dx(&self) -> f64 { + unsafe { libinput_event_pointer_get_dx(self.event) } + } + + pub fn dy(&self) -> f64 { + unsafe { libinput_event_pointer_get_dy(self.event) } + } + + #[allow(dead_code)] + pub fn time_usec(&self) -> u64 { + unsafe { libinput_event_pointer_get_time_usec(self.event) } + } +} diff --git a/src/libinput/sys.rs b/src/libinput/sys.rs index f5ccd8b5..2c15c9dc 100644 --- a/src/libinput/sys.rs +++ b/src/libinput/sys.rs @@ -16,6 +16,7 @@ extern "C" { pub type libinput_device; pub type libinput_event; pub type libinput_event_keyboard; + pub type libinput_event_pointer; pub fn libinput_log_set_handler(libinput: *mut libinput, log_handler: libinput_log_handler); pub fn libinput_log_set_priority(libinput: *mut libinput, priority: libinput_log_priority); @@ -42,15 +43,22 @@ extern "C" { pub fn libinput_event_destroy(event: *mut libinput_event); pub fn libinput_event_get_type(event: *mut libinput_event) -> libinput_event_type; pub fn libinput_event_get_device(event: *mut libinput_event) -> *mut libinput_device; + pub fn libinput_event_get_keyboard_event( event: *mut libinput_event, ) -> *mut libinput_event_keyboard; - pub fn libinput_event_keyboard_get_key(event: *mut libinput_event_keyboard) -> u32; pub fn libinput_event_keyboard_get_key_state( event: *mut libinput_event_keyboard, ) -> libinput_key_state; pub fn libinput_event_keyboard_get_time_usec(event: *mut libinput_event_keyboard) -> u64; + + pub fn libinput_event_get_pointer_event( + event: *mut libinput_event, + ) -> *mut libinput_event_pointer; + pub fn libinput_event_pointer_get_time_usec(event: *mut libinput_event_pointer) -> u64; + pub fn libinput_event_pointer_get_dx(event: *mut libinput_event_pointer) -> f64; + pub fn libinput_event_pointer_get_dy(event: *mut libinput_event_pointer) -> f64; } #[repr(C)] diff --git a/src/logind.rs b/src/logind.rs index 5ff34031..3c79eff7 100644 --- a/src/logind.rs +++ b/src/logind.rs @@ -22,7 +22,7 @@ pub enum LogindError { pub struct Session { socket: Rc, - seat: String, + _seat: String, session_path: String, } @@ -58,7 +58,7 @@ impl Session { }; Ok(Self { socket: socket.clone(), - seat, + _seat: seat, session_path, }) } diff --git a/src/main.rs b/src/main.rs index ad7e7c34..e8d0c1ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,9 +16,8 @@ use crate::acceptor::AcceptorError; use crate::async_engine::{AsyncError, Phase}; -use crate::backends::dummy::DummyBackend; use crate::backends::metal; -use crate::backends::xorg::XorgBackendError; +use crate::backends::xorg::{XorgBackend, XorgBackendError}; use crate::client::Clients; use crate::clientmem::ClientMemError; use crate::dbus::{Dbus, FALSE}; @@ -150,7 +149,6 @@ fn main_() -> Result<(), MainError> { let state = Rc::new(State { xkb_ctx, forker: Default::default(), - backend: CloneCell::new(DummyBackend::new()), default_keymap: xkb_keymap, eng: engine.clone(), el: el.clone(), @@ -165,17 +163,15 @@ fn main_() -> Result<(), MainError> { node_ids, backend_events: AsyncQueue::new(), output_handlers: Default::default(), - mouse_handlers: Default::default(), seat_ids: Default::default(), - kb_ids: Default::default(), outputs: Default::default(), seat_queue: Default::default(), slow_clients: AsyncQueue::new(), none_surface_ext: Rc::new(NoneSurfaceExt), tree_changed_sent: Cell::new(false), config: Default::default(), - mouse_ids: Default::default(), - kb_handlers: Default::default(), + input_device_ids: Default::default(), + input_device_handlers: Default::default(), theme: Default::default(), pending_container_layout: Default::default(), pending_container_titles: Default::default(), @@ -183,10 +179,7 @@ fn main_() -> Result<(), MainError> { pending_float_titles: Default::default(), dbus: Dbus::new(&engine, &run_toplevel), }); - let _future = state.eng.spawn(metal::run(state.clone())); forker.install(&state); - // let backend = XorgBackend::new(&state)?; - // state.backend.set(backend); let config = config::ConfigProxy::default(&state); state.config.set(Some(Rc::new(config))); let _global_event_handler = engine.spawn(tasks::handle_backend_events(state.clone())); @@ -199,6 +192,7 @@ fn main_() -> Result<(), MainError> { let socket_path = Acceptor::install(&state)?; forker.setenv(b"WAYLAND_DISPLAY", socket_path.as_bytes()); let _xwayland = engine.spawn(xwayland::manage(state.clone())); + let _backend = engine.spawn(tasks::start_backend(state.clone())); el.run()?; drop(_xwayland); state.clients.clear(); diff --git a/src/state.rs b/src/state.rs index cac0eb77..473cb4ea 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,8 +1,5 @@ use crate::async_engine::{AsyncEngine, SpawnedFuture}; -use crate::backend::{ - Backend, BackendEvent, Keyboard, KeyboardId, KeyboardIds, MouseId, MouseIds, OutputId, - OutputIds, -}; +use crate::backend::{BackendEvent, InputDevice, InputDeviceId, InputDeviceIds, OutputId, OutputIds}; use crate::client::{Client, Clients}; use crate::config::ConfigProxy; use crate::cursor::ServerCursors; @@ -33,7 +30,6 @@ use std::rc::Rc; pub struct State { pub xkb_ctx: XkbContext, pub forker: CloneCell>>, - pub backend: CloneCell>, pub default_keymap: Rc, pub eng: Rc, pub el: Rc, @@ -45,14 +41,12 @@ pub struct State { pub globals: Globals, pub output_ids: OutputIds, pub seat_ids: SeatIds, - pub kb_ids: KeyboardIds, - pub mouse_ids: MouseIds, + pub input_device_ids: InputDeviceIds, pub node_ids: NodeIds, pub root: Rc, pub backend_events: AsyncQueue, pub output_handlers: RefCell>>, - pub mouse_handlers: RefCell>, - pub kb_handlers: RefCell>, + pub input_device_handlers: RefCell>, pub outputs: CopyHashMap>, pub seat_queue: LinkedList>, pub slow_clients: AsyncQueue>, @@ -67,16 +61,10 @@ pub struct State { pub dbus: Dbus, } -pub struct MouseData { +pub struct InputDeviceData { pub handler: SpawnedFuture<()>, - pub id: MouseId, - pub data: Rc, -} - -pub struct KeyboardData { - pub handler: SpawnedFuture<()>, - pub id: KeyboardId, - pub kb: Rc, + pub id: InputDeviceId, + pub device: Rc, pub data: Rc, } diff --git a/src/tasks/backend.rs b/src/tasks/backend.rs index e95ea1ba..7111cd9e 100644 --- a/src/tasks/backend.rs +++ b/src/tasks/backend.rs @@ -1,5 +1,5 @@ use crate::backend::{BackendEvent, Output}; -use crate::tasks::device; +use crate::tasks::input_device; use crate::tasks::output::OutputHandler; use crate::State; use std::rc::Rc; @@ -19,8 +19,7 @@ impl BackendEventHandler { fn handle_event(&mut self, event: BackendEvent) { match event { BackendEvent::NewOutput(output) => self.handle_new_output(output), - BackendEvent::NewMouse(s) => device::handle(&self.state, s), - BackendEvent::NewKeyboard(s) => device::handle(&self.state, s), + BackendEvent::NewInputDevice(s) => input_device::handle(&self.state, s), } } diff --git a/src/tasks/device.rs b/src/tasks/device.rs deleted file mode 100644 index b7a6dd6b..00000000 --- a/src/tasks/device.rs +++ /dev/null @@ -1,174 +0,0 @@ -use crate::async_engine::SpawnedFuture; -use crate::backend::{Keyboard, KeyboardEvent, Mouse, MouseEvent}; -use crate::config::ConfigProxy; -use crate::ifs::wl_seat::WlSeatGlobal; -use crate::state::{DeviceHandlerData, KeyboardData, MouseData}; -use crate::utils::asyncevent::AsyncEvent; -use crate::State; -use std::rc::Rc; - -pub trait DeviceApi: 'static { - type Event; - - fn on_change(&self, cb: Rc); - fn announce(&self, config: &ConfigProxy); - fn announce_del(&self, config: &ConfigProxy); - fn removed(&self) -> bool; - fn add(self: &Rc, state: &State, handler: SpawnedFuture<()>, data: Rc); - fn remove(&self, state: &State); - fn event(&self) -> Option; - fn send(seat: &Rc, event: Self::Event); -} - -impl DeviceApi for dyn Keyboard { - type Event = KeyboardEvent; - - fn on_change(&self, cb: Rc) { - self.on_change(cb); - } - - fn announce(&self, config: &ConfigProxy) { - config.new_keyboard(self.id()); - } - - fn announce_del(&self, config: &ConfigProxy) { - config.del_keyboard(self.id()); - } - - fn removed(&self) -> bool { - self.removed() - } - - fn add( - self: &Rc, - state: &State, - handler: SpawnedFuture<()>, - data: Rc, - ) { - state.kb_handlers.borrow_mut().insert( - self.id(), - KeyboardData { - handler, - id: self.id(), - kb: self.clone(), - data, - }, - ); - } - - fn remove(&self, state: &State) { - state.kb_handlers.borrow_mut().remove(&self.id()); - } - - fn event(&self) -> Option { - self.event() - } - - fn send(seat: &Rc, event: Self::Event) { - seat.kb_event(event); - } -} - -impl DeviceApi for dyn Mouse { - type Event = MouseEvent; - - fn on_change(&self, cb: Rc) { - self.on_change(cb); - } - - fn announce(&self, config: &ConfigProxy) { - config.new_mouse(self.id()); - } - - fn announce_del(&self, config: &ConfigProxy) { - config.del_mouse(self.id()); - } - - fn removed(&self) -> bool { - self.removed() - } - - fn add( - self: &Rc, - state: &State, - handler: SpawnedFuture<()>, - data: Rc, - ) { - state.mouse_handlers.borrow_mut().insert( - self.id(), - MouseData { - handler, - id: self.id(), - data, - }, - ); - } - - fn remove(&self, state: &State) { - state.mouse_handlers.borrow_mut().remove(&self.id()); - } - - fn event(&self) -> Option { - self.event() - } - - fn send(seat: &Rc, event: Self::Event) { - seat.mouse_event(event); - } -} - -pub fn handle(state: &Rc, dev: Rc) { - let data = Rc::new(DeviceHandlerData { - seat: Default::default(), - }); - let oh = DeviceHandler { - state: state.clone(), - dev: dev.clone(), - data: data.clone(), - }; - let handler = state.eng.spawn(oh.handle()); - dev.add(&state, handler, data); -} - -pub struct DeviceHandler { - pub state: Rc, - pub dev: Rc, - pub data: Rc, -} - -impl DeviceHandler { - pub async fn handle(self) { - let ae = Rc::new(AsyncEvent::default()); - { - let ae = ae.clone(); - self.dev.on_change(Rc::new(move || ae.trigger())); - } - if let Some(config) = self.state.config.get() { - self.dev.announce(&config); - } - loop { - if self.dev.removed() { - break; - } - if let Some(seat) = self.data.seat.get() { - let mut any_events = false; - while let Some(event) = self.dev.event() { - T::send(&seat, event); - any_events = true; - } - if any_events { - seat.mark_last_active(); - } - } else { - while self.dev.event().is_some() { - // nothing - } - } - ae.triggered().await; - } - if let Some(config) = self.state.config.get() { - self.dev.announce_del(&config); - } - self.dev.remove(&self.state); - } -} diff --git a/src/tasks/input_device.rs b/src/tasks/input_device.rs new file mode 100644 index 00000000..8abac35d --- /dev/null +++ b/src/tasks/input_device.rs @@ -0,0 +1,69 @@ +use crate::backend::{InputDevice}; +use crate::state::{DeviceHandlerData, InputDeviceData}; +use crate::utils::asyncevent::AsyncEvent; +use crate::State; +use std::rc::Rc; + +pub fn handle(state: &Rc, dev: Rc) { + let data = Rc::new(DeviceHandlerData { + seat: Default::default(), + }); + let oh = DeviceHandler { + state: state.clone(), + dev: dev.clone(), + data: data.clone(), + }; + let handler = state.eng.spawn(oh.handle()); + state.input_device_handlers.borrow_mut().insert( + dev.id(), + InputDeviceData { + handler, + id: dev.id(), + device: dev.clone(), + data, + }, + ); +} + +pub struct DeviceHandler { + pub state: Rc, + pub dev: Rc, + pub data: Rc, +} + +impl DeviceHandler { + pub async fn handle(self) { + let ae = Rc::new(AsyncEvent::default()); + { + let ae = ae.clone(); + self.dev.on_change(Rc::new(move || ae.trigger())); + } + 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; + while let Some(event) = self.dev.event() { + seat.event(event); + any_events = true; + } + if any_events { + seat.mark_last_active(); + } + } else { + while self.dev.event().is_some() { + // nothing + } + } + 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()); + } +} diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 4073466a..9b787a0e 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -1,12 +1,14 @@ mod backend; -mod device; +mod input_device; mod output; mod slow_clients; +mod start_backend; use crate::tasks::backend::BackendEventHandler; use crate::tasks::slow_clients::SlowClientHandler; use crate::State; use std::rc::Rc; +pub use start_backend::start_backend; pub async fn handle_backend_events(state: Rc) { let mut beh = BackendEventHandler { state }; diff --git a/src/tasks/start_backend.rs b/src/tasks/start_backend.rs new file mode 100644 index 00000000..c60d9a5c --- /dev/null +++ b/src/tasks/start_backend.rs @@ -0,0 +1,17 @@ +use std::future::pending; +use std::rc::Rc; +use crate::{ErrorFmt, metal, State, XorgBackend}; + +pub async fn start_backend(state: Rc) { + log::info!("Trying to start X backend"); + let e = match XorgBackend::new(&state) { + Ok(_b) => pending().await, + Err(e) => e, + }; + log::warn!("Could not start X backend: {}", ErrorFmt(e)); + log::info!("Trying to start metal backend"); + let e = metal::run(state.clone()).await; + log::error!("Metal backend failed: {}", ErrorFmt(e)); + log::warn!("Shutting down"); + state.el.stop(); +} diff --git a/src/udev.rs b/src/udev.rs index 7808a795..4073be66 100644 --- a/src/udev.rs +++ b/src/udev.rs @@ -38,6 +38,7 @@ extern "C" { fn udev_list_entry_get_next(list_entry: *mut udev_list_entry) -> *mut udev_list_entry; fn udev_list_entry_get_name(list_entry: *mut udev_list_entry) -> *const c::c_char; + #[allow(dead_code)] fn udev_list_entry_get_value(list_entry: *mut udev_list_entry) -> *const c::c_char; fn udev_device_new_from_syspath(udev: *mut udev, syspath: *const c::c_char) @@ -85,7 +86,7 @@ pub struct UdevMonitor { } pub struct UdevEnumerate { - udev: Rc, + _udev: Rc, enumerate: *mut udev_enumerate, } @@ -95,7 +96,7 @@ pub struct UdevListEntry<'a> { } pub struct UdevDevice { - udev: Rc, + _udev: Rc, device: *mut udev_device, } @@ -125,7 +126,7 @@ impl Udev { return Err(UdevError::NewEnumerate(Errno::default().into())); } Ok(UdevEnumerate { - udev: self.clone(), + _udev: self.clone(), enumerate: res, }) } @@ -140,7 +141,7 @@ impl Udev { return Err(UdevError::DeviceFromSyspath(Errno::default().into())); } Ok(UdevDevice { - udev: self.clone(), + _udev: self.clone(), device: res, }) } @@ -198,7 +199,7 @@ impl UdevMonitor { None } else { Some(UdevDevice { - udev: self.udev.clone(), + _udev: self.udev.clone(), device: res, }) } @@ -305,6 +306,7 @@ impl UdevDevice { unsafe { udev_device_get_devnum(self.device) } } + #[allow(dead_code)] pub fn is_initialized(&self) -> bool { unsafe { udev_device_get_is_initialized(self.device) != 0 } } diff --git a/src/utils/bitfield.rs b/src/utils/bitfield.rs index d5ad22e1..8e136115 100644 --- a/src/utils/bitfield.rs +++ b/src/utils/bitfield.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use std::mem; const SEG_SIZE: usize = 8 * mem::size_of::(); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 1461caf0..3a317ec8 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -20,3 +20,4 @@ pub mod tri; pub mod vasprintf; pub mod vec_ext; pub mod vecstorage; +pub mod syncqueue; diff --git a/src/utils/syncqueue.rs b/src/utils/syncqueue.rs new file mode 100644 index 00000000..d3467b04 --- /dev/null +++ b/src/utils/syncqueue.rs @@ -0,0 +1,29 @@ +use std::cell::UnsafeCell; +use std::collections::VecDeque; +use crate::utils::ptr_ext::MutPtrExt; + +pub struct SyncQueue { + el: UnsafeCell>, +} + +impl Default for SyncQueue { + fn default() -> Self { + Self { + el: Default::default(), + } + } +} + +impl SyncQueue { + pub fn push(&self, t: T) { + unsafe { + self.el.get().deref_mut().push_back(t); + } + } + + pub fn pop(&self) -> Option { + unsafe { + self.el.get().deref_mut().pop_front() + } + } +} diff --git a/src/xwayland/xwm.rs b/src/xwayland/xwm.rs index a7b0d047..00660140 100644 --- a/src/xwayland/xwm.rs +++ b/src/xwayland/xwm.rs @@ -107,8 +107,8 @@ pub struct Wm { c: RustConnection, atoms: Atoms, socket: AsyncFd, - root: Window, - xwin: Window, + _root: Window, + _xwin: Window, client: Rc, windows: AHashMap>, windows_by_surface_id: AHashMap>, @@ -228,8 +228,8 @@ impl Wm { c, atoms, socket: socket_dup, - root, - xwin, + _root: root, + _xwin: xwin, client, windows: Default::default(), windows_by_surface_id: Default::default(),