From b3f586ea6a1103cc0d9edc50e49e96399dc75308 Mon Sep 17 00:00:00 2001 From: Janis Date: Sat, 7 May 2022 00:29:28 +0200 Subject: [PATCH] removed old xlib.rs file --- src/xlib.rs | 774 ---------------------------------------------------- 1 file changed, 774 deletions(-) delete mode 100644 src/xlib.rs diff --git a/src/xlib.rs b/src/xlib.rs deleted file mode 100644 index 4c3b247..0000000 --- a/src/xlib.rs +++ /dev/null @@ -1,774 +0,0 @@ -use log::info; -use std::ptr::{null, null_mut}; -use std::{ffi::CString, rc::Rc}; - -use x11::xlib::{ - self, AnyButton, AnyKey, AnyModifier, Atom, ButtonPressMask, - ButtonReleaseMask, CWEventMask, ControlMask, CurrentTime, EnterWindowMask, - FocusChangeMask, LockMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, - Mod5Mask, PointerMotionMask, PropertyChangeMask, ShiftMask, - StructureNotifyMask, SubstructureNotifyMask, SubstructureRedirectMask, - Window, XCloseDisplay, XConfigureRequestEvent, XDefaultScreen, XEvent, - XGetTransientForHint, XGrabPointer, XInternAtom, XKillClient, XMapWindow, - XOpenDisplay, XRaiseWindow, XRootWindow, XSetErrorHandler, XSync, - XUngrabButton, XUngrabKey, XUngrabPointer, XWarpPointer, XWindowAttributes, -}; -use xlib::GrabModeAsync; - -use log::error; - -use crate::clients::Client; - -pub struct XLib { - display: Display, - root: Window, - _screen: i32, - atoms: Atoms, - global_keybinds: Vec, -} - -struct Atoms { - protocols: Atom, - delete_window: Atom, - active_window: Atom, - take_focus: Atom, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum KeyOrButton { - Key(i32, u32), - Button(u32, u32, u64), -} - -impl KeyOrButton { - #[allow(dead_code)] - pub fn key(keycode: i32, modmask: u32) -> Self { - Self::Key(keycode, modmask) - } - pub fn button(button: u32, modmask: u32, buttonmask: i64) -> Self { - Self::Button(button, modmask, buttonmask as u64) - } -} - -#[derive(Clone)] -pub struct Display(Rc<*mut xlib::Display>); - -impl Drop for XLib { - fn drop(&mut self) { - self.close_dpy(); - } -} - -impl XLib { - pub fn new() -> Self { - let (display, _screen, root) = unsafe { - let display = XOpenDisplay(null()); - - assert_ne!(display, null_mut()); - - let display = Display::new(display); - let screen = XDefaultScreen(display.get()); - let root = XRootWindow(display.get(), screen); - - (display, screen, root) - }; - - Self { - atoms: Atoms::init(display.clone()), - global_keybinds: Vec::new(), - root, - _screen, - display, - } - } - - pub fn init(&mut self) { - unsafe { - let mut window_attributes = - std::mem::MaybeUninit::::zeroed() - .assume_init(); - - window_attributes.event_mask = SubstructureRedirectMask - | StructureNotifyMask - | SubstructureNotifyMask - | EnterWindowMask - | PointerMotionMask - | ButtonPressMask; - - xlib::XChangeWindowAttributes( - self.dpy(), - self.root, - CWEventMask, - &mut window_attributes, - ); - - xlib::XSelectInput( - self.dpy(), - self.root, - window_attributes.event_mask, - ); - - XSetErrorHandler(Some(xlib_error_handler)); - - XSync(self.dpy(), 0); - } - - self.grab_global_keybinds(self.root); - } - - pub fn add_global_keybind(&mut self, key: KeyOrButton) { - self.global_keybinds.push(key); - } - - #[allow(dead_code)] - fn ungrab_global_keybings(&self, window: Window) { - unsafe { - XUngrabButton(self.dpy(), AnyButton as u32, AnyModifier, window); - XUngrabKey(self.dpy(), AnyKey, AnyModifier, window); - } - } - - fn grab_global_keybinds(&self, window: Window) { - for kb in self.global_keybinds.iter() { - self.grab_key_or_button(window, kb); - } - } - - #[allow(dead_code)] - pub fn remove_global_keybind(&mut self, key: &KeyOrButton) { - if self.global_keybinds.contains(key) { - self.global_keybinds.retain(|kb| kb != key); - } - } - - fn dpy(&self) -> *mut xlib::Display { - self.display.get() - } - - #[allow(dead_code)] - pub fn squash_event(&self, event_type: i32) -> XEvent { - unsafe { - let mut event = - std::mem::MaybeUninit::::zeroed().assume_init(); - - while xlib::XCheckTypedEvent(self.dpy(), event_type, &mut event) - != 0 - {} - - event - } - } - - pub fn next_event(&self) -> XEvent { - unsafe { - let mut event = - std::mem::MaybeUninit::::zeroed().assume_init(); - xlib::XNextEvent(self.dpy(), &mut event); - - event - } - } - - pub fn grab_key_or_button(&self, window: Window, key: &KeyOrButton) { - let numlock_mask = self.get_numlock_mask(); - let modifiers = - vec![0, LockMask, numlock_mask, LockMask | numlock_mask]; - - for modifier in modifiers.iter() { - match key { - &KeyOrButton::Key(keycode, modmask) => { - unsafe { - xlib::XGrabKey( - self.dpy(), - keycode, - modmask | modifier, - window, - 1, /* true */ - GrabModeAsync, - GrabModeAsync, - ); - } - } - &KeyOrButton::Button(button, modmask, buttonmask) => { - unsafe { - xlib::XGrabButton( - self.dpy(), - button, - modmask | modifier, - window, - 1, /*true */ - buttonmask as u32, - GrabModeAsync, - GrabModeAsync, - 0, - 0, - ); - } - } - } - } - } - - pub fn focus_client(&self, client: &Client) { - unsafe { - xlib::XSetInputFocus( - self.dpy(), - client.window, - xlib::RevertToPointerRoot, - xlib::CurrentTime, - ); - - let screen = xlib::XDefaultScreenOfDisplay(self.dpy()).as_ref(); - - if let Some(screen) = screen { - xlib::XSetWindowBorder( - self.dpy(), - client.window, - screen.white_pixel, - ); - } - - xlib::XChangeProperty( - self.dpy(), - self.root, - self.atoms.active_window, - xlib::XA_WINDOW, - 32, - xlib::PropModeReplace, - &client.window as *const u64 as *const _, - 1, - ); - } - - self.send_protocol(client, self.atoms.take_focus); - } - - pub fn unfocus_client(&self, client: &Client) { - //info!("unfocusing client: {:?}", client); - - unsafe { - xlib::XSetInputFocus( - self.dpy(), - self.root, - xlib::RevertToPointerRoot, - xlib::CurrentTime, - ); - - let screen = xlib::XDefaultScreenOfDisplay(self.dpy()).as_ref(); - - if let Some(screen) = screen { - xlib::XSetWindowBorder( - self.dpy(), - client.window, - screen.black_pixel, - ); - } - - // xlib::XDeleteProperty( - // self.dpy(), - // self.root, - // self.atoms.active_window, - // ); - } - } - - pub fn move_resize_client(&self, client: &Client) { - let mut windowchanges = xlib::XWindowChanges { - x: client.position.x, - y: client.position.y, - width: client.size.x, - height: client.size.y, - border_width: 0, - sibling: 0, - stack_mode: 0, - }; - - if client.size.x < 1 || client.size.y < 1 { - error!("client {:?} size is less than 1 pixel!", client); - } else { - unsafe { - xlib::XConfigureWindow( - self.dpy(), - client.window, - (xlib::CWY | xlib::CWX | xlib::CWHeight | xlib::CWWidth) - as u32, - &mut windowchanges, - ); - - // I don't think I have to call this ~ - //self.configure_client(client); - } - } - } - - pub fn move_client(&self, client: &Client) { - let mut wc = xlib::XWindowChanges { - x: client.position.x, - y: client.position.y, - width: client.size.x, - height: client.size.y, - border_width: 0, - sibling: 0, - stack_mode: 0, - }; - - if client.size.x < 1 || client.size.y < 1 { - error!("client {:?} size is less than 1 pixel!", client); - } else { - unsafe { - xlib::XConfigureWindow( - self.dpy(), - client.window, - (xlib::CWX | xlib::CWY) as u32, - &mut wc, - ); - } - } - } - - pub fn resize_client(&self, client: &Client) { - let mut wc = xlib::XWindowChanges { - x: client.position.x, - y: client.position.y, - width: client.size.x, - height: client.size.y, - border_width: 0, - sibling: 0, - stack_mode: 0, - }; - - if client.size.x < 1 || client.size.y < 1 { - error!("client {:?} size is less than 1 pixel!", client); - } else { - unsafe { - xlib::XConfigureWindow( - self.dpy(), - client.window, - (xlib::CWWidth | xlib::CWHeight) as u32, - &mut wc, - ); - } - } - } - - pub fn hide_client(&self, client: &Client) { - let mut wc = xlib::XWindowChanges { - x: client.size.x * -2, - y: client.position.y, - width: client.size.x, - height: client.size.y, - border_width: 0, - sibling: 0, - stack_mode: 0, - }; - - if client.size.x < 1 || client.size.y < 1 { - error!("client {:?} size is less than 1 pixel!", client); - } else { - unsafe { - xlib::XConfigureWindow( - self.dpy(), - client.window, - (xlib::CWX | xlib::CWY) as u32, - &mut wc, - ); - } - } - } - - pub fn raise_client(&self, client: &Client) { - unsafe { - XRaiseWindow(self.dpy(), client.window); - } - } - - pub fn get_window_size(&self, window: Window) -> Option<(i32, i32)> { - let mut wa = unsafe { - std::mem::MaybeUninit::::zeroed() - .assume_init() - }; - - if unsafe { - xlib::XGetWindowAttributes(self.dpy(), window, &mut wa) != 0 - } { - Some((wa.width, wa.height)) - } else { - None - } - } - - #[allow(dead_code)] - fn get_window_attributes( - &self, - window: Window, - ) -> Option { - let mut wa = unsafe { - std::mem::MaybeUninit::::zeroed() - .assume_init() - }; - - if unsafe { - xlib::XGetWindowAttributes(self.dpy(), window, &mut wa) != 0 - } { - Some(wa) - } else { - None - } - } - - pub fn get_transient_for_window(&self, window: Window) -> Option { - let mut transient_for: Window = 0; - - if unsafe { - XGetTransientForHint(self.dpy(), window, &mut transient_for) != 0 - } { - Some(transient_for) - } else { - None - } - } - - #[allow(dead_code)] - pub fn expose_client(&self, client: &Client) { - self.expose_window(client.window); - } - - #[allow(dead_code)] - fn expose_window(&self, window: Window) { - if let Some(wa) = self.get_window_attributes(window) { - unsafe { - xlib::XClearArea( - self.dpy(), - window, - 0, - 0, - wa.width as u32, - wa.height as u32, - 1, - ); - } - } - } - - pub fn configure_window(&self, event: &XConfigureRequestEvent) { - let mut wc = xlib::XWindowChanges { - x: event.x, - y: event.y, - width: event.width, - height: event.height, - border_width: event.border_width, - sibling: event.above, - stack_mode: event.detail, - }; - - unsafe { - xlib::XConfigureWindow( - self.dpy(), - event.window, - event.value_mask as u32, - &mut wc, - ); - } - } - - pub fn configure_client(&self, client: &Client, border: i32) { - let mut event = xlib::XConfigureEvent { - type_: xlib::ConfigureNotify, - display: self.dpy(), - event: client.window, - window: client.window, - x: client.position.x, - y: client.position.y, - width: client.size.x, - height: client.size.y, - border_width: border, - override_redirect: 0, - send_event: 0, - serial: 0, - above: 0, - }; - - unsafe { - xlib::XSetWindowBorderWidth( - self.dpy(), - event.window, - event.border_width as u32, - ); - - xlib::XSendEvent( - self.dpy(), - event.window, - 0, - StructureNotifyMask, - &mut event as *mut _ as *mut XEvent, - ); - } - } - - pub fn map_window(&self, window: Window) { - unsafe { - XMapWindow(self.dpy(), window); - - xlib::XSelectInput( - self.dpy(), - window, - EnterWindowMask - | FocusChangeMask - | PropertyChangeMask - | StructureNotifyMask, - ); - } - - self.grab_global_keybinds(window); - } - - pub fn dimensions(&self) -> (i32, i32) { - unsafe { - let mut wa = - std::mem::MaybeUninit::::zeroed() - .assume_init(); - - xlib::XGetWindowAttributes(self.dpy(), self.root, &mut wa); - - info!("Root window dimensions: {}, {}", wa.width, wa.height); - - (wa.width, wa.height) - } - } - - fn close_dpy(&self) { - unsafe { - XCloseDisplay(self.dpy()); - } - } - - pub fn kill_client(&self, client: &Client) { - if !self.send_protocol(client, self.atoms.delete_window) { - unsafe { - XKillClient(self.dpy(), client.window); - } - } - } - - pub fn grab_cursor(&self) { - unsafe { - XGrabPointer( - self.dpy(), - self.root, - 0, - (ButtonPressMask | ButtonReleaseMask | PointerMotionMask) - as u32, - GrabModeAsync, - GrabModeAsync, - 0, - 0, - CurrentTime, - ); - } - } - - pub fn release_cursor(&self) { - unsafe { - XUngrabPointer(self.dpy(), CurrentTime); - } - } - - pub fn move_cursor(&self, window: Option, position: (i32, i32)) { - unsafe { - XWarpPointer( - self.dpy(), - 0, - window.unwrap_or(self.root), - 0, - 0, - 0, - 0, - position.0, - position.1, - ); - } - } - - fn check_for_protocol(&self, client: &Client, proto: xlib::Atom) -> bool { - let mut protos: *mut xlib::Atom = null_mut(); - let mut num_protos: i32 = 0; - - unsafe { - if xlib::XGetWMProtocols( - self.dpy(), - client.window, - &mut protos, - &mut num_protos, - ) != 0 - { - for i in 0..num_protos { - if *protos.offset(i as isize) == proto { - return true; - } - } - } - } - - return false; - } - - fn send_protocol(&self, client: &Client, proto: xlib::Atom) -> bool { - if self.check_for_protocol(client, proto) { - let mut data = xlib::ClientMessageData::default(); - data.set_long(0, proto as i64); - - let mut event = XEvent { - client_message: xlib::XClientMessageEvent { - type_: xlib::ClientMessage, - serial: 0, - display: self.dpy(), - send_event: 0, - window: client.window, - format: 32, - message_type: self.atoms.protocols, - data, - }, - }; - - unsafe { - xlib::XSendEvent( - self.dpy(), - client.window, - 0, - xlib::NoEventMask, - &mut event, - ); - } - - true - } else { - false - } - } - - pub fn make_key(&self, key: S, modmask: u32) -> KeyOrButton - where - S: AsRef, - { - let key = self.keycode(key); - - KeyOrButton::Key(key, modmask) - } - - fn keycode(&self, string: S) -> i32 - where - S: AsRef, - { - let c_string = CString::new(string.as_ref()).unwrap(); - - unsafe { - let keysym = xlib::XStringToKeysym(c_string.as_ptr()); - xlib::XKeysymToKeycode(self.dpy(), keysym) as i32 - } - } - - fn get_numlock_mask(&self) -> u32 { - unsafe { - let modmap = xlib::XGetModifierMapping(self.dpy()); - let max_keypermod = (*modmap).max_keypermod; - - for i in 0..8 { - for j in 0..max_keypermod { - if *(*modmap) - .modifiermap - .offset((i * max_keypermod + j) as isize) - == xlib::XKeysymToKeycode( - self.dpy(), - x11::keysym::XK_Num_Lock as u64, - ) - { - return 1 << i; - } - } - } - } - - 0 - } - - pub fn get_clean_mask(&self) -> u32 { - !(self.get_numlock_mask() | LockMask) - & (ShiftMask - | ControlMask - | Mod1Mask - | Mod2Mask - | Mod3Mask - | Mod4Mask - | Mod5Mask) - } - - #[allow(dead_code)] - pub fn clean_mask(&self, mask: u32) -> u32 { - mask & self.get_clean_mask() - } - - pub fn are_masks_equal(&self, rhs: u32, lhs: u32) -> bool { - let clean = self.get_clean_mask(); - - rhs & clean == lhs & clean - } -} - -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 - } -} - -impl Atoms { - 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); - } -}