1use cty::c_int;
2
3use crate::get_error;
4use ndless::prelude::*;
5pub mod ll {
6 #![allow(non_camel_case_types)]
7
8 use cty::{c_int, c_void, int16_t, uint16_t, uint8_t};
9
10 use crate::Rect;
11
12 pub static SDL_DISABLE: c_int = 0;
13 pub static SDL_ENABLE: c_int = 1;
14 pub static SDL_QUERY: c_int = -1;
15
16 pub type WMcursor = c_void;
17
18 #[repr(C)]
19 #[derive(Copy, Clone)]
20 pub struct SDL_Cursor {
21 pub area: Rect,
22 pub hot_x: int16_t,
23 pub hot_y: int16_t,
24 pub data: *mut uint8_t,
25 pub mask: *mut uint8_t,
26 pub save: [*mut uint8_t; 2],
27 pub wm_cursor: *mut WMcursor,
28 }
29
30 extern "C" {
31 pub fn SDL_ShowCursor(toggle: c_int) -> c_int;
32 pub fn SDL_CreateCursor(
33 data: *mut uint8_t,
34 mask: *mut uint8_t,
35 w: c_int,
36 h: c_int,
37 hot_x: c_int,
38 hot_y: c_int,
39 ) -> *mut SDL_Cursor;
40 pub fn SDL_SetCursor(cursor: *mut SDL_Cursor);
41 pub fn SDL_GetCursor() -> *mut SDL_Cursor;
42 pub fn SDL_FreeCursor(cursor: *mut SDL_Cursor);
43 pub fn SDL_WarpMouse(x: uint16_t, y: uint16_t);
44 }
45}
46
47pub fn warp_mouse(x: u16, y: u16) {
48 unsafe {
49 ll::SDL_WarpMouse(x, y);
50 }
51}
52
53#[derive(PartialEq)]
54pub struct Cursor {
55 pub raw: *mut ll::SDL_Cursor,
56 pub owned: bool,
57}
58
59fn wrap_cursor(raw: *mut ll::SDL_Cursor, owned: bool) -> Cursor {
60 Cursor { raw, owned }
61}
62
63impl Cursor {
64 pub fn new(
65 data: &[u8],
66 mask: &[u8],
67 w: isize,
68 h: isize,
69 hot_x: isize,
70 hot_y: isize,
71 ) -> Result<Cursor, String> {
72 let mut data = data.to_vec();
73 let mut mask = mask.to_vec();
74 unsafe {
75 let raw = ll::SDL_CreateCursor(
76 data.as_mut_ptr(),
77 mask.as_mut_ptr(),
78 w as c_int,
79 h as c_int,
80 hot_x as c_int,
81 hot_y as c_int,
82 );
83
84 if raw.is_null() {
85 Err(get_error())
86 } else {
87 Ok(wrap_cursor(raw, true))
88 }
89 }
90 }
91}
92
93impl Drop for Cursor {
94 fn drop(&mut self) {
95 unsafe {
96 if self.owned {
97 ll::SDL_FreeCursor(self.raw);
98 }
99 }
100 }
101}
102
103pub fn set_cursor(cursor: &Cursor) {
104 unsafe {
105 ll::SDL_SetCursor(cursor.raw);
106 }
107}
108
109pub fn get_cursor() -> Cursor {
110 unsafe { wrap_cursor(ll::SDL_GetCursor(), false) }
111}
112
113pub fn set_cursor_visible(visible: bool) {
114 unsafe {
115 ll::SDL_ShowCursor(visible as c_int);
116 }
117}
118
119pub fn toggle_cursor_visible() {
120 unsafe {
121 if ll::SDL_ShowCursor(ll::SDL_QUERY) == ll::SDL_ENABLE {
122 ll::SDL_ShowCursor(ll::SDL_DISABLE);
123 } else {
124 ll::SDL_ShowCursor(ll::SDL_ENABLE);
125 }
126 }
127}
128
129pub fn is_cursor_visible() -> bool {
130 unsafe { ll::SDL_ShowCursor(ll::SDL_QUERY) == ll::SDL_ENABLE }
131}