autocommit 2022-03-09 17:51:17 CET
This commit is contained in:
parent
4df6b559b7
commit
0399772467
35 changed files with 429 additions and 423 deletions
|
|
@ -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::mods::{Modifiers, ALT, CTRL, SHIFT};
|
||||||
use i4config::keyboard::syms::{
|
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,
|
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::Axis::{Horizontal, Vertical};
|
||||||
use i4config::Direction::{Down, Left, Right, Up};
|
use i4config::Direction::{Down, Left, Right, Up};
|
||||||
use i4config::{
|
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;
|
use rand::Rng;
|
||||||
|
|
||||||
|
|
@ -73,14 +73,12 @@ fn configure_seat(s: Seat) {
|
||||||
|
|
||||||
fn do_grab(s: Seat, grab: bool) {
|
fn do_grab(s: Seat, grab: bool) {
|
||||||
for device in s.input_devices() {
|
for device in s.input_devices() {
|
||||||
if let InputDevice::Keyboard(kb) = device {
|
log::info!(
|
||||||
log::info!(
|
"{}rabbing keyboard {:?}",
|
||||||
"{}rabbing keyboard {:?}",
|
if grab { "G" } else { "Ung" },
|
||||||
if grab { "G" } else { "Ung" },
|
device.0
|
||||||
kb.0
|
);
|
||||||
);
|
grab_input_device(device, grab);
|
||||||
grab_keyboard(kb, grab);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if grab {
|
if grab {
|
||||||
s.unbind(SYM_y);
|
s.unbind(SYM_y);
|
||||||
|
|
@ -99,7 +97,9 @@ pub fn configure() {
|
||||||
for device in input_devices() {
|
for device in input_devices() {
|
||||||
device.set_seat(seat);
|
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);
|
config!(configure);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::_private::ipc::{ClientMessage, InitMessage, Response, ServerMessage};
|
||||||
use crate::_private::{bincode_ops, logging, Config, ConfigEntry, ConfigEntryGen, VERSION};
|
use crate::_private::{bincode_ops, logging, Config, ConfigEntry, ConfigEntryGen, VERSION};
|
||||||
use crate::keyboard::keymap::Keymap;
|
use crate::keyboard::keymap::Keymap;
|
||||||
use crate::theme::Color;
|
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::cell::{Cell, RefCell};
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::collections::HashMap;
|
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 });
|
self.send(&ClientMessage::GrabKb { kb, grab });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::keyboard::keymap::Keymap;
|
||||||
use crate::keyboard::mods::Modifiers;
|
use crate::keyboard::mods::Modifiers;
|
||||||
use crate::keyboard::syms::KeySym;
|
use crate::keyboard::syms::KeySym;
|
||||||
use crate::theme::Color;
|
use crate::theme::Color;
|
||||||
use crate::{Axis, Direction, InputDevice, Keyboard, LogLevel, Seat};
|
use crate::{Axis, Direction, InputDevice, LogLevel, Seat};
|
||||||
use bincode::{BorrowDecode, Decode, Encode};
|
use bincode::{BorrowDecode, Decode, Encode};
|
||||||
|
|
||||||
#[derive(Encode, BorrowDecode, Debug)]
|
#[derive(Encode, BorrowDecode, Debug)]
|
||||||
|
|
@ -92,7 +92,7 @@ pub enum ClientMessage<'a> {
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
},
|
},
|
||||||
GrabKb {
|
GrabKb {
|
||||||
kb: Keyboard,
|
kb: InputDevice,
|
||||||
grab: bool,
|
grab: bool,
|
||||||
},
|
},
|
||||||
GetTitleHeight,
|
GetTitleHeight,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
get!().grab(kb, grab);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,16 +42,7 @@ impl Seat {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
#[derive(Encode, Decode, Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
pub struct Keyboard(pub u64);
|
pub struct InputDevice(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),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputDevice {
|
impl InputDevice {
|
||||||
pub fn set_seat(self, seat: Seat) {
|
pub fn set_seat(self, seat: Seat) {
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,6 @@ pub enum AsyncError {
|
||||||
WheelError(#[from] WheelError),
|
WheelError(#[from] WheelError),
|
||||||
#[error("The event loop caused an error: {0}")]
|
#[error("The event loop caused an error: {0}")]
|
||||||
EventLoopError(#[from] EventLoopError),
|
EventLoopError(#[from] EventLoopError),
|
||||||
#[error("The file descriptor is in an error state")]
|
|
||||||
FdError,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ use std::fmt::Debug;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
linear_ids!(OutputIds, OutputId);
|
linear_ids!(OutputIds, OutputId);
|
||||||
linear_ids!(KeyboardIds, KeyboardId);
|
linear_ids!(InputDeviceIds, InputDeviceId);
|
||||||
linear_ids!(MouseIds, MouseId);
|
|
||||||
|
|
||||||
pub trait Backend {}
|
pub trait Backend {}
|
||||||
|
|
||||||
|
|
@ -16,25 +15,17 @@ pub trait Output {
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>);
|
fn on_change(&self, cb: Rc<dyn Fn()>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Keyboard {
|
pub trait InputDevice {
|
||||||
fn id(&self) -> KeyboardId;
|
fn id(&self) -> InputDeviceId;
|
||||||
fn removed(&self) -> bool;
|
fn removed(&self) -> bool;
|
||||||
fn event(&self) -> Option<KeyboardEvent>;
|
fn event(&self) -> Option<InputEvent>;
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>);
|
fn on_change(&self, cb: Rc<dyn Fn()>);
|
||||||
fn grab(&self, grab: bool);
|
fn grab(&self, grab: bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Mouse {
|
|
||||||
fn id(&self) -> MouseId;
|
|
||||||
fn removed(&self) -> bool;
|
|
||||||
fn event(&self) -> Option<MouseEvent>;
|
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum BackendEvent {
|
pub enum BackendEvent {
|
||||||
NewOutput(Rc<dyn Output>),
|
NewOutput(Rc<dyn Output>),
|
||||||
NewKeyboard(Rc<dyn Keyboard>),
|
NewInputDevice(Rc<dyn InputDevice>),
|
||||||
NewMouse(Rc<dyn Mouse>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
|
@ -50,12 +41,8 @@ pub enum ScrollAxis {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum KeyboardEvent {
|
pub enum InputEvent {
|
||||||
Key(u32, KeyState),
|
Key(u32, KeyState),
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum MouseEvent {
|
|
||||||
OutputPosition(OutputId, Fixed, Fixed),
|
OutputPosition(OutputId, Fixed, Fixed),
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
Motion(Fixed, Fixed),
|
Motion(Fixed, Fixed),
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
use crate::backend::Backend;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub struct DummyBackend {}
|
|
||||||
|
|
||||||
impl DummyBackend {
|
|
||||||
pub fn new() -> Rc<Self> {
|
|
||||||
Rc::new(Self {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Backend for DummyBackend {}
|
|
||||||
|
|
@ -8,12 +8,15 @@ use crate::libinput::{LibInput, LibInputAdapter, LibInputError};
|
||||||
use crate::logind::{LogindError, Session};
|
use crate::logind::{LogindError, Session};
|
||||||
use crate::udev::{UdevError, UdevMonitor};
|
use crate::udev::{UdevError, UdevMonitor};
|
||||||
use crate::utils::copyhashmap::CopyHashMap;
|
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::cell::{Cell, RefCell};
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
use std::future::pending;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uapi::{c, OwnedFd};
|
use uapi::{c, OwnedFd};
|
||||||
|
use crate::backend::{Backend, InputDevice, InputDeviceId, InputEvent};
|
||||||
|
use crate::utils::syncqueue::SyncQueue;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum MetalError {
|
pub enum MetalError {
|
||||||
|
|
@ -31,11 +34,14 @@ pub enum MetalError {
|
||||||
LibInput(#[from] LibInputError),
|
LibInput(#[from] LibInputError),
|
||||||
#[error("Dupfd failed")]
|
#[error("Dupfd failed")]
|
||||||
Dup(#[source] crate::utils::oserror::OsError),
|
Dup(#[source] crate::utils::oserror::OsError),
|
||||||
|
#[error("Metal backend terminated unexpectedly")]
|
||||||
|
UnexpectedTermination,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(state: Rc<State>) {
|
pub async fn run(state: Rc<State>) -> MetalError {
|
||||||
if let Err(e) = run_(state).await {
|
match run_(state).await {
|
||||||
log::error!("{}", ErrorFmt(e));
|
Err(e) => e,
|
||||||
|
_ => MetalError::UnexpectedTermination,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +54,10 @@ struct MetalBackend {
|
||||||
libinput_fd: AsyncFd,
|
libinput_fd: AsyncFd,
|
||||||
device_holder: Rc<DeviceHolder>,
|
device_holder: Rc<DeviceHolder>,
|
||||||
session: Session,
|
session: Session,
|
||||||
ids: NumCell<u64>,
|
}
|
||||||
|
|
||||||
|
impl Backend for MetalBackend {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_(state: Rc<State>) -> Result<(), MetalError> {
|
async fn run_(state: Rc<State>) -> Result<(), MetalError> {
|
||||||
|
|
@ -89,26 +98,26 @@ async fn run_(state: Rc<State>) -> Result<(), MetalError> {
|
||||||
libinput_fd,
|
libinput_fd,
|
||||||
device_holder,
|
device_holder,
|
||||||
session,
|
session,
|
||||||
ids: Default::default(),
|
|
||||||
});
|
});
|
||||||
let _monitor = state.eng.spawn(metal.clone().monitor_devices());
|
let _monitor = state.eng.spawn(metal.clone().monitor_devices());
|
||||||
let _events = state.eng.spawn(metal.clone().handle_libinput_events());
|
let _events = state.eng.spawn(metal.clone().handle_libinput_events());
|
||||||
if let Err(e) = metal.enumerate_devices() {
|
if let Err(e) = metal.enumerate_devices() {
|
||||||
return Err(MetalError::Enumerate(Box::new(e)));
|
return Err(MetalError::Enumerate(Box::new(e)));
|
||||||
}
|
}
|
||||||
let queue = AsyncQueue::<String>::new();
|
pending().await
|
||||||
queue.pop().await;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MetalDevice {
|
struct MetalDevice {
|
||||||
slot: usize,
|
slot: usize,
|
||||||
device_id: u64,
|
id: InputDeviceId,
|
||||||
devnum: c::dev_t,
|
devnum: c::dev_t,
|
||||||
fd: CloneCell<Option<Rc<OwnedFd>>>,
|
fd: CloneCell<Option<Rc<OwnedFd>>>,
|
||||||
inputdev: Cell<Option<RegisteredDevice>>,
|
inputdev: Cell<Option<RegisteredDevice>>,
|
||||||
devnode: CString,
|
devnode: CString,
|
||||||
sysname: CString,
|
_sysname: CString,
|
||||||
|
removed: Cell<bool>,
|
||||||
|
events: SyncQueue<InputEvent>,
|
||||||
|
cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DeviceHolder {
|
struct DeviceHolder {
|
||||||
|
|
@ -135,8 +144,33 @@ impl LibInputAdapter for DeviceHolder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetalBackend {
|
impl InputDevice for MetalDevice {
|
||||||
fn id(&self) -> u64 {
|
fn id(&self) -> InputDeviceId {
|
||||||
self.ids.fetch_add(1)
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn removed(&self) -> bool {
|
||||||
|
self.removed.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn event(&self) -> Option<InputEvent> {
|
||||||
|
self.events.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,36 @@
|
||||||
use crate::async_engine::FdStatus;
|
use crate::async_engine::FdStatus;
|
||||||
use crate::libinput::consts::LIBINPUT_EVENT_KEYBOARD_KEY;
|
|
||||||
use crate::libinput::event::LibInputEvent;
|
use crate::libinput::event::LibInputEvent;
|
||||||
use crate::metal::MetalBackend;
|
use crate::metal::MetalBackend;
|
||||||
use crate::ErrorFmt;
|
use crate::ErrorFmt;
|
||||||
use std::rc::Rc;
|
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 {
|
impl MetalBackend {
|
||||||
pub async fn handle_libinput_events(self: Rc<Self>) {
|
pub async fn handle_libinput_events(self: Rc<Self>) {
|
||||||
|
|
@ -34,22 +61,40 @@ impl MetalBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_event(self: &Rc<Self>, event: LibInputEvent) {
|
fn handle_event(self: &Rc<Self>, event: LibInputEvent) {
|
||||||
|
use crate::libinput::consts as c;
|
||||||
|
|
||||||
match event.ty() {
|
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<Self>, event: LibInputEvent) {
|
fn handle_device_added(self: &Rc<Self>, _event: LibInputEvent) {
|
||||||
let event = match event.keyboard_event() {
|
// let dev = unpack!(self, event);
|
||||||
Some(event) => event,
|
}
|
||||||
_ => return,
|
|
||||||
|
fn handle_device_removed(self: &Rc<Self>, 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<Self>, 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!(
|
dev.event(InputEvent::Key(event.key(), state));
|
||||||
"key: {}, state: {:?}, time: {}",
|
}
|
||||||
event.key(),
|
|
||||||
event.key_state(),
|
fn handle_pointer_motion(self: &Rc<Self>, event: LibInputEvent) {
|
||||||
event.time_usec()
|
let (event, dev) = unpack!(self, event, pointer_event);
|
||||||
);
|
dev.event(InputEvent::Motion(event.dx().into(), event.dy().into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
|
use std::cell::Cell;
|
||||||
use crate::async_engine::FdStatus;
|
use crate::async_engine::FdStatus;
|
||||||
use crate::dbus::TRUE;
|
use crate::dbus::TRUE;
|
||||||
use crate::metal::{MetalBackend, MetalDevice, MetalError};
|
use crate::metal::{MetalBackend, MetalDevice, MetalError};
|
||||||
use crate::udev::UdevDevice;
|
use crate::udev::UdevDevice;
|
||||||
use crate::ErrorFmt;
|
use crate::ErrorFmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use crate::backend::BackendEvent;
|
||||||
|
|
||||||
impl MetalBackend {
|
impl MetalBackend {
|
||||||
pub async fn monitor_devices(self: Rc<Self>) {
|
pub async fn monitor_devices(self: Rc<Self>) {
|
||||||
|
|
@ -54,8 +56,11 @@ impl MetalBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_input_device(self: &Rc<Self>, dev: &UdevDevice) {
|
fn add_input_device(self: &Rc<Self>, dev: &UdevDevice) {
|
||||||
|
if !dev.is_initialized() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let slf = self.clone();
|
let slf = self.clone();
|
||||||
let device_id = self.id();
|
let device_id = self.state.input_device_ids.next();
|
||||||
let devnum = dev.devnum();
|
let devnum = dev.devnum();
|
||||||
let devnode = match dev.devnode() {
|
let devnode = match dev.devnode() {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
|
|
@ -83,12 +88,15 @@ impl MetalBackend {
|
||||||
};
|
};
|
||||||
let dev = Rc::new(MetalDevice {
|
let dev = Rc::new(MetalDevice {
|
||||||
slot,
|
slot,
|
||||||
device_id,
|
id: device_id,
|
||||||
devnum,
|
devnum,
|
||||||
fd: Default::default(),
|
fd: Default::default(),
|
||||||
inputdev: Default::default(),
|
inputdev: Default::default(),
|
||||||
devnode: devnode.to_owned(),
|
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());
|
slots[slot] = Some(dev.clone());
|
||||||
self.device_holder.input_devices.set(devnum, dev);
|
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 mut slots = slf.device_holder.input_devices_.borrow_mut();
|
||||||
let dev = 'dev: {
|
let dev = 'dev: {
|
||||||
if let Some(dev) = id.get(&devnum) {
|
if let Some(dev) = id.get(&devnum) {
|
||||||
if dev.device_id == device_id {
|
if dev.id == device_id {
|
||||||
break 'dev dev;
|
break 'dev dev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -126,6 +134,7 @@ impl MetalBackend {
|
||||||
};
|
};
|
||||||
inputdev.device().set_slot(slot);
|
inputdev.device().set_slot(slot);
|
||||||
dev.inputdev.set(Some(inputdev));
|
dev.inputdev.set(Some(inputdev));
|
||||||
|
slf.state.backend_events.push(BackendEvent::NewInputDevice(dev.clone()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod dummy;
|
|
||||||
pub mod metal;
|
pub mod metal;
|
||||||
pub mod xorg;
|
pub mod xorg;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::backend::{
|
use crate::backend::{Backend, BackendEvent, KeyState, InputEvent, Output, OutputId, ScrollAxis, InputDeviceId, InputDevice};
|
||||||
Backend, BackendEvent, KeyState, Keyboard, KeyboardEvent, KeyboardId, Mouse, MouseEvent,
|
|
||||||
MouseId, Output, OutputId, ScrollAxis,
|
|
||||||
};
|
|
||||||
use crate::drm::drm::{Drm, DrmError};
|
use crate::drm::drm::{Drm, DrmError};
|
||||||
use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING};
|
use crate::drm::gbm::{GbmDevice, GbmError, GBM_BO_USE_RENDERING};
|
||||||
use crate::drm::{ModifiedFormat, INVALID_MODIFIER};
|
use crate::drm::{ModifiedFormat, INVALID_MODIFIER};
|
||||||
|
|
@ -26,11 +23,13 @@ use thiserror::Error;
|
||||||
use uapi::{c, OwnedFd};
|
use uapi::{c, OwnedFd};
|
||||||
use xcb_dl::{ffi, Xcb, XcbDri3, XcbPresent, XcbRender, XcbXinput, XcbXkb};
|
use xcb_dl::{ffi, Xcb, XcbDri3, XcbPresent, XcbRender, XcbXinput, XcbXkb};
|
||||||
use xcb_dl_util::cursor::{XcbCursorContext, XcbCursorImage};
|
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;
|
use xcb_dl_util::xcb_box::XcbBox;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum XorgBackendError {
|
pub enum XorgBackendError {
|
||||||
|
#[error("Could not connect to the X server")]
|
||||||
|
CannotConnect(#[source] XcbConnectionError),
|
||||||
#[error("The xcb connection is in an error state")]
|
#[error("The xcb connection is in an error state")]
|
||||||
ErrorEvent,
|
ErrorEvent,
|
||||||
#[error("The drm subsystem returned an error")]
|
#[error("The drm subsystem returned an error")]
|
||||||
|
|
@ -97,6 +96,10 @@ impl XcbCon {
|
||||||
let render = Box::new(XcbRender::load_loose()?);
|
let render = Box::new(XcbRender::load_loose()?);
|
||||||
|
|
||||||
let c = xcb.xcb_connect(ptr::null(), ptr::null_mut());
|
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 errors = XcbErrorParser::new(&xcb, c);
|
||||||
|
|
||||||
let mut con = Self {
|
let mut con = Self {
|
||||||
|
|
@ -554,8 +557,8 @@ impl XorgBackend {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let seat = Rc::new(XorgSeat {
|
let seat = Rc::new(XorgSeat {
|
||||||
kb_id: self.state.kb_ids.next(),
|
kb_id: self.state.input_device_ids.next(),
|
||||||
mouse_id: self.state.mouse_ids.next(),
|
mouse_id: self.state.input_device_ids.next(),
|
||||||
backend: self.clone(),
|
backend: self.clone(),
|
||||||
kb: info.deviceid,
|
kb: info.deviceid,
|
||||||
mouse: info.attachment,
|
mouse: info.attachment,
|
||||||
|
|
@ -571,10 +574,10 @@ impl XorgBackend {
|
||||||
self.mouse_seats.set(info.attachment, seat.clone());
|
self.mouse_seats.set(info.attachment, seat.clone());
|
||||||
self.state
|
self.state
|
||||||
.backend_events
|
.backend_events
|
||||||
.push(BackendEvent::NewMouse(seat.clone()));
|
.push(BackendEvent::NewInputDevice(Rc::new(XorgSeatMouse(seat.clone()))));
|
||||||
self.state
|
self.state
|
||||||
.backend_events
|
.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),
|
7 => (ScrollAxis::Horizontal, 15),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
seat.mouse_event(MouseEvent::Scroll(val, axis));
|
seat.mouse_event(InputEvent::Scroll(val, axis));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const BTN_LEFT: u32 = 0x110;
|
const BTN_LEFT: u32 = 0x110;
|
||||||
|
|
@ -780,7 +783,7 @@ impl XorgBackend {
|
||||||
3 => BTN_RIGHT,
|
3 => BTN_RIGHT,
|
||||||
n => BTN_SIDE + n - 8,
|
n => BTN_SIDE + n - 8,
|
||||||
};
|
};
|
||||||
seat.mouse_event(MouseEvent::Button(button, state));
|
seat.mouse_event(InputEvent::Button(button, state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -800,7 +803,7 @@ impl XorgBackend {
|
||||||
let event =
|
let event =
|
||||||
unsafe { (event as *const _ as *const ffi::xcb_input_key_press_event_t).deref() };
|
unsafe { (event as *const _ as *const ffi::xcb_input_key_press_event_t).deref() };
|
||||||
if let Some(seat) = self.seats.get(&event.deviceid) {
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -843,7 +846,7 @@ impl XorgBackend {
|
||||||
self.outputs.get(&event.event),
|
self.outputs.get(&event.event),
|
||||||
self.mouse_seats.get(&event.deviceid),
|
self.mouse_seats.get(&event.deviceid),
|
||||||
) {
|
) {
|
||||||
seat.mouse_event(MouseEvent::OutputPosition(
|
seat.mouse_event(InputEvent::OutputPosition(
|
||||||
win.id,
|
win.id,
|
||||||
Fixed::from_1616(event.event_x),
|
Fixed::from_1616(event.event_x),
|
||||||
Fixed::from_1616(event.event_y),
|
Fixed::from_1616(event.event_y),
|
||||||
|
|
@ -864,7 +867,7 @@ impl XorgBackend {
|
||||||
(Some(a), Some(b)) => (a, b),
|
(Some(a), Some(b)) => (a, b),
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
};
|
};
|
||||||
seat.mouse_event(MouseEvent::OutputPosition(
|
seat.mouse_event(InputEvent::OutputPosition(
|
||||||
win.id,
|
win.id,
|
||||||
Fixed::from_1616(event.event_x),
|
Fixed::from_1616(event.event_x),
|
||||||
Fixed::from_1616(event.event_y),
|
Fixed::from_1616(event.event_y),
|
||||||
|
|
@ -997,19 +1000,23 @@ impl Output for XorgOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XorgSeat {
|
struct XorgSeat {
|
||||||
kb_id: KeyboardId,
|
kb_id: InputDeviceId,
|
||||||
mouse_id: MouseId,
|
mouse_id: InputDeviceId,
|
||||||
backend: Rc<XorgBackend>,
|
backend: Rc<XorgBackend>,
|
||||||
kb: ffi::xcb_input_device_id_t,
|
kb: ffi::xcb_input_device_id_t,
|
||||||
mouse: ffi::xcb_input_device_id_t,
|
mouse: ffi::xcb_input_device_id_t,
|
||||||
removed: Cell<bool>,
|
removed: Cell<bool>,
|
||||||
kb_cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
kb_cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
||||||
mouse_cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
mouse_cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
||||||
kb_events: RefCell<VecDeque<KeyboardEvent>>,
|
kb_events: RefCell<VecDeque<InputEvent>>,
|
||||||
mouse_events: RefCell<VecDeque<MouseEvent>>,
|
mouse_events: RefCell<VecDeque<InputEvent>>,
|
||||||
button_map: CopyHashMap<u32, u32>,
|
button_map: CopyHashMap<u32, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct XorgSeatKeyboard(Rc<XorgSeat>);
|
||||||
|
|
||||||
|
struct XorgSeatMouse(Rc<XorgSeat>);
|
||||||
|
|
||||||
impl XorgSeat {
|
impl XorgSeat {
|
||||||
fn kb_changed(&self) {
|
fn kb_changed(&self) {
|
||||||
if let Some(cb) = self.kb_cb.get() {
|
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_events.borrow_mut().push_back(event);
|
||||||
self.mouse_changed();
|
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_events.borrow_mut().push_back(event);
|
||||||
self.kb_changed();
|
self.kb_changed();
|
||||||
}
|
}
|
||||||
|
|
@ -1066,26 +1073,26 @@ impl XorgSeat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Keyboard for XorgSeat {
|
impl InputDevice for XorgSeatKeyboard {
|
||||||
fn id(&self) -> KeyboardId {
|
fn id(&self) -> InputDeviceId {
|
||||||
self.kb_id
|
self.0.kb_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn removed(&self) -> bool {
|
fn removed(&self) -> bool {
|
||||||
self.removed.get()
|
self.0.removed.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event(&self) -> Option<KeyboardEvent> {
|
fn event(&self) -> Option<InputEvent> {
|
||||||
self.kb_events.borrow_mut().pop_front()
|
self.0.kb_events.borrow_mut().pop_front()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
||||||
self.kb_cb.set(Some(cb));
|
self.0.kb_cb.set(Some(cb));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn grab(&self, grab: bool) {
|
fn grab(&self, grab: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let con = &self.backend.con;
|
let con = &self.0.backend.con;
|
||||||
let mut err = ptr::null_mut();
|
let mut err = ptr::null_mut();
|
||||||
if grab {
|
if grab {
|
||||||
let res = con.input.xcb_input_xi_grab_device(
|
let res = con.input.xcb_input_xi_grab_device(
|
||||||
|
|
@ -1093,7 +1100,7 @@ impl Keyboard for XorgSeat {
|
||||||
con.screen.root,
|
con.screen.root,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
self.kb,
|
self.0.kb,
|
||||||
ffi::XCB_GRAB_MODE_ASYNC as _,
|
ffi::XCB_GRAB_MODE_ASYNC as _,
|
||||||
ffi::XCB_GRAB_MODE_ASYNC as _,
|
ffi::XCB_GRAB_MODE_ASYNC as _,
|
||||||
1,
|
1,
|
||||||
|
|
@ -1106,39 +1113,43 @@ impl Keyboard for XorgSeat {
|
||||||
let res = match con.check(res, err) {
|
let res = match con.check(res, err) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Could not grab device {}: {}", self.kb, ErrorFmt(e));
|
log::error!("Could not grab device {}: {}", self.0.kb, ErrorFmt(e));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if res.status != ffi::XCB_GRAB_STATUS_SUCCESS as _ {
|
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 {
|
} else {
|
||||||
let cookie = con
|
let cookie = con
|
||||||
.input
|
.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) {
|
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 {
|
impl InputDevice for XorgSeatMouse {
|
||||||
fn id(&self) -> MouseId {
|
fn id(&self) -> InputDeviceId {
|
||||||
self.mouse_id
|
self.0.mouse_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn removed(&self) -> bool {
|
fn removed(&self) -> bool {
|
||||||
self.removed.get()
|
self.0.removed.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event(&self) -> Option<MouseEvent> {
|
fn event(&self) -> Option<InputEvent> {
|
||||||
self.mouse_events.borrow_mut().pop_front()
|
self.0.mouse_events.borrow_mut().pop_front()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
||||||
self.mouse_cb.set(Some(cb));
|
self.0.mouse_cb.set(Some(cb));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn grab(&self, _grab: bool) {
|
||||||
|
log::error!("Cannot grab xorg mouse");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
mod handler;
|
mod handler;
|
||||||
|
|
||||||
use crate::backend::{KeyboardId, MouseId};
|
|
||||||
use crate::config::handler::ConfigProxyHandler;
|
use crate::config::handler::ConfigProxyHandler;
|
||||||
use crate::ifs::wl_seat::SeatId;
|
use crate::ifs::wl_seat::SeatId;
|
||||||
use crate::utils::ptr_ext::PtrExt;
|
use crate::utils::ptr_ext::PtrExt;
|
||||||
|
|
@ -8,12 +7,13 @@ use crate::{NumCell, State};
|
||||||
use i4config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage};
|
use i4config::_private::ipc::{InitMessage, ServerMessage, V1InitMessage};
|
||||||
use i4config::_private::{bincode_ops, ConfigEntry, VERSION};
|
use i4config::_private::{bincode_ops, ConfigEntry, VERSION};
|
||||||
use i4config::keyboard::ModifiedKeySym;
|
use i4config::keyboard::ModifiedKeySym;
|
||||||
use i4config::{InputDevice, Keyboard, Mouse, Seat};
|
use i4config::{InputDevice, Seat};
|
||||||
use libloading::Library;
|
use libloading::Library;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use crate::backend::InputDeviceId;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum ConfigError {
|
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 {
|
self.handler.send(&ServerMessage::NewInputDevice {
|
||||||
device: InputDevice::Keyboard(Keyboard(kb.raw() as _)),
|
device: InputDevice(dev.raw() as _),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_mouse(&self, mouse: MouseId) {
|
pub fn del_input_device(&self, dev: InputDeviceId) {
|
||||||
self.handler.send(&ServerMessage::NewInputDevice {
|
|
||||||
device: InputDevice::Mouse(Mouse(mouse.raw() as _)),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn del_keyboard(&self, kb: KeyboardId) {
|
|
||||||
self.handler.send(&ServerMessage::DelInputDevice {
|
self.handler.send(&ServerMessage::DelInputDevice {
|
||||||
device: InputDevice::Keyboard(Keyboard(kb.raw() as _)),
|
device: InputDevice(dev.raw() as _),
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn del_mouse(&self, mouse: MouseId) {
|
|
||||||
self.handler.send(&ServerMessage::DelInputDevice {
|
|
||||||
device: InputDevice::Mouse(Mouse(mouse.raw() as _)),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::backend::{KeyboardId, MouseId};
|
|
||||||
use crate::ifs::wl_seat::{SeatId, WlSeatGlobal};
|
use crate::ifs::wl_seat::{SeatId, WlSeatGlobal};
|
||||||
use crate::state::DeviceHandlerData;
|
use crate::state::DeviceHandlerData;
|
||||||
use crate::tree::walker::NodeVisitorBase;
|
use crate::tree::walker::NodeVisitorBase;
|
||||||
|
|
@ -14,12 +13,13 @@ use i4config::_private::ipc::{ClientMessage, Response, ServerMessage};
|
||||||
use i4config::keyboard::keymap::Keymap;
|
use i4config::keyboard::keymap::Keymap;
|
||||||
use i4config::keyboard::mods::Modifiers;
|
use i4config::keyboard::mods::Modifiers;
|
||||||
use i4config::keyboard::syms::KeySym;
|
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 libloading::Library;
|
||||||
use log::Level;
|
use log::Level;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use crate::backend::InputDeviceId;
|
||||||
|
|
||||||
pub(super) struct ConfigProxyHandler {
|
pub(super) struct ConfigProxyHandler {
|
||||||
pub client_data: Cell<*const u8>,
|
pub client_data: Cell<*const u8>,
|
||||||
|
|
@ -156,20 +156,12 @@ impl ConfigProxyHandler {
|
||||||
&self,
|
&self,
|
||||||
device: InputDevice,
|
device: InputDevice,
|
||||||
) -> Result<Rc<DeviceHandlerData>, CphError> {
|
) -> Result<Rc<DeviceHandlerData>, CphError> {
|
||||||
let data = match device {
|
let data = self
|
||||||
InputDevice::Keyboard(kb) => self
|
|
||||||
.state
|
.state
|
||||||
.kb_handlers
|
.input_device_handlers
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.get(&KeyboardId::from_raw(kb.0 as _))
|
.get(&InputDeviceId::from_raw(device.0 as _))
|
||||||
.map(|d| d.data.clone()),
|
.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()),
|
|
||||||
};
|
|
||||||
match data {
|
match data {
|
||||||
Some(d) => Ok(d),
|
Some(d) => Ok(d),
|
||||||
_ => Err(CphError::DeviceDoesNotExist(device)),
|
_ => Err(CphError::DeviceDoesNotExist(device)),
|
||||||
|
|
@ -186,11 +178,11 @@ impl ConfigProxyHandler {
|
||||||
Err(CphError::SeatDoesNotExist(seat))
|
Err(CphError::SeatDoesNotExist(seat))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_kb(&self, kb: Keyboard) -> Result<Rc<dyn backend::Keyboard>, CphError> {
|
fn get_kb(&self, kb: InputDevice) -> Result<Rc<dyn backend::InputDevice>, CphError> {
|
||||||
let kbs = self.state.kb_handlers.borrow_mut();
|
let kbs = self.state.input_device_handlers.borrow_mut();
|
||||||
match kbs.get(&(KeyboardId::from_raw(kb.0 as _))) {
|
match kbs.get(&(InputDeviceId::from_raw(kb.0 as _))) {
|
||||||
None => Err(CphError::KeyboardDoesNotExist(kb)),
|
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 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() {
|
for dev in devs.values() {
|
||||||
if matches(&dev.data) {
|
if matches(&dev.data) {
|
||||||
res.push(InputDevice::Keyboard(Keyboard(dev.id.raw() as _)));
|
res.push(InputDevice(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 _)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -314,7 +298,7 @@ impl ConfigProxyHandler {
|
||||||
Ok(())
|
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)?;
|
let kb = self.get_kb(kb)?;
|
||||||
kb.grab(grab);
|
kb.grab(grab);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -532,7 +516,7 @@ enum CphError {
|
||||||
#[error("Seat {0:?} does not exist")]
|
#[error("Seat {0:?} does not exist")]
|
||||||
SeatDoesNotExist(Seat),
|
SeatDoesNotExist(Seat),
|
||||||
#[error("Keyboard {0:?} does not exist")]
|
#[error("Keyboard {0:?} does not exist")]
|
||||||
KeyboardDoesNotExist(Keyboard),
|
KeyboardDoesNotExist(InputDevice),
|
||||||
#[error("Could not parse the message")]
|
#[error("Could not parse the message")]
|
||||||
ParsingFailed(#[source] DecodeError),
|
ParsingFailed(#[source] DecodeError),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,9 @@ const MSG_ERROR: u8 = 3;
|
||||||
const MSG_SIGNAL: u8 = 4;
|
const MSG_SIGNAL: u8 = 4;
|
||||||
|
|
||||||
const NO_REPLY_EXPECTED: u8 = 0x1;
|
const NO_REPLY_EXPECTED: u8 = 0x1;
|
||||||
|
#[allow(dead_code)]
|
||||||
const NO_AUTO_START: u8 = 0x2;
|
const NO_AUTO_START: u8 = 0x2;
|
||||||
|
#[allow(dead_code)]
|
||||||
const ALLOW_INTERACTIVE_AUTHORIZATION: u8 = 0x4;
|
const ALLOW_INTERACTIVE_AUTHORIZATION: u8 = 0x4;
|
||||||
|
|
||||||
pub const BUS_DEST: &'static str = "org.freedesktop.DBus";
|
pub const BUS_DEST: &'static str = "org.freedesktop.DBus";
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ impl DbusSocket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn call_noreply<'a, T: MethodCall<'a>>(&self, destination: &str, path: &str, msg: T) {
|
pub fn call_noreply<'a, T: MethodCall<'a>>(&self, destination: &str, path: &str, msg: T) {
|
||||||
if !self.dead.get() {
|
if !self.dead.get() {
|
||||||
self.send_call(path, destination, NO_REPLY_EXPECTED, &msg);
|
self.send_call(path, destination, NO_REPLY_EXPECTED, &msg);
|
||||||
|
|
@ -89,6 +90,7 @@ impl DbusSocket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn get<T, F>(&self, destination: &str, path: &str, f: F)
|
pub fn get<T, F>(&self, destination: &str, path: &str, f: F)
|
||||||
where
|
where
|
||||||
T: Property,
|
T: Property,
|
||||||
|
|
@ -120,6 +122,7 @@ impl DbusSocket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn handle_signal<T, F>(
|
pub fn handle_signal<T, F>(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
sender: Option<&str>,
|
sender: Option<&str>,
|
||||||
|
|
|
||||||
|
|
@ -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::client::{Client, ClientId};
|
||||||
use crate::fixed::Fixed;
|
use crate::fixed::Fixed;
|
||||||
use crate::ifs::ipc;
|
use crate::ifs::ipc;
|
||||||
|
|
@ -114,18 +114,13 @@ impl NodeSeatState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
pub fn kb_event(self: &Rc<Self>, event: KeyboardEvent) {
|
pub fn event(self: &Rc<Self>, event: InputEvent) {
|
||||||
match event {
|
match event {
|
||||||
KeyboardEvent::Key(k, s) => self.key_event(k, s),
|
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),
|
||||||
pub fn mouse_event(self: &Rc<Self>, event: MouseEvent) {
|
InputEvent::Scroll(d, a) => self.pointer_owner.scroll(self, d, a),
|
||||||
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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,6 +136,7 @@ impl WlSeatGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn motion_event(self: &Rc<Self>, dx: Fixed, dy: Fixed) {
|
fn motion_event(self: &Rc<Self>, dx: Fixed, dy: Fixed) {
|
||||||
|
log::info!("motion: {}x{}", dx, dy);
|
||||||
let (x, y) = self.pos.get();
|
let (x, y) = self.pos.get();
|
||||||
self.set_new_position(x + dx, y + dy);
|
self.set_new_position(x + dx, y + dy);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ pub enum LibInputError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LibInput {
|
pub struct LibInput {
|
||||||
data: Box<UserData>,
|
_data: Box<UserData>,
|
||||||
li: *mut libinput,
|
li: *mut libinput,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ impl LibInput {
|
||||||
};
|
};
|
||||||
libinput_log_set_priority(li, priority.raw() as _);
|
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 {
|
pub fn fd(&self) -> c::c_int {
|
||||||
|
|
@ -122,7 +122,7 @@ impl LibInput {
|
||||||
libinput_device_ref(res);
|
libinput_device_ref(res);
|
||||||
}
|
}
|
||||||
Ok(RegisteredDevice {
|
Ok(RegisteredDevice {
|
||||||
li: self.clone(),
|
_li: self.clone(),
|
||||||
dev: res,
|
dev: res,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
use crate::libinput::sys::{
|
use crate::libinput::sys::{libinput_device, libinput_device_get_user_data, libinput_device_set_user_data, libinput_device_unref, libinput_path_remove_device};
|
||||||
libinput_device, libinput_device_set_user_data, libinput_device_unref,
|
|
||||||
libinput_path_remove_device,
|
|
||||||
};
|
|
||||||
use crate::libinput::LibInput;
|
use crate::libinput::LibInput;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
@ -12,7 +9,7 @@ pub struct LibInputDevice<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RegisteredDevice {
|
pub struct RegisteredDevice {
|
||||||
pub(super) li: Rc<LibInput>,
|
pub(super) _li: Rc<LibInput>,
|
||||||
pub(super) dev: *mut libinput_device,
|
pub(super) dev: *mut libinput_device,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,6 +27,15 @@ impl<'a> LibInputDevice<'a> {
|
||||||
libinput_device_set_user_data(self.dev, slot as _);
|
libinput_device_set_user_data(self.dev, slot as _);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn slot(&self) -> Option<usize> {
|
||||||
|
let res = unsafe { libinput_device_get_user_data(self.dev) as usize };
|
||||||
|
if res == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(res - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegisteredDevice {
|
impl RegisteredDevice {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
use crate::libinput::consts::{EventType, KeyState};
|
use crate::libinput::consts::{EventType, KeyState};
|
||||||
use crate::libinput::device::LibInputDevice;
|
use crate::libinput::device::LibInputDevice;
|
||||||
use crate::libinput::sys::{
|
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};
|
||||||
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 std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub struct LibInputEvent<'a> {
|
pub struct LibInputEvent<'a> {
|
||||||
|
|
@ -18,6 +13,11 @@ pub struct LibInputEventKeyboard<'a> {
|
||||||
pub(super) _phantom: PhantomData<&'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> {
|
impl<'a> Drop for LibInputEvent<'a> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
@ -49,6 +49,18 @@ impl<'a> LibInputEvent<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pointer_event(&self) -> Option<LibInputEventPointer> {
|
||||||
|
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> {
|
impl<'a> LibInputEventKeyboard<'a> {
|
||||||
|
|
@ -60,7 +72,23 @@ impl<'a> LibInputEventKeyboard<'a> {
|
||||||
unsafe { KeyState(libinput_event_keyboard_get_key_state(self.event)) }
|
unsafe { KeyState(libinput_event_keyboard_get_key_state(self.event)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn time_usec(&self) -> u64 {
|
pub fn time_usec(&self) -> u64 {
|
||||||
unsafe { libinput_event_keyboard_get_time_usec(self.event) }
|
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) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ extern "C" {
|
||||||
pub type libinput_device;
|
pub type libinput_device;
|
||||||
pub type libinput_event;
|
pub type libinput_event;
|
||||||
pub type libinput_event_keyboard;
|
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_handler(libinput: *mut libinput, log_handler: libinput_log_handler);
|
||||||
pub fn libinput_log_set_priority(libinput: *mut libinput, priority: libinput_log_priority);
|
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_destroy(event: *mut libinput_event);
|
||||||
pub fn libinput_event_get_type(event: *mut libinput_event) -> libinput_event_type;
|
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_device(event: *mut libinput_event) -> *mut libinput_device;
|
||||||
|
|
||||||
pub fn libinput_event_get_keyboard_event(
|
pub fn libinput_event_get_keyboard_event(
|
||||||
event: *mut libinput_event,
|
event: *mut libinput_event,
|
||||||
) -> *mut libinput_event_keyboard;
|
) -> *mut libinput_event_keyboard;
|
||||||
|
|
||||||
pub fn libinput_event_keyboard_get_key(event: *mut libinput_event_keyboard) -> u32;
|
pub fn libinput_event_keyboard_get_key(event: *mut libinput_event_keyboard) -> u32;
|
||||||
pub fn libinput_event_keyboard_get_key_state(
|
pub fn libinput_event_keyboard_get_key_state(
|
||||||
event: *mut libinput_event_keyboard,
|
event: *mut libinput_event_keyboard,
|
||||||
) -> libinput_key_state;
|
) -> libinput_key_state;
|
||||||
pub fn libinput_event_keyboard_get_time_usec(event: *mut libinput_event_keyboard) -> u64;
|
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)]
|
#[repr(C)]
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ pub enum LogindError {
|
||||||
|
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
socket: Rc<DbusSocket>,
|
socket: Rc<DbusSocket>,
|
||||||
seat: String,
|
_seat: String,
|
||||||
session_path: String,
|
session_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ impl Session {
|
||||||
};
|
};
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
socket: socket.clone(),
|
socket: socket.clone(),
|
||||||
seat,
|
_seat: seat,
|
||||||
session_path,
|
session_path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
src/main.rs
14
src/main.rs
|
|
@ -16,9 +16,8 @@
|
||||||
|
|
||||||
use crate::acceptor::AcceptorError;
|
use crate::acceptor::AcceptorError;
|
||||||
use crate::async_engine::{AsyncError, Phase};
|
use crate::async_engine::{AsyncError, Phase};
|
||||||
use crate::backends::dummy::DummyBackend;
|
|
||||||
use crate::backends::metal;
|
use crate::backends::metal;
|
||||||
use crate::backends::xorg::XorgBackendError;
|
use crate::backends::xorg::{XorgBackend, XorgBackendError};
|
||||||
use crate::client::Clients;
|
use crate::client::Clients;
|
||||||
use crate::clientmem::ClientMemError;
|
use crate::clientmem::ClientMemError;
|
||||||
use crate::dbus::{Dbus, FALSE};
|
use crate::dbus::{Dbus, FALSE};
|
||||||
|
|
@ -150,7 +149,6 @@ fn main_() -> Result<(), MainError> {
|
||||||
let state = Rc::new(State {
|
let state = Rc::new(State {
|
||||||
xkb_ctx,
|
xkb_ctx,
|
||||||
forker: Default::default(),
|
forker: Default::default(),
|
||||||
backend: CloneCell::new(DummyBackend::new()),
|
|
||||||
default_keymap: xkb_keymap,
|
default_keymap: xkb_keymap,
|
||||||
eng: engine.clone(),
|
eng: engine.clone(),
|
||||||
el: el.clone(),
|
el: el.clone(),
|
||||||
|
|
@ -165,17 +163,15 @@ fn main_() -> Result<(), MainError> {
|
||||||
node_ids,
|
node_ids,
|
||||||
backend_events: AsyncQueue::new(),
|
backend_events: AsyncQueue::new(),
|
||||||
output_handlers: Default::default(),
|
output_handlers: Default::default(),
|
||||||
mouse_handlers: Default::default(),
|
|
||||||
seat_ids: Default::default(),
|
seat_ids: Default::default(),
|
||||||
kb_ids: Default::default(),
|
|
||||||
outputs: Default::default(),
|
outputs: Default::default(),
|
||||||
seat_queue: Default::default(),
|
seat_queue: Default::default(),
|
||||||
slow_clients: AsyncQueue::new(),
|
slow_clients: AsyncQueue::new(),
|
||||||
none_surface_ext: Rc::new(NoneSurfaceExt),
|
none_surface_ext: Rc::new(NoneSurfaceExt),
|
||||||
tree_changed_sent: Cell::new(false),
|
tree_changed_sent: Cell::new(false),
|
||||||
config: Default::default(),
|
config: Default::default(),
|
||||||
mouse_ids: Default::default(),
|
input_device_ids: Default::default(),
|
||||||
kb_handlers: Default::default(),
|
input_device_handlers: Default::default(),
|
||||||
theme: Default::default(),
|
theme: Default::default(),
|
||||||
pending_container_layout: Default::default(),
|
pending_container_layout: Default::default(),
|
||||||
pending_container_titles: Default::default(),
|
pending_container_titles: Default::default(),
|
||||||
|
|
@ -183,10 +179,7 @@ fn main_() -> Result<(), MainError> {
|
||||||
pending_float_titles: Default::default(),
|
pending_float_titles: Default::default(),
|
||||||
dbus: Dbus::new(&engine, &run_toplevel),
|
dbus: Dbus::new(&engine, &run_toplevel),
|
||||||
});
|
});
|
||||||
let _future = state.eng.spawn(metal::run(state.clone()));
|
|
||||||
forker.install(&state);
|
forker.install(&state);
|
||||||
// let backend = XorgBackend::new(&state)?;
|
|
||||||
// state.backend.set(backend);
|
|
||||||
let config = config::ConfigProxy::default(&state);
|
let config = config::ConfigProxy::default(&state);
|
||||||
state.config.set(Some(Rc::new(config)));
|
state.config.set(Some(Rc::new(config)));
|
||||||
let _global_event_handler = engine.spawn(tasks::handle_backend_events(state.clone()));
|
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)?;
|
let socket_path = Acceptor::install(&state)?;
|
||||||
forker.setenv(b"WAYLAND_DISPLAY", socket_path.as_bytes());
|
forker.setenv(b"WAYLAND_DISPLAY", socket_path.as_bytes());
|
||||||
let _xwayland = engine.spawn(xwayland::manage(state.clone()));
|
let _xwayland = engine.spawn(xwayland::manage(state.clone()));
|
||||||
|
let _backend = engine.spawn(tasks::start_backend(state.clone()));
|
||||||
el.run()?;
|
el.run()?;
|
||||||
drop(_xwayland);
|
drop(_xwayland);
|
||||||
state.clients.clear();
|
state.clients.clear();
|
||||||
|
|
|
||||||
24
src/state.rs
24
src/state.rs
|
|
@ -1,8 +1,5 @@
|
||||||
use crate::async_engine::{AsyncEngine, SpawnedFuture};
|
use crate::async_engine::{AsyncEngine, SpawnedFuture};
|
||||||
use crate::backend::{
|
use crate::backend::{BackendEvent, InputDevice, InputDeviceId, InputDeviceIds, OutputId, OutputIds};
|
||||||
Backend, BackendEvent, Keyboard, KeyboardId, KeyboardIds, MouseId, MouseIds, OutputId,
|
|
||||||
OutputIds,
|
|
||||||
};
|
|
||||||
use crate::client::{Client, Clients};
|
use crate::client::{Client, Clients};
|
||||||
use crate::config::ConfigProxy;
|
use crate::config::ConfigProxy;
|
||||||
use crate::cursor::ServerCursors;
|
use crate::cursor::ServerCursors;
|
||||||
|
|
@ -33,7 +30,6 @@ use std::rc::Rc;
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub xkb_ctx: XkbContext,
|
pub xkb_ctx: XkbContext,
|
||||||
pub forker: CloneCell<Option<Rc<ForkerProxy>>>,
|
pub forker: CloneCell<Option<Rc<ForkerProxy>>>,
|
||||||
pub backend: CloneCell<Rc<dyn Backend>>,
|
|
||||||
pub default_keymap: Rc<XkbKeymap>,
|
pub default_keymap: Rc<XkbKeymap>,
|
||||||
pub eng: Rc<AsyncEngine>,
|
pub eng: Rc<AsyncEngine>,
|
||||||
pub el: Rc<EventLoop>,
|
pub el: Rc<EventLoop>,
|
||||||
|
|
@ -45,14 +41,12 @@ pub struct State {
|
||||||
pub globals: Globals,
|
pub globals: Globals,
|
||||||
pub output_ids: OutputIds,
|
pub output_ids: OutputIds,
|
||||||
pub seat_ids: SeatIds,
|
pub seat_ids: SeatIds,
|
||||||
pub kb_ids: KeyboardIds,
|
pub input_device_ids: InputDeviceIds,
|
||||||
pub mouse_ids: MouseIds,
|
|
||||||
pub node_ids: NodeIds,
|
pub node_ids: NodeIds,
|
||||||
pub root: Rc<DisplayNode>,
|
pub root: Rc<DisplayNode>,
|
||||||
pub backend_events: AsyncQueue<BackendEvent>,
|
pub backend_events: AsyncQueue<BackendEvent>,
|
||||||
pub output_handlers: RefCell<AHashMap<OutputId, SpawnedFuture<()>>>,
|
pub output_handlers: RefCell<AHashMap<OutputId, SpawnedFuture<()>>>,
|
||||||
pub mouse_handlers: RefCell<AHashMap<MouseId, MouseData>>,
|
pub input_device_handlers: RefCell<AHashMap<InputDeviceId, InputDeviceData>>,
|
||||||
pub kb_handlers: RefCell<AHashMap<KeyboardId, KeyboardData>>,
|
|
||||||
pub outputs: CopyHashMap<OutputId, Rc<WlOutputGlobal>>,
|
pub outputs: CopyHashMap<OutputId, Rc<WlOutputGlobal>>,
|
||||||
pub seat_queue: LinkedList<Rc<WlSeatGlobal>>,
|
pub seat_queue: LinkedList<Rc<WlSeatGlobal>>,
|
||||||
pub slow_clients: AsyncQueue<Rc<Client>>,
|
pub slow_clients: AsyncQueue<Rc<Client>>,
|
||||||
|
|
@ -67,16 +61,10 @@ pub struct State {
|
||||||
pub dbus: Dbus,
|
pub dbus: Dbus,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MouseData {
|
pub struct InputDeviceData {
|
||||||
pub handler: SpawnedFuture<()>,
|
pub handler: SpawnedFuture<()>,
|
||||||
pub id: MouseId,
|
pub id: InputDeviceId,
|
||||||
pub data: Rc<DeviceHandlerData>,
|
pub device: Rc<dyn InputDevice>,
|
||||||
}
|
|
||||||
|
|
||||||
pub struct KeyboardData {
|
|
||||||
pub handler: SpawnedFuture<()>,
|
|
||||||
pub id: KeyboardId,
|
|
||||||
pub kb: Rc<dyn Keyboard>,
|
|
||||||
pub data: Rc<DeviceHandlerData>,
|
pub data: Rc<DeviceHandlerData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::backend::{BackendEvent, Output};
|
use crate::backend::{BackendEvent, Output};
|
||||||
use crate::tasks::device;
|
use crate::tasks::input_device;
|
||||||
use crate::tasks::output::OutputHandler;
|
use crate::tasks::output::OutputHandler;
|
||||||
use crate::State;
|
use crate::State;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
@ -19,8 +19,7 @@ impl BackendEventHandler {
|
||||||
fn handle_event(&mut self, event: BackendEvent) {
|
fn handle_event(&mut self, event: BackendEvent) {
|
||||||
match event {
|
match event {
|
||||||
BackendEvent::NewOutput(output) => self.handle_new_output(output),
|
BackendEvent::NewOutput(output) => self.handle_new_output(output),
|
||||||
BackendEvent::NewMouse(s) => device::handle(&self.state, s),
|
BackendEvent::NewInputDevice(s) => input_device::handle(&self.state, s),
|
||||||
BackendEvent::NewKeyboard(s) => device::handle(&self.state, s),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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<dyn Fn()>);
|
|
||||||
fn announce(&self, config: &ConfigProxy);
|
|
||||||
fn announce_del(&self, config: &ConfigProxy);
|
|
||||||
fn removed(&self) -> bool;
|
|
||||||
fn add(self: &Rc<Self>, state: &State, handler: SpawnedFuture<()>, data: Rc<DeviceHandlerData>);
|
|
||||||
fn remove(&self, state: &State);
|
|
||||||
fn event(&self) -> Option<Self::Event>;
|
|
||||||
fn send(seat: &Rc<WlSeatGlobal>, event: Self::Event);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeviceApi for dyn Keyboard {
|
|
||||||
type Event = KeyboardEvent;
|
|
||||||
|
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
|
||||||
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<Self>,
|
|
||||||
state: &State,
|
|
||||||
handler: SpawnedFuture<()>,
|
|
||||||
data: Rc<DeviceHandlerData>,
|
|
||||||
) {
|
|
||||||
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> {
|
|
||||||
self.event()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send(seat: &Rc<WlSeatGlobal>, event: Self::Event) {
|
|
||||||
seat.kb_event(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeviceApi for dyn Mouse {
|
|
||||||
type Event = MouseEvent;
|
|
||||||
|
|
||||||
fn on_change(&self, cb: Rc<dyn Fn()>) {
|
|
||||||
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<Self>,
|
|
||||||
state: &State,
|
|
||||||
handler: SpawnedFuture<()>,
|
|
||||||
data: Rc<DeviceHandlerData>,
|
|
||||||
) {
|
|
||||||
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> {
|
|
||||||
self.event()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send(seat: &Rc<WlSeatGlobal>, event: Self::Event) {
|
|
||||||
seat.mouse_event(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle<T: DeviceApi + ?Sized>(state: &Rc<State>, dev: Rc<T>) {
|
|
||||||
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<T: DeviceApi + ?Sized> {
|
|
||||||
pub state: Rc<State>,
|
|
||||||
pub dev: Rc<T>,
|
|
||||||
pub data: Rc<DeviceHandlerData>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: DeviceApi + ?Sized> DeviceHandler<T> {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
69
src/tasks/input_device.rs
Normal file
69
src/tasks/input_device.rs
Normal file
|
|
@ -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<State>, dev: Rc<dyn InputDevice>) {
|
||||||
|
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<State>,
|
||||||
|
pub dev: Rc<dyn InputDevice>,
|
||||||
|
pub data: Rc<DeviceHandlerData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
mod backend;
|
mod backend;
|
||||||
mod device;
|
mod input_device;
|
||||||
mod output;
|
mod output;
|
||||||
mod slow_clients;
|
mod slow_clients;
|
||||||
|
mod start_backend;
|
||||||
|
|
||||||
use crate::tasks::backend::BackendEventHandler;
|
use crate::tasks::backend::BackendEventHandler;
|
||||||
use crate::tasks::slow_clients::SlowClientHandler;
|
use crate::tasks::slow_clients::SlowClientHandler;
|
||||||
use crate::State;
|
use crate::State;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
pub use start_backend::start_backend;
|
||||||
|
|
||||||
pub async fn handle_backend_events(state: Rc<State>) {
|
pub async fn handle_backend_events(state: Rc<State>) {
|
||||||
let mut beh = BackendEventHandler { state };
|
let mut beh = BackendEventHandler { state };
|
||||||
|
|
|
||||||
17
src/tasks/start_backend.rs
Normal file
17
src/tasks/start_backend.rs
Normal file
|
|
@ -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<State>) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
12
src/udev.rs
12
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_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;
|
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_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)
|
fn udev_device_new_from_syspath(udev: *mut udev, syspath: *const c::c_char)
|
||||||
|
|
@ -85,7 +86,7 @@ pub struct UdevMonitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UdevEnumerate {
|
pub struct UdevEnumerate {
|
||||||
udev: Rc<Udev>,
|
_udev: Rc<Udev>,
|
||||||
enumerate: *mut udev_enumerate,
|
enumerate: *mut udev_enumerate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +96,7 @@ pub struct UdevListEntry<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UdevDevice {
|
pub struct UdevDevice {
|
||||||
udev: Rc<Udev>,
|
_udev: Rc<Udev>,
|
||||||
device: *mut udev_device,
|
device: *mut udev_device,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -125,7 +126,7 @@ impl Udev {
|
||||||
return Err(UdevError::NewEnumerate(Errno::default().into()));
|
return Err(UdevError::NewEnumerate(Errno::default().into()));
|
||||||
}
|
}
|
||||||
Ok(UdevEnumerate {
|
Ok(UdevEnumerate {
|
||||||
udev: self.clone(),
|
_udev: self.clone(),
|
||||||
enumerate: res,
|
enumerate: res,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +141,7 @@ impl Udev {
|
||||||
return Err(UdevError::DeviceFromSyspath(Errno::default().into()));
|
return Err(UdevError::DeviceFromSyspath(Errno::default().into()));
|
||||||
}
|
}
|
||||||
Ok(UdevDevice {
|
Ok(UdevDevice {
|
||||||
udev: self.clone(),
|
_udev: self.clone(),
|
||||||
device: res,
|
device: res,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -198,7 +199,7 @@ impl UdevMonitor {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(UdevDevice {
|
Some(UdevDevice {
|
||||||
udev: self.udev.clone(),
|
_udev: self.udev.clone(),
|
||||||
device: res,
|
device: res,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -305,6 +306,7 @@ impl UdevDevice {
|
||||||
unsafe { udev_device_get_devnum(self.device) }
|
unsafe { udev_device_get_devnum(self.device) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn is_initialized(&self) -> bool {
|
pub fn is_initialized(&self) -> bool {
|
||||||
unsafe { udev_device_get_is_initialized(self.device) != 0 }
|
unsafe { udev_device_get_is_initialized(self.device) != 0 }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
const SEG_SIZE: usize = 8 * mem::size_of::<usize>();
|
const SEG_SIZE: usize = 8 * mem::size_of::<usize>();
|
||||||
|
|
|
||||||
|
|
@ -20,3 +20,4 @@ pub mod tri;
|
||||||
pub mod vasprintf;
|
pub mod vasprintf;
|
||||||
pub mod vec_ext;
|
pub mod vec_ext;
|
||||||
pub mod vecstorage;
|
pub mod vecstorage;
|
||||||
|
pub mod syncqueue;
|
||||||
|
|
|
||||||
29
src/utils/syncqueue.rs
Normal file
29
src/utils/syncqueue.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use crate::utils::ptr_ext::MutPtrExt;
|
||||||
|
|
||||||
|
pub struct SyncQueue<T> {
|
||||||
|
el: UnsafeCell<VecDeque<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Default for SyncQueue<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
el: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> SyncQueue<T> {
|
||||||
|
pub fn push(&self, t: T) {
|
||||||
|
unsafe {
|
||||||
|
self.el.get().deref_mut().push_back(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop(&self) -> Option<T> {
|
||||||
|
unsafe {
|
||||||
|
self.el.get().deref_mut().pop_front()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -107,8 +107,8 @@ pub struct Wm {
|
||||||
c: RustConnection,
|
c: RustConnection,
|
||||||
atoms: Atoms,
|
atoms: Atoms,
|
||||||
socket: AsyncFd,
|
socket: AsyncFd,
|
||||||
root: Window,
|
_root: Window,
|
||||||
xwin: Window,
|
_xwin: Window,
|
||||||
client: Rc<Client>,
|
client: Rc<Client>,
|
||||||
windows: AHashMap<Window, Rc<XwindowData>>,
|
windows: AHashMap<Window, Rc<XwindowData>>,
|
||||||
windows_by_surface_id: AHashMap<WlSurfaceId, Rc<XwindowData>>,
|
windows_by_surface_id: AHashMap<WlSurfaceId, Rc<XwindowData>>,
|
||||||
|
|
@ -228,8 +228,8 @@ impl Wm {
|
||||||
c,
|
c,
|
||||||
atoms,
|
atoms,
|
||||||
socket: socket_dup,
|
socket: socket_dup,
|
||||||
root,
|
_root: root,
|
||||||
xwin,
|
_xwin: xwin,
|
||||||
client,
|
client,
|
||||||
windows: Default::default(),
|
windows: Default::default(),
|
||||||
windows_by_surface_id: Default::default(),
|
windows_by_surface_id: Default::default(),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue