summaryrefslogtreecommitdiff
path: root/src/cursors.rs
blob: 0a4e0418db78d9edd72fe5279f98ba773c7e1ff4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use crate::error::*;
use xcb::{
    x::{CreateGlyphCursor, Cursor, Font, OpenFont},
    Connection,
};

// https://tronche.com/gui/x/xlib/appendix/b/
const XC_LEFT_PTR: u16 = 68;

/// 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,
}

impl Cursors {
    /// Load default cursors using the given connection.
    pub fn new_with(conn: &Connection) -> Result<Self> {
        // Open cursor font
        let font = conn.generate_id();
        conn.check_request(conn.send_request_checked(&OpenFont {
            fid: font,
            name: "cursor".as_bytes(),
        }))?;

        Ok(Self {
            normal: Self::load_cursor(conn, font, XC_LEFT_PTR)?,
            font,
        })
    }

    /// Load the cursor with the given id from `font`
    fn load_cursor(conn: &Connection, font: Font, id: u16) -> Result<Cursor> {
        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 fn normal(&self) -> Cursor {
        self.normal
    }
}