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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
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<Self> {
// 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<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 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 });
}
}
|