From 8bd88947361714bb08c8442081e34aacf1cecba9 Mon Sep 17 00:00:00 2001 From: user Date: Sat, 20 Nov 2021 23:51:23 +0100 Subject: [PATCH] added filed from `refactor` branch --- src/backends/keycodes.rs | 205 ++++++++++++++++++++++++++++++ src/backends/mod.rs | 104 +++++++++++++++ src/backends/window_event.rs | 238 +++++++++++++++++++++++++++++++++++ src/main.rs | 1 + 4 files changed, 548 insertions(+) create mode 100644 src/backends/keycodes.rs create mode 100644 src/backends/mod.rs create mode 100644 src/backends/window_event.rs diff --git a/src/backends/keycodes.rs b/src/backends/keycodes.rs new file mode 100644 index 0000000..6874e26 --- /dev/null +++ b/src/backends/keycodes.rs @@ -0,0 +1,205 @@ +#![allow(dead_code)] + +#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)] +pub enum MouseButton { + Left, + Middle, + Right, + ScrollUp, + ScrollDown, + ScrollLeft, + ScrollRight, + Forward, + Backward, +} + +/// from winit +#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy)] +#[repr(u32)] +pub enum VirtualKeyCode { + Key1, + Key2, + Key3, + Key4, + Key5, + Key6, + Key7, + Key8, + Key9, + Key0, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + + /// The Escape key, next to F1. + Escape, + + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + + /// Print Screen/SysRq. + Snapshot, + /// Scroll Lock. + Scroll, + /// Pause/Break key, next to Scroll lock. + Pause, + + /// `Insert`, next to Backspace. + Insert, + Home, + Delete, + End, + PageDown, + PageUp, + + Left, + Up, + Right, + Down, + + /// The Backspace key, right over Enter. + // TODO: rename + Back, + /// The Enter key. + Return, + /// The space bar. + Space, + + /// The "Compose" key on Linux. + Compose, + + Caret, + + Numlock, + Numpad0, + Numpad1, + Numpad2, + Numpad3, + Numpad4, + Numpad5, + Numpad6, + Numpad7, + Numpad8, + Numpad9, + NumpadAdd, + NumpadDivide, + NumpadDecimal, + NumpadComma, + NumpadEnter, + NumpadEquals, + NumpadMultiply, + NumpadSubtract, + + AbntC1, + AbntC2, + Apostrophe, + Apps, + Asterisk, + At, + Ax, + Backslash, + Calculator, + Capital, + Colon, + Comma, + Convert, + Equals, + Grave, + Kana, + Kanji, + LAlt, + LBracket, + LControl, + LShift, + LWin, + Mail, + MediaSelect, + MediaStop, + Minus, + Mute, + MyComputer, + // also called "Next" + NavigateForward, + // also called "Prior" + NavigateBackward, + NextTrack, + NoConvert, + OEM102, + Period, + PlayPause, + Plus, + Power, + PrevTrack, + RAlt, + RBracket, + RControl, + RShift, + RWin, + Semicolon, + Slash, + Sleep, + Stop, + Sysrq, + Tab, + Underline, + Unlabeled, + VolumeDown, + VolumeUp, + Wake, + WebBack, + WebFavorites, + WebForward, + WebHome, + WebRefresh, + WebSearch, + WebStop, + Yen, + Copy, + Paste, + Cut, +} diff --git a/src/backends/mod.rs b/src/backends/mod.rs new file mode 100644 index 0000000..ac7b21e --- /dev/null +++ b/src/backends/mod.rs @@ -0,0 +1,104 @@ +use self::window_event::KeyBind; + +pub mod keycodes; +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 focus_window(&self, window: Window); + fn unfocus_window(&self, window: Window); + fn move_window(&self, window: Window, pos: i32); + fn resize_window(&self, window: Window, pos: i32); + fn hide_window(&self, window: Window); + fn screen_size(&self) -> (i32, i32); + fn kill_window(&self, window: Window); +} + +pub mod xlib { + use std::ffi::CString; + + use x11::xlib::{Atom, Window, XInternAtom}; + + #[derive(Clone)] + pub struct Display(Rc<*mut xlib::Display>); + + impl Deref for Display {} + + impl Display { + pub fn new(display: *mut x11::xlib::Display) -> Self { + Self { + 0: Rc::new(display), + } + } + + pub fn get(&self) -> *mut x11::xlib::Display { + *self.0 + } + } + + pub struct XLib { + display: Display, + root: Window, + screen: i32, + atoms: XLibAtoms, + keybinds: Vec<()>, + } + + struct XLibAtoms { + protocols: Atom, + delete_window: Atom, + active_window: Atom, + take_focus: Atom, + } + + impl XLibAtoms { + fn init(display: Display) -> Self { + unsafe { + Self { + protocols: { + let name = CString::new("WM_PROTOCOLS").unwrap(); + XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) + }, + delete_window: { + let name = CString::new("WM_DELETE_WINDOW").unwrap(); + XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) + }, + active_window: { + let name = CString::new("WM_ACTIVE_WINDOW").unwrap(); + XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) + }, + take_focus: { + let name = CString::new("WM_TAKE_FOCUS").unwrap(); + XInternAtom(display.get(), name.as_c_str().as_ptr(), 0) + }, + } + } + } + } + + #[allow(dead_code)] + unsafe extern "C" fn xlib_error_handler( + _dpy: *mut x11::xlib::Display, + ee: *mut x11::xlib::XErrorEvent, + ) -> std::os::raw::c_int { + let err = ee.as_ref().unwrap(); + + 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); + } + } +} diff --git a/src/backends/window_event.rs b/src/backends/window_event.rs new file mode 100644 index 0000000..51b7ac3 --- /dev/null +++ b/src/backends/window_event.rs @@ -0,0 +1,238 @@ +#![allow(dead_code)] +use x11::xlib::Window; + +use super::keycodes::{MouseButton, VirtualKeyCode}; + +#[derive(Debug)] +pub enum WindowEvent { + KeyEvent { + window: Window, + event: KeyEvent, + }, + ButtonEvent { + window: Window, + event: ButtonEvent, + }, + MotionEvent { + window: Window, + event: MotionEvent, + }, + MapRequestEvent { + window: Window, + event: MapEvent, + }, + MapEvent { + window: Window, + event: MapEvent, + }, + UnmapEvent { + window: Window, + event: UnmapEvent, + }, + CreateEvent { + window: Window, + event: CreateEvent, + }, + DestroyEvent { + window: Window, + event: DestroyEvent, + }, + EnterEvent { + window: Window, + event: EnterEvent, + }, + ConfigureEvent { + window: Window, + event: ConfigureEvent, + }, + FullscreenEvent { + window: Window, + event: FullscreenEvent, + }, //1 { window: Window, event: 1 }, +} + +#[derive(Debug)] +pub enum KeyState { + Pressed, + Released, +} + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)] +#[repr(u8)] +pub enum ModifierKey { + Shift, + ShiftLock, + Control, + Alt, + AltGr, + /// Windows key on most keyboards + Super, + NumLock, +} + +#[derive(Default, Debug, Clone)] +pub struct ModifierState { + modifiers: std::collections::HashSet, +} + +impl ModifierState { + pub fn new() -> Self { + Self::default() + } + + pub fn set_modifier(&mut self, modifier: ModifierKey) { + self.modifiers.insert(modifier); + } + + pub fn unset_modifier(&mut self, modifier: ModifierKey) { + self.modifiers.remove(&modifier); + } + + pub fn get_modifier(&mut self, modifier: ModifierKey) -> bool { + self.modifiers.contains(&modifier) + } +} + +#[derive(Debug)] +pub struct KeyEvent { + pub state: KeyState, + pub keycode: VirtualKeyCode, + pub modifierstate: ModifierState, +} + +impl KeyEvent { + pub fn new( + state: KeyState, + keycode: VirtualKeyCode, + modifierstate: ModifierState, + ) -> Self { + Self { + state, + keycode, + modifierstate, + } + } +} + +#[derive(Debug)] +pub struct ButtonEvent { + pub state: KeyState, + pub keycode: MouseButton, + pub modifierstate: ModifierState, +} + +impl ButtonEvent { + pub fn new( + state: KeyState, + keycode: MouseButton, + modifierstate: ModifierState, + ) -> Self { + Self { + state, + keycode, + modifierstate, + } + } +} + +#[derive(Debug)] +pub struct MotionEvent { + pub position: [i32; 2], +} + +impl MotionEvent { + pub fn new(position: [i32; 2]) -> Self { + Self { position } + } +} + +#[derive(Debug)] +pub struct MapEvent { + pub window: Window, +} + +impl MapEvent { + pub fn new(window: Window) -> Self { + Self { window } + } +} + +#[derive(Debug)] +pub struct UnmapEvent { + pub window: Window, +} + +impl UnmapEvent { + pub fn new(window: Window) -> Self { + Self { window } + } +} + +#[derive(Debug)] +pub struct EnterEvent {} + +#[derive(Debug)] +pub struct DestroyEvent { + pub window: Window, +} + +impl DestroyEvent { + pub fn new(window: Window) -> Self { + Self { window } + } +} + +#[derive(Debug)] +pub struct CreateEvent { + pub window: Window, + pub position: [i32; 2], + pub size: [i32; 2], +} + +impl CreateEvent { + pub fn new(window: Window, position: [i32; 2], size: [i32; 2]) -> Self { + Self { + window, + position, + size, + } + } +} + +#[derive(Debug)] +pub struct ConfigureEvent { + pub window: Window, + pub position: [i32; 2], + pub size: [i32; 2], +} + +impl ConfigureEvent { + pub fn new(window: Window, position: [i32; 2], size: [i32; 2]) -> Self { + Self { + window, + position, + size, + } + } +} + +#[derive(Debug)] +pub struct FullscreenEvent { + new_fullscreen: bool, +} + +impl FullscreenEvent { + pub fn new(new_fullscreen: bool) -> Self { + Self { new_fullscreen } + } +} + +pub struct KeyBind { + key: VirtualKeyCode, + modifiers: ModifierState, +} + +pub struct MouseBind { + button: MouseButton, + modifiers: ModifierState, +} diff --git a/src/main.rs b/src/main.rs index 4825886..badbd47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ use log4rs::{ }; use state::WMConfig; +mod backends; mod clients; //mod clients2; mod state;