2023-05-09 20:19:35 +03:00
|
|
|
use std::ffi::CString;
|
|
|
|
|
|
2019-08-26 19:06:59 -07:00
|
|
|
use crate::window::CursorIcon;
|
|
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
impl XConnection {
|
|
|
|
|
pub fn set_cursor_icon(&self, window: ffi::Window, cursor: Option<CursorIcon>) {
|
|
|
|
|
let cursor = *self
|
|
|
|
|
.cursor_cache
|
|
|
|
|
.lock()
|
2022-08-31 18:32:19 +02:00
|
|
|
.unwrap()
|
2019-08-26 19:06:59 -07:00
|
|
|
.entry(cursor)
|
|
|
|
|
.or_insert_with(|| self.get_cursor(cursor));
|
|
|
|
|
|
|
|
|
|
self.update_cursor(window, cursor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn create_empty_cursor(&self) -> ffi::Cursor {
|
|
|
|
|
let data = 0;
|
|
|
|
|
let pixmap = unsafe {
|
|
|
|
|
let screen = (self.xlib.XDefaultScreen)(self.display);
|
|
|
|
|
let window = (self.xlib.XRootWindow)(self.display, screen);
|
|
|
|
|
(self.xlib.XCreateBitmapFromData)(self.display, window, &data, 1, 1)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if pixmap == 0 {
|
|
|
|
|
panic!("failed to allocate pixmap for cursor");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
// We don't care about this color, since it only fills bytes
|
|
|
|
|
// in the pixmap which are not 0 in the mask.
|
|
|
|
|
let mut dummy_color = MaybeUninit::uninit();
|
|
|
|
|
let cursor = (self.xlib.XCreatePixmapCursor)(
|
|
|
|
|
self.display,
|
|
|
|
|
pixmap,
|
|
|
|
|
pixmap,
|
|
|
|
|
dummy_color.as_mut_ptr(),
|
|
|
|
|
dummy_color.as_mut_ptr(),
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
);
|
|
|
|
|
(self.xlib.XFreePixmap)(self.display, pixmap);
|
|
|
|
|
|
|
|
|
|
cursor
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_cursor(&self, cursor: Option<CursorIcon>) -> ffi::Cursor {
|
|
|
|
|
let cursor = match cursor {
|
|
|
|
|
Some(cursor) => cursor,
|
|
|
|
|
None => return self.create_empty_cursor(),
|
|
|
|
|
};
|
|
|
|
|
|
2023-05-09 20:19:35 +03:00
|
|
|
let name = CString::new(cursor.name()).unwrap();
|
|
|
|
|
unsafe {
|
|
|
|
|
(self.xcursor.XcursorLibraryLoadCursor)(self.display, name.as_ptr() as *const c_char)
|
2019-08-26 19:06:59 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn update_cursor(&self, window: ffi::Window, cursor: ffi::Cursor) {
|
|
|
|
|
unsafe {
|
|
|
|
|
(self.xlib.XDefineCursor)(self.display, window, cursor);
|
|
|
|
|
|
|
|
|
|
self.flush_requests().expect("Failed to set the cursor");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|