diff options
Diffstat (limited to 'src/win32/callback.rs')
-rw-r--r-- | src/win32/callback.rs | 253 |
1 files changed, 0 insertions, 253 deletions
diff --git a/src/win32/callback.rs b/src/win32/callback.rs deleted file mode 100644 index e852eeb..0000000 --- a/src/win32/callback.rs +++ /dev/null @@ -1,253 +0,0 @@ -use std::mem; -use std::ptr; -use std::cell::RefCell; -use std::sync::mpsc::Sender; -use std::sync::{Arc, Mutex}; - -use CursorState; -use Event; -use super::event; - -use user32; -use winapi; - -/// There's no parameters passed to the callback function, so it needs to get -/// its context (the HWND, the Sender for events, etc.) stashed in -/// a thread-local variable. -thread_local!(pub static CONTEXT_STASH: RefCell<Option<ThreadLocalData>> = RefCell::new(None)); - -pub struct ThreadLocalData { - pub win: winapi::HWND, - pub sender: Sender<Event>, - pub cursor_state: Arc<Mutex<CursorState>> -} - -/// Checks that the window is the good one, and if so send the event to it. -fn send_event(input_window: winapi::HWND, event: Event) { - CONTEXT_STASH.with(|context_stash| { - let context_stash = context_stash.borrow(); - let stored = match *context_stash { - None => return, - Some(ref v) => v - }; - - let &ThreadLocalData { ref win, ref sender, .. } = stored; - - if win != &input_window { - return; - } - - sender.send(event).ok(); // ignoring if closed - }); -} - -/// This is the callback that is called by `DispatchMessage` in the events loop. -/// -/// Returning 0 tells the Win32 API that the message has been processed. -pub unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, - wparam: winapi::WPARAM, lparam: winapi::LPARAM) - -> winapi::LRESULT -{ - match msg { - winapi::WM_DESTROY => { - use events::Event::Closed; - - CONTEXT_STASH.with(|context_stash| { - let context_stash = context_stash.borrow(); - let stored = match *context_stash { - None => return, - Some(ref v) => v - }; - - let &ThreadLocalData { ref win, .. } = stored; - - if win == &window { - user32::PostQuitMessage(0); - } - }); - - send_event(window, Closed); - 0 - }, - - winapi::WM_ERASEBKGND => { - 1 - }, - - winapi::WM_SIZE => { - use events::Event::Resized; - let w = winapi::LOWORD(lparam as winapi::DWORD) as u32; - let h = winapi::HIWORD(lparam as winapi::DWORD) as u32; - send_event(window, Resized(w, h)); - 0 - }, - - winapi::WM_MOVE => { - use events::Event::Moved; - let x = winapi::LOWORD(lparam as winapi::DWORD) as i32; - let y = winapi::HIWORD(lparam as winapi::DWORD) as i32; - send_event(window, Moved(x, y)); - 0 - }, - - winapi::WM_CHAR => { - use std::mem; - use events::Event::ReceivedCharacter; - let chr: char = mem::transmute(wparam as u32); - send_event(window, ReceivedCharacter(chr)); - 0 - }, - - winapi::WM_MOUSEMOVE => { - use events::Event::MouseMoved; - - let x = winapi::GET_X_LPARAM(lparam) as i32; - let y = winapi::GET_Y_LPARAM(lparam) as i32; - - send_event(window, MouseMoved((x, y))); - - 0 - }, - - winapi::WM_MOUSEWHEEL => { - use events::Event::MouseWheel; - - let value = (wparam >> 16) as i16; - let value = value as i32; - - send_event(window, MouseWheel(value)); - - 0 - }, - - winapi::WM_KEYDOWN => { - use events::Event::KeyboardInput; - use events::ElementState::Pressed; - let scancode = ((lparam >> 16) & 0xff) as u8; - let vkey = event::vkeycode_to_element(wparam); - send_event(window, KeyboardInput(Pressed, scancode, vkey)); - 0 - }, - - winapi::WM_KEYUP => { - use events::Event::KeyboardInput; - use events::ElementState::Released; - let scancode = ((lparam >> 16) & 0xff) as u8; - let vkey = event::vkeycode_to_element(wparam); - send_event(window, KeyboardInput(Released, scancode, vkey)); - 0 - }, - - winapi::WM_LBUTTONDOWN => { - use events::Event::MouseInput; - use events::MouseButton::Left; - use events::ElementState::Pressed; - send_event(window, MouseInput(Pressed, Left)); - 0 - }, - - winapi::WM_LBUTTONUP => { - use events::Event::MouseInput; - use events::MouseButton::Left; - use events::ElementState::Released; - send_event(window, MouseInput(Released, Left)); - 0 - }, - - winapi::WM_RBUTTONDOWN => { - use events::Event::MouseInput; - use events::MouseButton::Right; - use events::ElementState::Pressed; - send_event(window, MouseInput(Pressed, Right)); - 0 - }, - - winapi::WM_RBUTTONUP => { - use events::Event::MouseInput; - use events::MouseButton::Right; - use events::ElementState::Released; - send_event(window, MouseInput(Released, Right)); - 0 - }, - - winapi::WM_MBUTTONDOWN => { - use events::Event::MouseInput; - use events::MouseButton::Middle; - use events::ElementState::Pressed; - send_event(window, MouseInput(Pressed, Middle)); - 0 - }, - - winapi::WM_MBUTTONUP => { - use events::Event::MouseInput; - use events::MouseButton::Middle; - use events::ElementState::Released; - send_event(window, MouseInput(Released, Middle)); - 0 - }, - - winapi::WM_INPUT => { - let mut data: winapi::RAWINPUT = mem::uninitialized(); - let mut data_size = mem::size_of::<winapi::RAWINPUT>() as winapi::UINT; - user32::GetRawInputData(mem::transmute(lparam), winapi::RID_INPUT, - mem::transmute(&mut data), &mut data_size, - mem::size_of::<winapi::RAWINPUTHEADER>() as winapi::UINT); - - if data.header.dwType == winapi::RIM_TYPEMOUSE { - let _x = data.mouse.lLastX; // FIXME: this is not always the relative movement - let _y = data.mouse.lLastY; - // TODO: - //send_event(window, Event::MouseRawMovement { x: x, y: y }); - - 0 - - } else { - user32::DefWindowProcW(window, msg, wparam, lparam) - } - }, - - winapi::WM_SETFOCUS => { - use events::Event::Focused; - send_event(window, Focused(true)); - 0 - }, - - winapi::WM_KILLFOCUS => { - use events::Event::Focused; - send_event(window, Focused(false)); - 0 - }, - - winapi::WM_SETCURSOR => { - CONTEXT_STASH.with(|context_stash| { - let cstash = context_stash.borrow(); - let cstash = cstash.as_ref(); - // there's a very bizarre borrow checker bug - // possibly related to rust-lang/rust/#23338 - let cursor_state = if let Some(cstash) = cstash { - if let Ok(cursor_state) = cstash.cursor_state.lock() { - match *cursor_state { - CursorState::Normal => { - user32::SetCursor(user32::LoadCursorW( - ptr::null_mut(), - winapi::IDC_ARROW)); - }, - CursorState::Grab | CursorState::Hide => { - user32::SetCursor(ptr::null_mut()); - } - } - } - } else { - return - }; - -// let &ThreadLocalData { ref cursor_state, .. } = stored; - }); - 0 - }, - - _ => { - user32::DefWindowProcW(window, msg, wparam, lparam) - } - } -} |