diff --git a/examples/cursor.rs b/examples/cursor.rs index 167c5cb1..995c6620 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -11,15 +11,15 @@ mod support; #[cfg(target_os = "android")] android_start!(main); -fn main() { +fn main() { let window = glutin::WindowBuilder::new().build().unwrap(); - window.set_title("A fantastic window!"); + window.set_title("A fantastic window!"); unsafe { window.make_current().unwrap() }; let context = support::load(&window); let cursors = [MouseCursor::Default, MouseCursor::Crosshair, MouseCursor::Hand, MouseCursor::Arrow, MouseCursor::Move, MouseCursor::Text, MouseCursor::Wait, MouseCursor::Help, MouseCursor::Progress, MouseCursor::NotAllowed, MouseCursor::ContextMenu, MouseCursor::NoneCursor, MouseCursor::Cell, MouseCursor::VerticalText, MouseCursor::Alias, MouseCursor::Copy, MouseCursor::NoDrop, MouseCursor::Grab, MouseCursor::Grabbing, MouseCursor::AllScroll, MouseCursor::ZoomIn, MouseCursor::ZoomOut, MouseCursor::EResize, MouseCursor::NResize, MouseCursor::NeResize, MouseCursor::NwResize, MouseCursor::SResize, MouseCursor::SeResize, MouseCursor::SwResize, MouseCursor::WResize, MouseCursor::EwResize, MouseCursor::NsResize, MouseCursor::NeswResize, MouseCursor::NwseResize, MouseCursor::ColResize, MouseCursor::RowResize]; let mut cursor_idx = 0; - + for event in window.wait_events() { match event { Event::KeyboardInput(ElementState::Pressed, _, _) => { diff --git a/src/api/win32/callback.rs b/src/api/win32/callback.rs index 5cd8ade5..d879da52 100644 --- a/src/api/win32/callback.rs +++ b/src/api/win32/callback.rs @@ -256,7 +256,7 @@ pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, CursorState::Normal => { user32::SetCursor(user32::LoadCursorW( ptr::null_mut(), - winapi::IDC_ARROW)); + window_state.cursor)); }, CursorState::Grab | CursorState::Hide => { user32::SetCursor(ptr::null_mut()); diff --git a/src/api/win32/init.rs b/src/api/win32/init.rs index 26ccba65..394923d3 100644 --- a/src/api/win32/init.rs +++ b/src/api/win32/init.rs @@ -217,6 +217,7 @@ unsafe fn init(title: Vec, window: &WindowAttributes, pf_reqs: &PixelFormat // Creating a mutex to track the current window state let window_state = Arc::new(Mutex::new(WindowState { + cursor: winapi::IDC_ARROW, // use arrow by default cursor_state: CursorState::Normal, attributes: window.clone() })); diff --git a/src/api/win32/mod.rs b/src/api/win32/mod.rs index 7a7f42ae..4dceaef1 100644 --- a/src/api/win32/mod.rs +++ b/src/api/win32/mod.rs @@ -42,9 +42,13 @@ lazy_static! { static ref WAKEUP_MSG_ID: u32 = unsafe { user32::RegisterWindowMessageA("Glutin::EventID".as_ptr() as *const i8) }; } +/// Cursor +pub type Cursor = *const u16; + /// Contains information about states and the window for the callback. #[derive(Clone)] pub struct WindowState { + pub cursor: Cursor, pub cursor_state: CursorState, pub attributes: WindowAttributes } @@ -112,7 +116,7 @@ impl Window { let opengl = opengl.clone().map_sharing(|sharing| { match sharing.context { Context::Wgl(ref c) => RawContext::Wgl(c.get_hglrc()), - Context::Egl(_) => unimplemented!(), // FIXME: + Context::Egl(_) => unimplemented!(), // FIXME: } }); @@ -261,41 +265,55 @@ impl Window { #[inline] pub fn set_cursor(&self, _cursor: MouseCursor) { - unimplemented!() + let cursor_id = match _cursor { + MouseCursor::Arrow | MouseCursor::Default => winapi::IDC_ARROW, + MouseCursor::Hand => winapi::IDC_HAND, + MouseCursor::Crosshair => winapi::IDC_CROSS, + MouseCursor::Text | MouseCursor::VerticalText => winapi::IDC_IBEAM, + MouseCursor::NotAllowed | MouseCursor::NoDrop => winapi::IDC_NO, + MouseCursor::EResize => winapi::IDC_SIZEWE, + MouseCursor::NResize => winapi::IDC_SIZENS, + MouseCursor::WResize => winapi::IDC_SIZEWE, + MouseCursor::SResize => winapi::IDC_SIZENS, + MouseCursor::EwResize | MouseCursor::ColResize => winapi::IDC_SIZEWE, + MouseCursor::NsResize | MouseCursor::RowResize => winapi::IDC_SIZENS, + MouseCursor::Wait | MouseCursor::Progress => winapi::IDC_WAIT, + MouseCursor::Help => winapi::IDC_HELP, + _ => winapi::IDC_ARROW, // use arrow for the missing cases. + }; + + unsafe { + let mut cur = self.window_state.lock().unwrap(); + cur.cursor = mem::transmute(cursor_id); + } } + pub fn set_cursor_state(&self, state: CursorState) -> Result<(), String> { - let mut current_state = self.window_state.lock().unwrap().cursor_state; + let mut current_state = self.window_state.lock().unwrap(); let foreground_thread_id = unsafe { user32::GetWindowThreadProcessId(self.window.0, ptr::null_mut()) }; let current_thread_id = unsafe { kernel32::GetCurrentThreadId() }; unsafe { user32::AttachThreadInput(foreground_thread_id, current_thread_id, 1) }; - let res = match (state, current_state) { + let res = match (state, current_state.cursor_state) { (CursorState::Normal, CursorState::Normal) => Ok(()), (CursorState::Hide, CursorState::Hide) => Ok(()), (CursorState::Grab, CursorState::Grab) => Ok(()), (CursorState::Hide, CursorState::Normal) => { - unsafe { - user32::SetCursor(ptr::null_mut()); - current_state = CursorState::Hide; - Ok(()) - } + current_state.cursor_state = CursorState::Hide; + Ok(()) }, (CursorState::Normal, CursorState::Hide) => { - unsafe { - user32::SetCursor(user32::LoadCursorW(ptr::null_mut(), winapi::IDC_ARROW)); - current_state = CursorState::Normal; - Ok(()) - } + current_state.cursor_state = CursorState::Normal; + Ok(()) }, - (CursorState::Grab, CursorState::Normal) => { + (CursorState::Grab, CursorState::Normal) | (CursorState::Grab, CursorState::Hide) => { unsafe { - user32::SetCursor(ptr::null_mut()); let mut rect = mem::uninitialized(); if user32::GetClientRect(self.window.0, &mut rect) == 0 { return Err(format!("GetWindowRect failed")); @@ -305,18 +323,17 @@ impl Window { if user32::ClipCursor(&rect) == 0 { return Err(format!("ClipCursor failed")); } - current_state = CursorState::Grab; + current_state.cursor_state = CursorState::Grab; Ok(()) } }, (CursorState::Normal, CursorState::Grab) => { unsafe { - user32::SetCursor(user32::LoadCursorW(ptr::null_mut(), winapi::IDC_ARROW)); if user32::ClipCursor(ptr::null()) == 0 { return Err(format!("ClipCursor failed")); } - current_state = CursorState::Normal; + current_state.cursor_state = CursorState::Normal; Ok(()) } },