1
0
Fork 0

Merge pull request #27 from MirkoCovizzi/master

Windows: add basic event handling
This commit is contained in:
Mirko Covizzi 2020-06-16 20:14:25 +02:00 committed by GitHub
commit 5ed224f097
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 21 deletions

View file

@ -18,7 +18,7 @@ x11 = { version = "2.3", features = ["xlib", "glx"]}
libc = "0.2" libc = "0.2"
[target.'cfg(target_os="windows")'.dependencies] [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] [target.'cfg(target_os="macos")'.dependencies]
cocoa = "0.20.1" cocoa = "0.20.1"

23
src/win/event.rs Normal file
View 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,
}
}

View file

@ -1,2 +1,5 @@
mod event;
mod window; mod window;
pub use event::*;
pub use window::*; pub use window::*;

View file

@ -15,14 +15,17 @@ use self::winapi::um::wingdi::{
}; };
use self::winapi::um::winuser::{ use self::winapi::um::winuser::{
AdjustWindowRectEx, CreateWindowExA, DefWindowProcA, DestroyWindow, DispatchMessageA, GetDC, AdjustWindowRectEx, CreateWindowExA, DefWindowProcA, DestroyWindow, DispatchMessageA, GetDC,
MessageBoxA, PeekMessageA, PostQuitMessage, RegisterClassA, ReleaseDC, TranslateMessage, GetWindowLongPtrA, MessageBoxA, PeekMessageA, PostMessageA, RegisterClassA, ReleaseDC,
UnregisterClassA, CS_OWNDC, MB_ICONERROR, MB_OK, MB_TOPMOST, MSG, SetWindowLongPtrA, TranslateMessage, UnregisterClassA, CS_OWNDC, GWLP_USERDATA, MB_ICONERROR,
PM_REMOVE, WM_CLOSE, WM_QUIT, WNDCLASSA, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, MB_OK, MB_TOPMOST, MSG, PM_REMOVE, WM_CREATE, WM_QUIT, WM_SHOWWINDOW, WNDCLASSA, WS_CAPTION,
WS_MINIMIZEBOX, WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE, 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::Parent::WithParent;
use crate::WindowOpenOptions; use crate::{handle_message, WindowOpenOptions};
use std::sync::{Arc, Mutex};
unsafe fn message_box(title: &str, msg: &str) { unsafe fn message_box(title: &str, msg: &str) {
let title = (title.to_owned() + "\0").as_ptr() as *const i8; let title = (title.to_owned() + "\0").as_ptr() as *const i8;
@ -68,16 +71,28 @@ fn handle_msg(_window: HWND) -> bool {
unsafe extern "system" fn wnd_proc( unsafe extern "system" fn wnd_proc(
hwnd: HWND, hwnd: HWND,
msg: UINT, msg: UINT,
w_param: WPARAM, wparam: WPARAM,
l_param: LPARAM, lparam: LPARAM,
) -> LRESULT { ) -> LRESULT {
let win = GetWindowLongPtrA(hwnd, GWLP_USERDATA) as *const c_void;
match msg { match msg {
WM_CLOSE => { WM_CREATE => {
PostQuitMessage(0); PostMessageA(hwnd, WM_SHOWWINDOW, 0, 0);
}
_ => return DefWindowProcA(hwnd, msg, w_param, l_param),
}
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 { unsafe fn register_wnd_class() -> ATOM {
@ -114,7 +129,7 @@ pub struct Window {
} }
impl Window { impl Window {
pub fn open(options: WindowOpenOptions) -> Self { pub fn open(options: WindowOpenOptions) -> Arc<Mutex<Self>> {
unsafe { unsafe {
let mut window = Window { let mut window = Window {
hwnd: null_mut(), hwnd: null_mut(),
@ -188,26 +203,26 @@ impl Window {
if pf_id == 0 { if pf_id == 0 {
// todo: use a more useful return like an Option // todo: use a more useful return like an Option
// todo: also launch error message boxes // todo: also launch error message boxes
return window; return Arc::new(Mutex::new(window));
} }
if SetPixelFormat(window.hdc, pf_id, &pfd) == 0 { if SetPixelFormat(window.hdc, pf_id, &pfd) == 0 {
// todo: use a more useful return like an Option // todo: use a more useful return like an Option
// todo: also launch error message boxes // todo: also launch error message boxes
return window; return Arc::new(Mutex::new(window));
} }
window.gl_context = wglCreateContext(window.hdc); window.gl_context = wglCreateContext(window.hdc);
if window.gl_context == 0 as HGLRC { if window.gl_context == 0 as HGLRC {
// todo: use a more useful return like an Option // todo: use a more useful return like an Option
// todo: also launch error message boxes // todo: also launch error message boxes
return window; return Arc::new(Mutex::new(window));
} }
if wglMakeCurrent(window.hdc, window.gl_context) == 0 { if wglMakeCurrent(window.hdc, window.gl_context) == 0 {
// todo: use a more useful return like an Option // todo: use a more useful return like an Option
// todo: also launch error message boxes // 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); let h = LoadLibraryA("opengl32.dll\0".as_ptr() as *const i8);
@ -217,6 +232,13 @@ impl Window {
GetProcAddress(h, symbol) as *const _ 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 // todo: decide what to do with the message pump
if parent.is_null() { if parent.is_null() {
loop { loop {
@ -227,11 +249,11 @@ impl Window {
// todo: pass callback rendering function instead // todo: pass callback rendering function instead
gl::ClearColor(0.3, 0.8, 0.3, 1.0); gl::ClearColor(0.3, 0.8, 0.3, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT); 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); unregister_wnd_class(self.window_class);
} }
} }
pub(crate) fn handle_mouse_motion(&self, x: i32, y: i32) {
println!("{}, {}", x, y);
}
} }