mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
Merge pull request #277 from tomaka/win32-callback
Extract callback from win32/init.rs to its own module
This commit is contained in:
commit
19debf3eb2
194
src/win32/callback.rs
Normal file
194
src/win32/callback.rs
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::sync::mpsc::{Sender, Receiver, channel};
|
||||||
|
|
||||||
|
use Event;
|
||||||
|
use super::event;
|
||||||
|
|
||||||
|
use user32;
|
||||||
|
use winapi;
|
||||||
|
|
||||||
|
/// Stores the current window and its events dispatcher.
|
||||||
|
///
|
||||||
|
/// We only have one window per thread. We still store the HWND in case where we
|
||||||
|
/// receive an event for another window.
|
||||||
|
thread_local!(pub static WINDOW: Rc<RefCell<Option<(winapi::HWND, Sender<Event>)>>> = Rc::new(RefCell::new(None)));
|
||||||
|
|
||||||
|
/// 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) {
|
||||||
|
WINDOW.with(|window| {
|
||||||
|
let window = window.borrow();
|
||||||
|
let stored = match *window {
|
||||||
|
None => return,
|
||||||
|
Some(ref v) => v
|
||||||
|
};
|
||||||
|
|
||||||
|
let &(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 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;
|
||||||
|
|
||||||
|
WINDOW.with(|w| {
|
||||||
|
let w = w.borrow();
|
||||||
|
let &(ref win, _) = match *w {
|
||||||
|
None => return,
|
||||||
|
Some(ref v) => v
|
||||||
|
};
|
||||||
|
|
||||||
|
if win == &window {
|
||||||
|
unsafe { 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 = unsafe { 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_SETFOCUS => {
|
||||||
|
use events::Event::Focused;
|
||||||
|
send_event(window, Focused(true));
|
||||||
|
0
|
||||||
|
},
|
||||||
|
|
||||||
|
winapi::WM_KILLFOCUS => {
|
||||||
|
use events::Event::Focused;
|
||||||
|
send_event(window, Focused(false));
|
||||||
|
0
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => unsafe {
|
||||||
|
user32::DefWindowProcW(window, msg, wparam, lparam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,13 @@
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use super::event;
|
use super::callback;
|
||||||
use super::Window;
|
use super::Window;
|
||||||
use BuilderAttribs;
|
use BuilderAttribs;
|
||||||
use {CreationError, Event};
|
use CreationError;
|
||||||
use CreationError::OsError;
|
use CreationError::OsError;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::rc::Rc;
|
use std::sync::mpsc::channel;
|
||||||
use std::sync::mpsc::{Sender, Receiver, channel};
|
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use super::gl;
|
use super::gl;
|
||||||
|
@ -18,12 +16,6 @@ use kernel32;
|
||||||
use user32;
|
use user32;
|
||||||
use gdi32;
|
use gdi32;
|
||||||
|
|
||||||
/// Stores the current window and its events dispatcher.
|
|
||||||
///
|
|
||||||
/// We only have one window per thread. We still store the HWND in case where we
|
|
||||||
/// receive an event for another window.
|
|
||||||
thread_local!(static WINDOW: Rc<RefCell<Option<(winapi::HWND, Sender<Event>)>>> = Rc::new(RefCell::new(None)));
|
|
||||||
|
|
||||||
/// Work-around the fact that HGLRC doesn't implement Send
|
/// Work-around the fact that HGLRC doesn't implement Send
|
||||||
pub struct ContextHack(pub winapi::HGLRC);
|
pub struct ContextHack(pub winapi::HGLRC);
|
||||||
unsafe impl Send for ContextHack {}
|
unsafe impl Send for ContextHack {}
|
||||||
|
@ -54,7 +46,7 @@ pub fn new_window(builder: BuilderAttribs<'static>, builder_sharelists: Option<C
|
||||||
let class = winapi::WNDCLASSEXW {
|
let class = winapi::WNDCLASSEXW {
|
||||||
cbSize: mem::size_of::<winapi::WNDCLASSEXW>() as winapi::UINT,
|
cbSize: mem::size_of::<winapi::WNDCLASSEXW>() as winapi::UINT,
|
||||||
style: winapi::CS_HREDRAW | winapi::CS_VREDRAW | winapi::CS_OWNDC,
|
style: winapi::CS_HREDRAW | winapi::CS_VREDRAW | winapi::CS_OWNDC,
|
||||||
lpfnWndProc: callback,
|
lpfnWndProc: callback::callback,
|
||||||
cbClsExtra: 0,
|
cbClsExtra: 0,
|
||||||
cbWndExtra: 0,
|
cbWndExtra: 0,
|
||||||
hInstance: unsafe { kernel32::GetModuleHandleW(ptr::null()) },
|
hInstance: unsafe { kernel32::GetModuleHandleW(ptr::null()) },
|
||||||
|
@ -356,7 +348,7 @@ pub fn new_window(builder: BuilderAttribs<'static>, builder_sharelists: Option<C
|
||||||
let events_receiver = {
|
let events_receiver = {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
let mut tx = Some(tx);
|
let mut tx = Some(tx);
|
||||||
WINDOW.with(|window| {
|
callback::WINDOW.with(|window| {
|
||||||
(*window.borrow_mut()) = Some((real_window, tx.take().unwrap()));
|
(*window.borrow_mut()) = Some((real_window, tx.take().unwrap()));
|
||||||
});
|
});
|
||||||
rx
|
rx
|
||||||
|
@ -423,223 +415,3 @@ pub fn new_window(builder: BuilderAttribs<'static>, builder_sharelists: Option<C
|
||||||
|
|
||||||
rx.recv().unwrap()
|
rx.recv().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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) {
|
|
||||||
WINDOW.with(|window| {
|
|
||||||
let window = window.borrow();
|
|
||||||
let stored = match *window {
|
|
||||||
None => return,
|
|
||||||
Some(ref v) => v
|
|
||||||
};
|
|
||||||
|
|
||||||
let &(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.
|
|
||||||
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;
|
|
||||||
|
|
||||||
WINDOW.with(|w| {
|
|
||||||
let w = w.borrow();
|
|
||||||
let &(ref win, _) = match *w {
|
|
||||||
None => return,
|
|
||||||
Some(ref v) => v
|
|
||||||
};
|
|
||||||
|
|
||||||
if win == &window {
|
|
||||||
unsafe { 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 = unsafe { 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_SETFOCUS => {
|
|
||||||
use events::Event::Focused;
|
|
||||||
send_event(window, Focused(true));
|
|
||||||
0
|
|
||||||
},
|
|
||||||
|
|
||||||
winapi::WM_KILLFOCUS => {
|
|
||||||
use events::Event::Focused;
|
|
||||||
send_event(window, Focused(false));
|
|
||||||
0
|
|
||||||
},
|
|
||||||
|
|
||||||
_ => unsafe {
|
|
||||||
user32::DefWindowProcW(window, msg, wparam, lparam)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*fn hints_to_pixelformat(hints: &Hints) -> winapi::PIXELFORMATDESCRIPTOR {
|
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
winapi::PIXELFORMATDESCRIPTOR {
|
|
||||||
nSize: size_of::<winapi::PIXELFORMATDESCRIPTOR>(),
|
|
||||||
nVersion: 1,
|
|
||||||
dwFlags:
|
|
||||||
if hints.stereo { PFD_STEREO } else { 0 },
|
|
||||||
iPixelType: PFD_TYPE_RGBA,
|
|
||||||
cColorBits: hints.red_bits + hints.green_bits + hints.blue_bits,
|
|
||||||
cRedBits:
|
|
||||||
|
|
||||||
pub nSize: WORD,
|
|
||||||
pub nVersion: WORD,
|
|
||||||
pub dwFlags: DWORD,
|
|
||||||
pub iPixelType: BYTE,
|
|
||||||
pub cColorBits: BYTE,
|
|
||||||
pub cRedBits: BYTE,
|
|
||||||
pub cRedShift: BYTE,
|
|
||||||
pub cGreenBits: BYTE,
|
|
||||||
pub cGreenShift: BYTE,
|
|
||||||
pub cBlueBits: BYTE,
|
|
||||||
pub cBlueShift: BYTE,
|
|
||||||
pub cAlphaBits: BYTE,
|
|
||||||
pub cAlphaShift: BYTE,
|
|
||||||
pub cAccumBits: BYTE,
|
|
||||||
pub cAccumRedBits: BYTE,
|
|
||||||
pub cAccumGreenBits: BYTE,
|
|
||||||
pub cAccumBlueBits: BYTE,
|
|
||||||
pub cAccumAlphaBits: BYTE,
|
|
||||||
pub cDepthBits: BYTE,
|
|
||||||
pub cStencilBits: BYTE,
|
|
||||||
pub cAuxBuffers: BYTE,
|
|
||||||
pub iLayerType: BYTE,
|
|
||||||
pub bReserved: BYTE,
|
|
||||||
pub dwLayerMask: DWORD,
|
|
||||||
pub dwVisibleMask: DWORD,
|
|
||||||
pub dwDamageMask: DWORD,
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ use user32;
|
||||||
use kernel32;
|
use kernel32;
|
||||||
use gdi32;
|
use gdi32;
|
||||||
|
|
||||||
|
mod callback;
|
||||||
mod event;
|
mod event;
|
||||||
mod gl;
|
mod gl;
|
||||||
mod headless;
|
mod headless;
|
||||||
|
|
Loading…
Reference in a new issue