From 11e27889aec6dfb943c6fb1aa97900e21e319bb7 Mon Sep 17 00:00:00 2001 From: Rengierof Date: Sat, 26 Dec 2015 16:38:00 +0200 Subject: Fixes cursor behavior with windows --- examples/cursor.rs | 6 +++--- src/api/win32/callback.rs | 2 +- src/api/win32/init.rs | 1 + src/api/win32/mod.rs | 55 +++++++++++++++++++++++++++++++---------------- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/examples/cursor.rs b/examples/cursor.rs index 167c5cb..995c662 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 5cd8ade..d879da5 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 26ccba6..394923d 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 7a7f42a..4dceaef 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(()) } }, -- cgit v1.2.3 From d2ac6cfa11899378546c1fb4b71943c83bb3dc62 Mon Sep 17 00:00:00 2001 From: Rengierof Date: Sat, 26 Dec 2015 16:47:25 +0200 Subject: Fixed grabbing example. --- examples/grabbing.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/grabbing.rs b/examples/grabbing.rs index 4b12b02..485be78 100644 --- a/examples/grabbing.rs +++ b/examples/grabbing.rs @@ -18,8 +18,8 @@ fn main() { let context = support::load(&window); let mut grabbed = false; - - for event in window.poll_events() { + + for event in window.wait_events() { match event { Event::KeyboardInput(ElementState::Pressed, _, _) => { if grabbed { @@ -33,6 +33,8 @@ fn main() { } }, + Event::Closed => break, + a @ Event::MouseMoved(_) => { println!("{:?}", a); }, @@ -44,4 +46,3 @@ fn main() { let _ = window.swap_buffers(); } } - -- cgit v1.2.3 From bc811fa587ac3f9c996d71cfc285b8edad0bf9f7 Mon Sep 17 00:00:00 2001 From: Rengierof Date: Sat, 26 Dec 2015 20:23:20 +0200 Subject: Removed unnecessary unsafe code block --- src/api/win32/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/api/win32/mod.rs b/src/api/win32/mod.rs index 4dceaef..cb7e170 100644 --- a/src/api/win32/mod.rs +++ b/src/api/win32/mod.rs @@ -43,7 +43,7 @@ lazy_static! { } /// Cursor -pub type Cursor = *const u16; +pub type Cursor = *const winapi::wchar_t; /// Contains information about states and the window for the callback. #[derive(Clone)] @@ -282,10 +282,8 @@ impl Window { _ => winapi::IDC_ARROW, // use arrow for the missing cases. }; - unsafe { - let mut cur = self.window_state.lock().unwrap(); - cur.cursor = mem::transmute(cursor_id); - } + let mut cur = self.window_state.lock().unwrap(); + cur.cursor = cursor_id; } -- cgit v1.2.3