Windows: add basic event handling
This commit is contained in:
parent
f35f97c73e
commit
c499697a9a
|
@ -17,7 +17,7 @@ xcb = { version = "0.9", features = ["thread", "xlib_xcb", "dri2"] }
|
|||
x11 = { version = "2.3", features = ["xlib", "glx"]}
|
||||
|
||||
[target.'cfg(target_os="windows")'.dependencies]
|
||||
winapi = { version = "0.3.8", features = ["libloaderapi", "winuser", "windef", "minwindef", "guiddef", "combaseapi", "wingdi"] }
|
||||
winapi = { version = "0.3.8", features = ["libloaderapi", "winuser", "windef", "minwindef", "guiddef", "combaseapi", "wingdi", "errhandlingapi"] }
|
||||
|
||||
[target.'cfg(target_os="macos")'.dependencies]
|
||||
cocoa = "0.20.1"
|
||||
|
|
23
src/win/event.rs
Normal file
23
src/win/event.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use winapi::shared::minwindef::{LPARAM, LRESULT, UINT, WPARAM};
|
||||
|
||||
use crate::Window;
|
||||
use winapi::um::winuser::WM_MOUSEMOVE;
|
||||
|
||||
pub(crate) unsafe fn handle_message(
|
||||
win: Arc<Mutex<Window>>,
|
||||
msg: UINT,
|
||||
wparam: WPARAM,
|
||||
lparam: LPARAM,
|
||||
) -> LRESULT {
|
||||
match msg {
|
||||
WM_MOUSEMOVE => {
|
||||
let x = (lparam & 0xFFFF) as i32;
|
||||
let y = ((lparam >> 16) & 0xFFFF) as i32;
|
||||
win.lock().unwrap().handle_mouse_motion(x, y);
|
||||
0
|
||||
}
|
||||
_ => 0,
|
||||
}
|
||||
}
|
|
@ -1,2 +1,5 @@
|
|||
mod event;
|
||||
mod window;
|
||||
|
||||
pub use event::*;
|
||||
pub use window::*;
|
||||
|
|
|
@ -15,14 +15,17 @@ use self::winapi::um::wingdi::{
|
|||
};
|
||||
use self::winapi::um::winuser::{
|
||||
AdjustWindowRectEx, CreateWindowExA, DefWindowProcA, DestroyWindow, DispatchMessageA, GetDC,
|
||||
MessageBoxA, PeekMessageA, PostQuitMessage, RegisterClassA, ReleaseDC, TranslateMessage,
|
||||
UnregisterClassA, CS_OWNDC, MB_ICONERROR, MB_OK, MB_TOPMOST, MSG,
|
||||
PM_REMOVE, WM_CLOSE, WM_QUIT, WNDCLASSA, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX,
|
||||
WS_MINIMIZEBOX, WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
|
||||
GetWindowLongPtrA, MessageBoxA, PeekMessageA, PostMessageA, RegisterClassA, ReleaseDC,
|
||||
SetWindowLongPtrA, TranslateMessage, UnregisterClassA, CS_OWNDC, GWLP_USERDATA, MB_ICONERROR,
|
||||
MB_OK, MB_TOPMOST, MSG, PM_REMOVE, WM_CREATE, WM_QUIT, WM_SHOWWINDOW, WNDCLASSA, WS_CAPTION,
|
||||
WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUPWINDOW, WS_SIZEBOX,
|
||||
WS_VISIBLE,
|
||||
};
|
||||
|
||||
use self::winapi::ctypes::c_void;
|
||||
use crate::Parent::WithParent;
|
||||
use crate::WindowOpenOptions;
|
||||
use crate::{handle_message, WindowOpenOptions};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
unsafe fn message_box(title: &str, msg: &str) {
|
||||
let title = (title.to_owned() + "\0").as_ptr() as *const i8;
|
||||
|
@ -68,17 +71,29 @@ fn handle_msg(_window: HWND) -> bool {
|
|||
unsafe extern "system" fn wnd_proc(
|
||||
hwnd: HWND,
|
||||
msg: UINT,
|
||||
w_param: WPARAM,
|
||||
l_param: LPARAM,
|
||||
wparam: WPARAM,
|
||||
lparam: LPARAM,
|
||||
) -> LRESULT {
|
||||
let win = GetWindowLongPtrA(hwnd, GWLP_USERDATA) as *const c_void;
|
||||
match msg {
|
||||
WM_CLOSE => {
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
_ => return DefWindowProcA(hwnd, msg, w_param, l_param),
|
||||
}
|
||||
WM_CREATE => {
|
||||
PostMessageA(hwnd, WM_SHOWWINDOW, 0, 0);
|
||||
0
|
||||
}
|
||||
_ => {
|
||||
if !win.is_null() {
|
||||
let win: &Arc<Mutex<Window>> = std::mem::transmute(win);
|
||||
let win = Arc::clone(win);
|
||||
let ret = handle_message(win, msg, wparam, lparam);
|
||||
|
||||
// todo: need_reconfigure thing?
|
||||
|
||||
// return ret
|
||||
}
|
||||
return DefWindowProcA(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn register_wnd_class() -> ATOM {
|
||||
// We generate a unique name for the new window class to prevent name collisions
|
||||
|
@ -114,7 +129,7 @@ pub struct Window {
|
|||
}
|
||||
|
||||
impl Window {
|
||||
pub fn open(options: WindowOpenOptions) -> Self {
|
||||
pub fn open(options: WindowOpenOptions) -> Arc<Mutex<Self>> {
|
||||
unsafe {
|
||||
let mut window = Window {
|
||||
hwnd: null_mut(),
|
||||
|
@ -188,26 +203,26 @@ impl Window {
|
|||
if pf_id == 0 {
|
||||
// todo: use a more useful return like an Option
|
||||
// todo: also launch error message boxes
|
||||
return window;
|
||||
return Arc::new(Mutex::new(window));
|
||||
}
|
||||
|
||||
if SetPixelFormat(window.hdc, pf_id, &pfd) == 0 {
|
||||
// todo: use a more useful return like an Option
|
||||
// todo: also launch error message boxes
|
||||
return window;
|
||||
return Arc::new(Mutex::new(window));
|
||||
}
|
||||
|
||||
window.gl_context = wglCreateContext(window.hdc);
|
||||
if window.gl_context == 0 as HGLRC {
|
||||
// todo: use a more useful return like an Option
|
||||
// todo: also launch error message boxes
|
||||
return window;
|
||||
return Arc::new(Mutex::new(window));
|
||||
}
|
||||
|
||||
if wglMakeCurrent(window.hdc, window.gl_context) == 0 {
|
||||
// todo: use a more useful return like an Option
|
||||
// todo: also launch error message boxes
|
||||
return window;
|
||||
return Arc::new(Mutex::new(window));
|
||||
}
|
||||
|
||||
let h = LoadLibraryA("opengl32.dll\0".as_ptr() as *const i8);
|
||||
|
@ -217,6 +232,13 @@ impl Window {
|
|||
GetProcAddress(h, symbol) as *const _
|
||||
});
|
||||
|
||||
let hwnd = window.hwnd;
|
||||
let hdc = window.hdc;
|
||||
|
||||
let win = Arc::new(Mutex::new(window));
|
||||
|
||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, &Arc::clone(&win) as *const _ as _);
|
||||
|
||||
// todo: decide what to do with the message pump
|
||||
if parent.is_null() {
|
||||
loop {
|
||||
|
@ -227,11 +249,11 @@ impl Window {
|
|||
// todo: pass callback rendering function instead
|
||||
gl::ClearColor(0.3, 0.8, 0.3, 1.0);
|
||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
||||
SwapBuffers(window.hdc);
|
||||
SwapBuffers(hdc);
|
||||
}
|
||||
}
|
||||
|
||||
window
|
||||
win
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,4 +267,8 @@ impl Window {
|
|||
unregister_wnd_class(self.window_class);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn handle_mouse_motion(&self, x: i32, y: i32) {
|
||||
println!("{}, {}", x, y);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue