From 94c5cd91113f519e610537d5fdff816d0717ff82 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 21 Nov 2021 15:43:17 +0100 Subject: [PATCH] starting to abstract away xlib backend --- Cargo.toml | 3 +- src/backends/mod.rs | 239 ++++++++++++++++++++++++++++++++--- src/backends/window_event.rs | 2 +- src/main.rs | 18 +++ 4 files changed, 239 insertions(+), 23 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3215225..0999cd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ log = "0.4.13" simple_logger = "1.11.0" dirs = "3.0.2" log4rs = "1.0.0" -indexmap = "1.6.2" \ No newline at end of file +indexmap = "1.6.2" +thiserror = "1.0.30" \ No newline at end of file diff --git a/src/backends/mod.rs b/src/backends/mod.rs index ac7b21e..7bbe267 100644 --- a/src/backends/mod.rs +++ b/src/backends/mod.rs @@ -5,10 +5,10 @@ pub mod window_event; pub trait WindowServerBackend { fn next_event(&self) -> window_event::WindowEvent; - fn add_keybind(&mut self, keybind: KeyBind, window: Some); - fn remove_keybind(&mut self, keybind: KeyBind, window: Some); - fn add_mousebind(&mut self, keybind: KeyBind, window: Some); - fn remove_mousebind(&mut self, keybind: KeyBind, window: Some); + fn add_keybind(&mut self, keybind: KeyBind, window: Option); + fn remove_keybind(&mut self, keybind: KeyBind, window: Option); + fn add_mousebind(&mut self, keybind: KeyBind, window: Option); + fn remove_mousebind(&mut self, keybind: KeyBind, window: Option); fn focus_window(&self, window: Window); fn unfocus_window(&self, window: Window); fn move_window(&self, window: Window, pos: i32); @@ -19,14 +19,111 @@ pub trait WindowServerBackend { } pub mod xlib { - use std::ffi::CString; + use log::{error, warn}; + use std::{ + borrow::Borrow, + convert::{TryFrom, TryInto}, + ffi::CString, + rc::Rc, + }; + use thiserror::Error; - use x11::xlib::{Atom, Window, XInternAtom}; + use x11::xlib::{self, Atom, Window, XEvent, XInternAtom}; + + use super::{window_event::WindowEvent, WindowServerBackend}; #[derive(Clone)] - pub struct Display(Rc<*mut xlib::Display>); + pub struct Display(Rc<*mut x11::xlib::Display>); - impl Deref for Display {} + #[derive(Debug, Error)] + pub enum XlibError { + #[error("BadAccess")] + BadAccess, + #[error("BadAlloc")] + BadAlloc, + #[error("BadAtom")] + BadAtom, + #[error("BadColor")] + BadColor, + #[error("BadCursor")] + BadCursor, + #[error("BadDrawable")] + BadDrawable, + #[error("BadFont")] + BadFont, + #[error("BadGC")] + BadGC, + #[error("BadIDChoice")] + BadIDChoice, + #[error("BadImplementation")] + BadImplementation, + #[error("BadLength")] + BadLength, + #[error("BadMatch")] + BadMatch, + #[error("BadName")] + BadName, + #[error("BadPixmap")] + BadPixmap, + #[error("BadRequest")] + BadRequest, + #[error("BadValue")] + BadValue, + #[error("BadWindow")] + BadWindow, + #[error("Invalid XError: {0}")] + InvalidError(u8), + } + + impl From for XlibError { + fn from(value: u8) -> Self { + match value { + xlib::BadAccess => XlibError::BadAccess, + xlib::BadAlloc => XlibError::BadAlloc, + xlib::BadAtom => XlibError::BadAtom, + xlib::BadColor => XlibError::BadColor, + xlib::BadCursor => XlibError::BadCursor, + xlib::BadDrawable => XlibError::BadDrawable, + xlib::BadFont => XlibError::BadFont, + xlib::BadGC => XlibError::BadGC, + xlib::BadIDChoice => XlibError::BadIDChoice, + xlib::BadImplementation => XlibError::BadImplementation, + xlib::BadLength => XlibError::BadLength, + xlib::BadMatch => XlibError::BadMatch, + xlib::BadName => XlibError::BadName, + xlib::BadPixmap => XlibError::BadPixmap, + xlib::BadRequest => XlibError::BadRequest, + xlib::BadValue => XlibError::BadValue, + xlib::BadWindow => XlibError::BadWindow, + any => XlibError::InvalidError(any), + } + } + } + + // impl Into for XlibError { + // fn into(self) -> i32 { + // match self { + // XlibError::BadAccess => xlib::BadAccess.into(), + // XlibError::BadAlloc => xlib::BadAlloc.into(), + // XlibError::BadAtom => xlib::BadAtom.into(), + // XlibError::BadColor => xlib::BadColor.into(), + // XlibError::BadCursor => xlib::BadCursor.into(), + // XlibError::BadDrawable => xlib::BadDrawable.into(), + // XlibError::BadFont => xlib::BadFont.into(), + // XlibError::BadGC => xlib::BadGC.into(), + // XlibError::BadIDChoice => xlib::BadIDChoice.into(), + // XlibError::BadImplementation => xlib::BadImplementation.into(), + // XlibError::BadLength => xlib::BadLength.into(), + // XlibError::BadMatch => xlib::BadMatch.into(), + // XlibError::BadName => xlib::BadName.into(), + // XlibError::BadPixmap => xlib::BadPixmap.into(), + // XlibError::BadRequest => xlib::BadRequest.into(), + // XlibError::BadValue => xlib::BadValue.into(), + // XlibError::BadWindow => xlib::BadWindow.into(), + // XlibError::InvalidError(err) => err, + // } + // } + // } impl Display { pub fn new(display: *mut x11::xlib::Display) -> Self { @@ -48,6 +145,102 @@ pub mod xlib { keybinds: Vec<()>, } + impl XLib { + fn dpy(&self) -> *mut xlib::Display { + self.display.get() + } + + fn next_xevent(&self) -> XEvent { + unsafe { + let mut event = std::mem::MaybeUninit::::zeroed() + .assume_init(); + xlib::XNextEvent(self.dpy(), &mut event); + + event + } + } + } + + impl TryFrom for WindowEvent { + type Error = crate::error::Error; + + fn try_from(event: XEvent) -> Result { + match event.get_type() { + xlib::MapRequest => Ok(Self::MapRequestEvent { + window: event.map_request.window, + event: todo!(), + }), + _ => Err(Self::Error::UnknownEvent), + } + } + } + + impl WindowServerBackend for XLib { + fn next_event(&self) -> super::window_event::WindowEvent { + self.next_xevent().try_into().unwrap() + } + + fn add_keybind( + &mut self, + keybind: super::window_event::KeyBind, + window: Option, + ) { + todo!() + } + + fn remove_keybind( + &mut self, + keybind: super::window_event::KeyBind, + window: Option, + ) { + todo!() + } + + fn add_mousebind( + &mut self, + keybind: super::window_event::KeyBind, + window: Option, + ) { + todo!() + } + + fn remove_mousebind( + &mut self, + keybind: super::window_event::KeyBind, + window: Option, + ) { + todo!() + } + + fn focus_window(&self, window: u64) { + todo!() + } + + fn unfocus_window(&self, window: u64) { + todo!() + } + + fn move_window(&self, window: u64, pos: i32) { + todo!() + } + + fn resize_window(&self, window: u64, pos: i32) { + todo!() + } + + fn hide_window(&self, window: u64) { + todo!() + } + + fn screen_size(&self) -> (i32, i32) { + todo!() + } + + fn kill_window(&self, window: u64) { + todo!() + } + } + struct XLibAtoms { protocols: Atom, delete_window: Atom, @@ -85,20 +278,24 @@ pub mod xlib { _dpy: *mut x11::xlib::Display, ee: *mut x11::xlib::XErrorEvent, ) -> std::os::raw::c_int { - let err = ee.as_ref().unwrap(); + let err_event = ee.as_ref().unwrap(); + let err = XlibError::from(err_event.error_code); - if err.error_code == x11::xlib::BadWindow - || err.error_code == x11::xlib::BadDrawable - || err.error_code == x11::xlib::BadAccess - || err.error_code == x11::xlib::BadMatch - { - 0 - } else { - error!( - "wm: fatal error:\nrequest_code: {}\nerror_code: {}", - err.request_code, err.error_code - ); - std::process::exit(1); + match err { + err @ XlibError::BadAccess + | err @ XlibError::BadMatch + | err @ XlibError::BadWindow + | err @ XlibError::BadDrawable => { + warn!("{:?}", err); + 0 + } + _ => { + error!( + "wm: fatal error:\nrequest_code: {}\nerror_code: {}", + err_event.request_code, err_event.error_code + ); + std::process::exit(1) + } } } } diff --git a/src/backends/window_event.rs b/src/backends/window_event.rs index 51b7ac3..6e0aaef 100644 --- a/src/backends/window_event.rs +++ b/src/backends/window_event.rs @@ -1,5 +1,5 @@ #![allow(dead_code)] -use x11::xlib::Window; +//use x11::xlib::Window; use super::keycodes::{MouseButton, VirtualKeyCode}; diff --git a/src/main.rs b/src/main.rs index badbd47..971d7f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,24 @@ mod state; mod util; mod xlib; +pub mod error { + use thiserror::Error; + + #[derive(Debug, Error)] + pub enum Error { + #[error("placeholder error for Result as Option")] + NonError, + #[error("Unknown Event")] + UnknownEvent, + #[error(transparent)] + IoError(#[from] std::io::Error), + #[error(transparent)] + FmtError(#[from] std::fmt::Error), + #[error(transparent)] + XlibError(#[from] crate::backends::xlib::XlibError), + } +} + fn init_logger() { let encoder = Box::new(PatternEncoder::new( "{d(%Y-%m-%d %H:%M:%S %Z)(utc)} │ {({M}::{f}:{L}):>25} │ {h({l:>5})} │ {m}{n}",