use crate::error::Result; use xcb::{ x::{CloseFont, CreateGlyphCursor, Cursor, Font, FreeCursor, OpenFont}, Connection as RawConnection, }; // https://tronche.com/gui/x/xlib/appendix/b/ const XC_LEFT_PTR: u16 = 68; const XC_FLEUR: u16 = 52; /// Caches X11 cursor objects #[derive(Debug)] pub struct Cursors { #[allow(unused)] // Needs to be kept around since the cursors depend on it font: Font, normal: Cursor, moving: Cursor, } impl Cursors { /// Load default cursors using the given connection. pub fn new_with(conn: &RawConnection) -> Result { // Open cursor font let font = conn.generate_id(); conn.check_request(conn.send_request_checked(&OpenFont { fid: font, name: b"cursor", }))?; Ok(Self { normal: Self::load_cursor(conn, font, XC_LEFT_PTR)?, moving: Self::load_cursor(conn, font, XC_FLEUR)?, font, }) } /// Load the cursor with the given id from `font` fn load_cursor(conn: &RawConnection, font: Font, id: u16) -> Result { let cid = conn.generate_id(); // https://github.com/mirror/libX11/blob/ff8706a5eae25b8bafce300527079f68a201d27f/src/Cursor.c#L34 conn.check_request(conn.send_request_checked(&CreateGlyphCursor { cid, source_font: font, mask_font: font, source_char: id, mask_char: id + 1, fore_red: 0, fore_green: 0, fore_blue: 0, back_red: u16::MAX, back_green: u16::MAX, back_blue: u16::MAX, }))?; Ok(cid) } pub const fn normal(&self) -> Cursor { self.normal } pub const fn moving(&self) -> Cursor { self.moving } /// Free the associated resources to avoid leaking them. /// This object must not be used again after this method is called, as all resources will be invalid. pub unsafe fn free(&self, conn: &RawConnection) { conn.send_request(&FreeCursor { cursor: self.normal, }); conn.send_request(&CloseFont { font: self.font }); } }