ndless_sdl/
mouse.rs

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}