use { crate::{ client::ClientError, ifs::wl_seat::WlSeat, leaks::Tracker, object::Object, utils::buffd::{MsgParser, MsgParserError}, wire::{wl_keyboard::*, WlKeyboardId, WlSurfaceId}, }, std::rc::Rc, thiserror::Error, uapi::OwnedFd, }; pub const REPEAT_INFO_SINCE: u32 = 4; #[allow(dead_code)] const NO_KEYMAP: u32 = 0; pub(super) const XKB_V1: u32 = 1; pub(super) const RELEASED: u32 = 0; pub(super) const PRESSED: u32 = 1; pub struct WlKeyboard { id: WlKeyboardId, seat: Rc, pub tracker: Tracker, } impl WlKeyboard { pub fn new(id: WlKeyboardId, seat: &Rc) -> Self { Self { id, seat: seat.clone(), tracker: Default::default(), } } pub fn send_keymap(self: &Rc, format: u32, fd: Rc, size: u32) { self.seat.client.event(Keymap { self_id: self.id, format, fd, size, }) } pub fn send_enter(self: &Rc, serial: u32, surface: WlSurfaceId, keys: &[u32]) { log::info!("enter with {:?}", keys); self.seat.client.event(Enter { self_id: self.id, serial, surface, keys, }) } pub fn send_leave(self: &Rc, serial: u32, surface: WlSurfaceId) { self.seat.client.event(Leave { self_id: self.id, serial, surface, }) } pub fn send_key(self: &Rc, serial: u32, time: u32, key: u32, state: u32) { self.seat.client.event(Key { self_id: self.id, serial, time, key, state, }) } pub fn send_modifiers( self: &Rc, serial: u32, mods_depressed: u32, mods_latched: u32, mods_locked: u32, group: u32, ) { self.seat.client.event(Modifiers { self_id: self.id, serial, mods_depressed, mods_latched, mods_locked, group, }) } pub fn send_repeat_info(self: &Rc, rate: i32, delay: i32) { self.seat.client.event(RepeatInfo { self_id: self.id, rate, delay, }) } fn release(&self, parser: MsgParser<'_, '_>) -> Result<(), ReleaseError> { let _req: Release = self.seat.client.parse(self, parser)?; self.seat.keyboards.remove(&self.id); self.seat.client.remove_obj(self)?; Ok(()) } } object_base! { WlKeyboard, WlKeyboardError; RELEASE => release, } impl Object for WlKeyboard { fn num_requests(&self) -> u32 { RELEASE + 1 } } simple_add_obj!(WlKeyboard); #[derive(Debug, Error)] pub enum WlKeyboardError { #[error(transparent)] ClientError(Box), #[error("Could not process a `release` request")] ReleaseError(#[from] ReleaseError), #[error("Could not create a keymap memfd")] KeymapMemfd(#[source] crate::utils::oserror::OsError), #[error("Could not copy the keymap")] KeymapCopy(#[source] crate::utils::oserror::OsError), } efrom!(WlKeyboardError, ClientError, ClientError); #[derive(Debug, Error)] pub enum ReleaseError { #[error("Parsing failed")] ParseError(#[source] Box), #[error(transparent)] ClientError(Box), } efrom!(ReleaseError, ParseError, MsgParserError); efrom!(ReleaseError, ClientError, ClientError);