From 765e0a74a945eb1899b98f79eb1076f88db3e806 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sun, 15 Sep 2013 15:10:22 -0500 Subject: [PATCH 1/3] Add mouse and cursor API --- src/mouse.rs | 157 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 153 insertions(+), 4 deletions(-) diff --git a/src/mouse.rs b/src/mouse.rs index e1f9a68f..7d56923a 100644 --- a/src/mouse.rs +++ b/src/mouse.rs @@ -1,3 +1,9 @@ +use std::ptr; +use std::vec; + +use get_error; +use surface; +use video; pub mod ll { use std::libc::{c_int, c_uint, c_void, uint8_t, uint32_t}; @@ -46,6 +52,84 @@ pub mod ll { externfn!(fn SDL_ShowCursor(toggle: SDL_MouseState) -> SDL_MouseState) } +#[deriving(Eq)] +pub enum SystemCursor { + ArrowCursor = ll::SDL_SYSTEM_CURSOR_ARROW, + IBeamCursor = ll::SDL_SYSTEM_CURSOR_IBEAM, + WaitCursor = ll::SDL_SYSTEM_CURSOR_WAIT, + CrosshairCursor = ll::SDL_SYSTEM_CURSOR_CROSSHAIR, + WaitArrowCursor = ll::SDL_SYSTEM_CURSOR_WAITARROW, + SizeNWSECursor = ll::SDL_SYSTEM_CURSOR_SIZENWSE, + SizeNESWCursor = ll::SDL_SYSTEM_CURSOR_SIZENESW, + SizeWECursor = ll::SDL_SYSTEM_CURSOR_SIZEWE, + SizeNSCursor = ll::SDL_SYSTEM_CURSOR_SIZENS, + SizeAllCursor = ll::SDL_SYSTEM_CURSOR_SIZEALL, + NoCursor = ll::SDL_SYSTEM_CURSOR_NO, + HandCursor = ll::SDL_SYSTEM_CURSOR_HAND, +} + +#[deriving(Eq)] +pub struct Cursor { + raw: *ll::SDL_Cursor, + owned: bool +} + +impl Drop for Cursor { + fn drop(&self) { + if self.owned { + unsafe { + ll::SDL_FreeCursor(self.raw); + } + } + } +} + +impl Cursor { + pub fn new(data: &[u8], mask: &[u8], width: int, height: int, hot_x: int, hot_y: int) -> Result<~Cursor, ~str> { + unsafe { + let raw = ll::SDL_CreateCursor(vec::raw::to_ptr(data), + vec::raw::to_ptr(mask), + width as i32, height as i32, + hot_x as i32, hot_y as i32); + + if raw == ptr::null() { + Err(get_error()) + } else { + Ok(~Cursor{ raw: raw, owned: true }) + } + } + } + + pub fn from_surface(surface: surface::Surface, hot_x: int, hot_y: int) -> Result<~Cursor, ~str> { + unsafe { + let raw = ll::SDL_CreateColorCursor(surface.raw, hot_x as i32, + hot_y as i32); + + if raw == ptr::null() { + Err(get_error()) + } else { + Ok(~Cursor{ raw: raw, owned: true }) + } + } + } + + pub fn from_system(cursor: SystemCursor) -> Result<~Cursor, ~str> { + unsafe { + let raw = ll::SDL_CreateSystemCursor(cursor as u32); + + if raw == ptr::null() { + Err(get_error()) + } else { + Ok(~Cursor{ raw: raw, owned: true }) + } + } + } + + pub fn set(&self) { + unsafe { ll::SDL_SetCursor(self.raw); } + } +} + #[deriving(Eq)] pub enum Mouse { LeftMouse, @@ -58,10 +142,10 @@ pub enum Mouse { #[deriving(Eq)] pub enum MouseState { LeftMouseState = 1, - MiddleMouseState, - RightMouseState, - X1MouseState, - X2MouseState, + MiddleMouseState = 2, + RightMouseState = 4, + X1MouseState = 8, + X2MouseState = 16, } pub fn wrap_mouse(bitflags: u8) -> Mouse { @@ -87,3 +171,68 @@ pub fn wrap_mouse_state(bitflags: u32) -> ~[MouseState] { else { None } }.collect() } + +pub fn get_mouse_focus() -> Result<~video::Window, ~str> { + let raw = unsafe { ll::SDL_GetMouseFocus() }; + if raw == ptr::null() { + Err(get_error()) + } else { + Ok(~video::Window{ raw: raw, owned: false }) + } +} + +pub fn get_mouse_state() -> (~[MouseState], int, int) { + let x = 0; + let y = 0; + let raw = unsafe { ll::SDL_GetMouseState(&x, &y) }; + + return (wrap_mouse_state(raw), x as int, y as int); +} + +pub fn get_relative_mouse_state() -> (~[MouseState], int, int) { + let x = 0; + let y = 0; + let raw = unsafe { ll::SDL_GetRelativeMouseState(&x, &y) }; + + return (wrap_mouse_state(raw), x as int, y as int); +} + +pub fn warp_mouse_in_window(window: &video::Window, x: i32, y: i32) { + unsafe { ll::SDL_WarpMouseInWindow(window.raw, x, y); } +} + +pub fn set_relative_mouse_mode(on: bool) { + unsafe { ll::SDL_SetRelativeMouseMode(on as i32); } +} + +pub fn get_relative_mouse_mode() -> bool { + unsafe { ll::SDL_GetRelativeMouseMode() == 1 } +} + +pub fn get_cursor() -> Option<~Cursor> { + let raw = unsafe { ll::SDL_GetCursor() }; + + if raw == ptr::null() { + None + } else { + Some(~Cursor { raw: raw, owned: false }) + } +} + +pub fn get_default_cursor() -> Option<~Cursor> { + let raw = unsafe { ll::SDL_GetDefaultCursor() }; + + if raw == ptr::null() { + None + } else { + Some(~Cursor { raw: raw, owned: false }) + } +} + +pub fn is_cursor_showing() -> bool { + unsafe { ll::SDL_ShowCursor(ll::SDL_QUERY) == 1 } +} + +pub fn show_cursor(show: bool) { + unsafe { ll::SDL_ShowCursor(show as i32); } +} From a5e9804803383500dc8f7837dcb6dc9fbb74262e Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sun, 15 Sep 2013 16:42:59 -0500 Subject: [PATCH 2/3] Add keyboard API --- src/codegen/keycode.rs | 8 +-- src/codegen/scancode.rs | 8 +-- src/keyboard.rs | 115 ++++++++++++++++++++++++++++++++++++++++ src/mouse.rs | 6 +-- 4 files changed, 128 insertions(+), 9 deletions(-) diff --git a/src/codegen/keycode.rs b/src/codegen/keycode.rs index fd1bf943..5037c5d6 100644 --- a/src/codegen/keycode.rs +++ b/src/codegen/keycode.rs @@ -271,12 +271,14 @@ pub fn generate(output_dir: &Path) { out.write_str("// This automatically generated file is used as sdl2::keycode. use std::num::IntConvertible; +use std::to_bytes::IterBytes; +#[deriving(IterBytes)] #[deriving(Eq)] pub enum KeyCode { "); for &entry in entries.iter() { - out.write_str(fmt!(" %s = %u,\n", entry.padded_ident(), entry.code)); + out.write_str(fmt!(" %s = %u_i,\n", entry.padded_ident(), entry.code)); } out.write_str(" @@ -303,7 +305,7 @@ impl IntConvertible for KeyCode { /// Get a *registered* key code. /// - /// This will fail if an unknown code is passed. + /// This will return UnknownKey if an unknown code is passed. /// /// For example, `from_int(13)` will return `ReturnKey`. fn from_int(n: int) -> KeyCode { @@ -313,7 +315,7 @@ impl IntConvertible for KeyCode { out.write_str(fmt!(" %u => %s,\n", entry.code, entry.ident())); } out.write_str(" - _ => { fail!(fmt!(\"No registered key code %d\", n)); } + _ => { UnknownKey } } } }"); diff --git a/src/codegen/scancode.rs b/src/codegen/scancode.rs index f4e4643c..6077f308 100644 --- a/src/codegen/scancode.rs +++ b/src/codegen/scancode.rs @@ -278,12 +278,14 @@ pub fn generate(output_dir: &Path) { out.write_str("// This automatically generated file is used as sdl2::scancode. use std::num::IntConvertible; +use std::to_bytes::IterBytes; +#[deriving(IterBytes)] #[deriving(Eq)] pub enum ScanCode { "); for &entry in entries.iter() { - out.write_str(fmt!(" %s = %u,\n", entry.padded_ident(), entry.code)); + out.write_str(fmt!(" %s = %u_u,\n", entry.padded_ident(), entry.code)); } out.write_str(" @@ -310,7 +312,7 @@ impl IntConvertible for ScanCode { /// Get a *registered* scan code. /// - /// This will fail if an unknown code is passed. + /// This will return UnknownScanCode if an unknown code is passed. /// /// For example, `from_int(4)` will return `AScanCode`. fn from_int(n: int) -> ScanCode { @@ -320,7 +322,7 @@ impl IntConvertible for ScanCode { out.write_str(fmt!(" %u => %s,\n", entry.code, entry.ident())); } out.write_str(" - _ => { fail!(fmt!(\"No registered scan code %d\", n)); } + _ => { UnknownScanCode } } } }"); diff --git a/src/keyboard.rs b/src/keyboard.rs index 173033c7..3bd5cb48 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -1,3 +1,13 @@ +use std::hashmap::HashMap; +use std::num::IntConvertible; +use std::ptr; +use std::str; +use std::vec; + +use keycode::KeyCode; +use rect::Rect; +use scancode::ScanCode; +use video::Window; pub mod ll { use std::libc::{c_int, c_schar, c_uint, int32_t, uint8_t, uint16_t, @@ -74,3 +84,108 @@ pub fn wrap_mod_state(bitflags: ll::SDL_Keymod) -> ~[Mod] { else { None } }.collect() } + +pub fn get_keyboard_focus() -> Option<~Window> { + let raw = unsafe { ll::SDL_GetKeyboardFocus() }; + if raw == ptr::null() { + None + } else { + Some(~Window{ raw: raw, owned: false }) + } +} + +pub fn get_keyboard_state() -> ~HashMap { + let mut state: ~HashMap = ~HashMap::new(); + let count = 0; + + let raw = unsafe { vec::raw::from_buf_raw(ll::SDL_GetKeyboardState(&count), + count as uint) }; + + let mut current = 0; + while current < raw.len() { + state.insert(IntConvertible::from_int(current as int), + raw[current] == 1); + current += 1; + } + + return state; +} + +pub fn get_mod_state() -> ~[Mod] { + unsafe { wrap_mod_state(ll::SDL_GetModState()) } +} + +pub fn set_mod_state(flags: &[Mod]) { + let mut state = 0; + for flag in flags.iter() { + state |= *flag as ll::SDL_Keymod; + } + + unsafe { ll::SDL_SetModState(state); } +} + +pub fn get_key_from_scancode(scancode: ScanCode) -> KeyCode { + unsafe { + IntConvertible::from_int(ll::SDL_GetKeyFromScancode(scancode.code() + as u32) as int) + } +} + +pub fn get_scancode_from_key(key: KeyCode) -> ScanCode { + unsafe { + IntConvertible::from_int(ll::SDL_GetScancodeFromKey(key.code()) + as int) + } +} + +pub fn get_scancode_name(scancode: ScanCode) -> ~str { + unsafe { + str::raw::from_c_str(ll::SDL_GetScancodeName(scancode.code() as u32)) + } +} + +pub fn get_scancode_from_name(name: &str) -> ScanCode { + unsafe { + do name.with_c_str |name| { + IntConvertible::from_int(ll::SDL_GetScancodeFromName(name) as int) + } + } +} + +pub fn get_key_name(key: KeyCode) -> ~str { + unsafe { + str::raw::from_c_str(ll::SDL_GetKeyName(key.code())) + } +} + +pub fn get_key_from_name(name: &str) -> KeyCode { + unsafe { + do name.with_c_str |name| { + IntConvertible::from_int(ll::SDL_GetKeyFromName(name) as int) + } + } +} + +pub fn start_text_input() { + unsafe { ll::SDL_StartTextInput(); } +} + +pub fn is_text_input_active() -> bool { + unsafe { ll::SDL_IsTextInputActive() == 1 } +} + +pub fn stop_text_input() { + unsafe { ll::SDL_StopTextInput(); } +} + +pub fn set_text_input_rect(rect: &Rect) { + unsafe { ll::SDL_SetTextInputRect(rect); } +} + +pub fn has_screen_keyboard_support() -> bool { + unsafe { ll::SDL_HasScreenKeyboardSupport() == 1 } +} + +pub fn is_screen_keyboard_shown(window: &Window) -> bool { + unsafe { ll::SDL_IsScreenKeyboardShown(window.raw) == 1 } +} diff --git a/src/mouse.rs b/src/mouse.rs index 7d56923a..8f539abd 100644 --- a/src/mouse.rs +++ b/src/mouse.rs @@ -172,12 +172,12 @@ pub fn wrap_mouse_state(bitflags: u32) -> ~[MouseState] { }.collect() } -pub fn get_mouse_focus() -> Result<~video::Window, ~str> { +pub fn get_mouse_focus() -> Option<~video::Window> { let raw = unsafe { ll::SDL_GetMouseFocus() }; if raw == ptr::null() { - Err(get_error()) + None } else { - Ok(~video::Window{ raw: raw, owned: false }) + Some(~video::Window{ raw: raw, owned: false }) } } From 5fd0af58f2b508c13b2f10ce12807eadf548f080 Mon Sep 17 00:00:00 2001 From: Travis Watkins Date: Sun, 15 Sep 2013 17:02:20 -0500 Subject: [PATCH 3/3] Add touch API --- src/touch.rs | 57 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/touch.rs b/src/touch.rs index 8448918e..15a43e3a 100644 --- a/src/touch.rs +++ b/src/touch.rs @@ -1,19 +1,48 @@ +use std::ptr; + +pub type TouchDevice = ll::SDL_TouchID; + +#[deriving(Eq)] +pub struct Finger { + id: TouchDevice, + x: f32, + y: f32, + pressure: f32, +} pub mod ll { - use std::libc::{c_float, c_int, int64_t}; + use std::libc::{c_int, int64_t}; + use touch::Finger; - pub type SDL_TouchID = int64_t; - pub type SDL_FingerID = int64_t; + pub type SDL_TouchID = int64_t; + pub type SDL_FingerID = int64_t; + pub type SDL_Finger = Finger; - pub struct SDL_Finger { - id: SDL_FingerID, - x: c_float, - y: c_float, - pressure: c_float, - } - - externfn!(fn SDL_GetNumTouchDevices() -> c_int) - externfn!(fn SDL_GetTouchDevice(index: c_int) -> SDL_TouchID) - externfn!(fn SDL_GetNumTouchFingers(touchID: SDL_TouchID) -> c_int) - externfn!(fn SDL_GetTouchFinger(touchID: SDL_TouchID, index: c_int)) + externfn!(fn SDL_GetNumTouchDevices() -> c_int) + externfn!(fn SDL_GetTouchDevice(index: c_int) -> SDL_TouchID) + externfn!(fn SDL_GetNumTouchFingers(touchID: SDL_TouchID) -> c_int) + externfn!(fn SDL_GetTouchFinger(touchID: SDL_TouchID, index: c_int) -> + *SDL_Finger) +} + +pub fn get_num_touch_devices() -> int { + unsafe { ll::SDL_GetNumTouchDevices() as int } +} + +pub fn get_touch_device(index: int) -> TouchDevice { + unsafe { ll::SDL_GetTouchDevice(index as i32) } +} + +pub fn get_num_touch_fingers(touch: TouchDevice) -> int { + unsafe { ll::SDL_GetNumTouchFingers(touch) as int } +} + +pub fn get_touch_finger(touch: TouchDevice, index: int) -> Option { + let raw = unsafe { ll::SDL_GetTouchFinger(touch, index as i32) }; + + if raw == ptr::null() { + None + } else { + unsafe { Some(*raw) } + } }