Merge pull request #34 from glowcoil/master
get windows building again and remove windows gl context creation code
This commit is contained in:
commit
d968c6182c
|
@ -2,22 +2,20 @@ use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use winapi::shared::minwindef::{LPARAM, LRESULT, UINT, WPARAM};
|
use winapi::shared::minwindef::{LPARAM, LRESULT, UINT, WPARAM};
|
||||||
|
|
||||||
use crate::Window;
|
use crate::{AppWindow, Window};
|
||||||
use winapi::um::winuser::{DefWindowProcA, WM_MOUSEMOVE, WM_PAINT, WM_TIMER};
|
use winapi::um::winuser::{DefWindowProcA, WM_MOUSEMOVE, WM_PAINT, WM_TIMER};
|
||||||
|
|
||||||
const WIN_FRAME_TIMER: usize = 4242;
|
const WIN_FRAME_TIMER: usize = 4242;
|
||||||
|
|
||||||
unsafe fn handle_timer(win: Arc<Mutex<Window>>, timer_id: usize) {
|
unsafe fn handle_timer<A: AppWindow>(win: &Arc<Mutex<Window<A>>>, timer_id: usize) {
|
||||||
match timer_id {
|
match timer_id {
|
||||||
WIN_FRAME_TIMER => {
|
WIN_FRAME_TIMER => {}
|
||||||
win.lock().unwrap().draw_frame();
|
|
||||||
}
|
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn handle_message(
|
pub(crate) unsafe fn handle_message<A: AppWindow>(
|
||||||
win: Arc<Mutex<Window>>,
|
win: &Arc<Mutex<Window<A>>>,
|
||||||
message: UINT,
|
message: UINT,
|
||||||
wparam: WPARAM,
|
wparam: WPARAM,
|
||||||
lparam: LPARAM,
|
lparam: LPARAM,
|
||||||
|
@ -37,10 +35,7 @@ pub(crate) unsafe fn handle_message(
|
||||||
handle_timer(win, wparam);
|
handle_timer(win, wparam);
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
WM_PAINT => {
|
WM_PAINT => 0,
|
||||||
win.lock().unwrap().draw_frame();
|
|
||||||
0
|
|
||||||
}
|
|
||||||
_ => DefWindowProcA(hwnd, message, wparam, lparam),
|
_ => DefWindowProcA(hwnd, message, wparam, lparam),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
mod event;
|
mod event;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
pub use event::*;
|
|
||||||
pub use window::*;
|
pub use window::*;
|
||||||
|
|
|
@ -1,38 +1,29 @@
|
||||||
extern crate winapi;
|
extern crate winapi;
|
||||||
|
|
||||||
use std::ffi::CString;
|
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
use self::winapi::shared::guiddef::GUID;
|
use self::winapi::shared::guiddef::GUID;
|
||||||
use self::winapi::shared::minwindef::{ATOM, FALSE, LPARAM, LRESULT, UINT, WPARAM};
|
use self::winapi::shared::minwindef::{ATOM, FALSE, LPARAM, LRESULT, UINT, WPARAM};
|
||||||
use self::winapi::shared::windef::{HDC, HGLRC, HWND, RECT};
|
use self::winapi::shared::windef::{HWND, RECT};
|
||||||
use self::winapi::um::combaseapi::CoCreateGuid;
|
use self::winapi::um::combaseapi::CoCreateGuid;
|
||||||
use self::winapi::um::libloaderapi::{GetProcAddress, LoadLibraryA};
|
|
||||||
use self::winapi::um::wingdi::{
|
|
||||||
wglCreateContext, wglDeleteContext, wglMakeCurrent, ChoosePixelFormat, SetPixelFormat,
|
|
||||||
SwapBuffers, PFD_DOUBLEBUFFER, PFD_DRAW_TO_WINDOW, PFD_MAIN_PLANE, PFD_SUPPORT_OPENGL,
|
|
||||||
PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR,
|
|
||||||
};
|
|
||||||
use self::winapi::um::winuser::{
|
use self::winapi::um::winuser::{
|
||||||
AdjustWindowRectEx, CreateWindowExA, DefWindowProcA, DestroyWindow, DispatchEventA, EventBoxA,
|
AdjustWindowRectEx, CreateWindowExA, DefWindowProcA, DestroyWindow, GetMessageA,
|
||||||
GetDC, GetEventA, GetWindowLongPtrA, PeekEventA, PostEventA, RegisterClassA, ReleaseDC,
|
GetWindowLongPtrA, MessageBoxA, PostMessageA, RegisterClassA, SetTimer, SetWindowLongPtrA,
|
||||||
SetTimer, SetWindowLongPtrA, TranslateEvent, UnregisterClassA, CS_OWNDC, GWLP_USERDATA,
|
TranslateMessage, UnregisterClassA, CS_OWNDC, GWLP_USERDATA, MB_ICONERROR, MB_OK, MB_TOPMOST,
|
||||||
MB_ICONERROR, MB_OK, MB_TOPMOST, MSG, PM_REMOVE, WM_CREATE, WM_QUIT, WM_SHOWWINDOW, WM_TIMER,
|
MSG, WM_CREATE, WM_SHOWWINDOW, WNDCLASSA, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS,
|
||||||
WNDCLASSA, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX,
|
WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
|
||||||
WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::winapi::ctypes::c_void;
|
use self::winapi::ctypes::c_void;
|
||||||
use crate::Parent::WithParent;
|
use super::event::handle_message;
|
||||||
use crate::{handle_message, WindowOpenOptions};
|
use crate::{AppWindow, Event, Parent::WithParent, RawWindow, WindowInfo, WindowOpenOptions};
|
||||||
use crate::{AppWindow, Event, MouseButtonID, MouseScroll};
|
|
||||||
use std::sync::{Arc, Mutex};
|
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;
|
||||||
let msg = (msg.to_owned() + "\0").as_ptr() as *const i8;
|
let msg = (msg.to_owned() + "\0").as_ptr() as *const i8;
|
||||||
EventBoxA(null_mut(), msg, title, MB_ICONERROR | MB_OK | MB_TOPMOST);
|
MessageBoxA(null_mut(), msg, title, MB_ICONERROR | MB_OK | MB_TOPMOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn generate_guid() -> String {
|
unsafe fn generate_guid() -> String {
|
||||||
|
@ -54,7 +45,7 @@ unsafe fn generate_guid() -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "system" fn wnd_proc(
|
unsafe extern "system" fn wnd_proc<A: AppWindow>(
|
||||||
hwnd: HWND,
|
hwnd: HWND,
|
||||||
msg: UINT,
|
msg: UINT,
|
||||||
wparam: WPARAM,
|
wparam: WPARAM,
|
||||||
|
@ -63,21 +54,20 @@ unsafe extern "system" fn wnd_proc(
|
||||||
let win_ptr = GetWindowLongPtrA(hwnd, GWLP_USERDATA) as *const c_void;
|
let win_ptr = GetWindowLongPtrA(hwnd, GWLP_USERDATA) as *const c_void;
|
||||||
match msg {
|
match msg {
|
||||||
WM_CREATE => {
|
WM_CREATE => {
|
||||||
PostEventA(hwnd, WM_SHOWWINDOW, 0, 0);
|
PostMessageA(hwnd, WM_SHOWWINDOW, 0, 0);
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if !win_ptr.is_null() {
|
if !win_ptr.is_null() {
|
||||||
let win_ref: Arc<Mutex<Window>> = Arc::from_raw(win_ptr as *mut Mutex<Window>);
|
let win: Arc<Mutex<Window<A>>> =
|
||||||
let win = Arc::clone(&win_ref);
|
Arc::from_raw(win_ptr as *mut Mutex<Window<A>>);
|
||||||
let ret = handle_message(win, msg, wparam, lparam);
|
|
||||||
|
let ret = handle_message(&win, msg, wparam, lparam);
|
||||||
|
|
||||||
// todo: need_reconfigure thing?
|
// todo: need_reconfigure thing?
|
||||||
|
|
||||||
// Needed otherwise it crashes because it drops the userdata
|
// If we don't do this, the Arc will be dropped and we'll get a crash.
|
||||||
// We basically need to keep the GWLP_USERDATA fresh between calls of the proc
|
let _ = Arc::into_raw(win);
|
||||||
// DO NOT REMOVE
|
|
||||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, Arc::into_raw(win_ref) as *const _ as _);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -87,13 +77,13 @@ unsafe extern "system" fn wnd_proc(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn register_wnd_class() -> ATOM {
|
unsafe fn register_wnd_class<A: AppWindow>() -> ATOM {
|
||||||
// We generate a unique name for the new window class to prevent name collisions
|
// We generate a unique name for the new window class to prevent name collisions
|
||||||
let class_name = format!("Baseview-{}", generate_guid()).as_ptr() as *const i8;
|
let class_name = format!("Baseview-{}", generate_guid()).as_ptr() as *const i8;
|
||||||
|
|
||||||
let wnd_class = WNDCLASSA {
|
let wnd_class = WNDCLASSA {
|
||||||
style: CS_OWNDC,
|
style: CS_OWNDC,
|
||||||
lpfnWndProc: Some(wnd_proc),
|
lpfnWndProc: Some(wnd_proc::<A>),
|
||||||
hInstance: null_mut(),
|
hInstance: null_mut(),
|
||||||
lpszClassName: class_name,
|
lpszClassName: class_name,
|
||||||
cbClsExtra: 0,
|
cbClsExtra: 0,
|
||||||
|
@ -111,44 +101,20 @@ unsafe fn unregister_wnd_class(wnd_class: ATOM) {
|
||||||
UnregisterClassA(wnd_class as _, null_mut());
|
UnregisterClassA(wnd_class as _, null_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_gl_context() {}
|
|
||||||
|
|
||||||
pub struct Window<A: AppWindow> {
|
pub struct Window<A: AppWindow> {
|
||||||
pub(crate) hwnd: HWND,
|
pub(crate) hwnd: HWND,
|
||||||
hdc: HDC,
|
|
||||||
gl_context: HGLRC,
|
|
||||||
window_class: ATOM,
|
window_class: ATOM,
|
||||||
app_window: A,
|
app_window: A,
|
||||||
app_message_rx: mpsc::Receiver<A::AppMessage>,
|
app_message_rx: mpsc::Receiver<A::AppMessage>,
|
||||||
scaling: Option<f64>, // DPI scale, 96.0 is "default".
|
scaling: Option<f64>, // DPI scale, 96.0 is "default".
|
||||||
r: f32,
|
|
||||||
g: f32,
|
|
||||||
b: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: AppWindow> Window<A> {
|
impl<A: AppWindow> Window<A> {
|
||||||
pub fn open(
|
pub fn open(options: WindowOpenOptions, app_message_rx: mpsc::Receiver<A::AppMessage>) {
|
||||||
options: WindowOpenOptions,
|
|
||||||
app_window: A,
|
|
||||||
app_message_rx: mpsc::Receiver<A::AppMessage>,
|
|
||||||
) {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut window = Window {
|
|
||||||
hwnd: null_mut(),
|
|
||||||
hdc: null_mut(),
|
|
||||||
gl_context: null_mut(),
|
|
||||||
window_class: 0,
|
|
||||||
app_window,
|
|
||||||
app_message_rx,
|
|
||||||
scaling: None,
|
|
||||||
r: 0.3,
|
|
||||||
g: 0.8,
|
|
||||||
b: 0.3,
|
|
||||||
};
|
|
||||||
|
|
||||||
let title = (options.title.to_owned() + "\0").as_ptr() as *const i8;
|
let title = (options.title.to_owned() + "\0").as_ptr() as *const i8;
|
||||||
|
|
||||||
window.window_class = register_wnd_class();
|
let window_class = register_wnd_class::<A>();
|
||||||
// todo: manage error ^
|
// todo: manage error ^
|
||||||
|
|
||||||
let mut flags = WS_POPUPWINDOW
|
let mut flags = WS_POPUPWINDOW
|
||||||
|
@ -176,9 +142,9 @@ impl<A: AppWindow> Window<A> {
|
||||||
AdjustWindowRectEx(&mut rect, flags, FALSE, 0);
|
AdjustWindowRectEx(&mut rect, flags, FALSE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.hwnd = CreateWindowExA(
|
let hwnd = CreateWindowExA(
|
||||||
0,
|
0,
|
||||||
window.window_class as _,
|
window_class as _,
|
||||||
title,
|
title,
|
||||||
flags,
|
flags,
|
||||||
0,
|
0,
|
||||||
|
@ -192,54 +158,28 @@ impl<A: AppWindow> Window<A> {
|
||||||
);
|
);
|
||||||
// todo: manage error ^
|
// todo: manage error ^
|
||||||
|
|
||||||
window.hdc = GetDC(window.hwnd);
|
let mut windows_handle = raw_window_handle::windows::WindowsHandle::empty();
|
||||||
|
windows_handle.hwnd = hwnd as *mut std::ffi::c_void;
|
||||||
|
|
||||||
let mut pfd: PIXELFORMATDESCRIPTOR = std::mem::zeroed();
|
let raw_window = RawWindow {
|
||||||
pfd.nSize = std::mem::size_of::<PIXELFORMATDESCRIPTOR>() as u16;
|
raw_window_handle: raw_window_handle::RawWindowHandle::Windows(windows_handle),
|
||||||
pfd.nVersion = 1;
|
};
|
||||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
|
||||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
||||||
pfd.cColorBits = 32;
|
|
||||||
// todo: ask wrl why 24 instead of 32?
|
|
||||||
pfd.cDepthBits = 24;
|
|
||||||
pfd.cStencilBits = 8;
|
|
||||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
||||||
|
|
||||||
let pf_id: i32 = ChoosePixelFormat(window.hdc, &pfd);
|
let window_info = WindowInfo {
|
||||||
if pf_id == 0 {
|
width: options.width as u32,
|
||||||
// todo: use a more useful return like an Option
|
height: options.height as u32,
|
||||||
// todo: also launch error message boxes
|
scale: 1.0,
|
||||||
//return Arc::new(Mutex::new(window));
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if SetPixelFormat(window.hdc, pf_id, &pfd) == 0 {
|
let app_window = A::build(raw_window, &window_info);
|
||||||
// todo: use a more useful return like an Option
|
|
||||||
// todo: also launch error message boxes
|
|
||||||
//return Arc::new(Mutex::new(window));
|
|
||||||
}
|
|
||||||
|
|
||||||
window.gl_context = wglCreateContext(window.hdc);
|
let window = Window {
|
||||||
if window.gl_context == 0 as HGLRC {
|
hwnd,
|
||||||
// todo: use a more useful return like an Option
|
window_class,
|
||||||
// todo: also launch error message boxes
|
app_window,
|
||||||
//return Arc::new(Mutex::new(window));
|
app_message_rx,
|
||||||
}
|
scaling: None,
|
||||||
|
};
|
||||||
if wglMakeCurrent(window.hdc, window.gl_context) == 0 {
|
|
||||||
// todo: use a more useful return like an Option
|
|
||||||
// todo: also launch error message boxes
|
|
||||||
//return Arc::new(Mutex::new(window));
|
|
||||||
}
|
|
||||||
|
|
||||||
let h = LoadLibraryA("opengl32.dll\0".as_ptr() as *const i8);
|
|
||||||
gl::load_with(|symbol| {
|
|
||||||
let symbol = CString::new(symbol.as_bytes()).unwrap();
|
|
||||||
let symbol = symbol.as_ptr();
|
|
||||||
GetProcAddress(h, symbol) as *const _
|
|
||||||
});
|
|
||||||
|
|
||||||
let hwnd = window.hwnd;
|
|
||||||
let hdc = window.hdc;
|
|
||||||
|
|
||||||
let win = Arc::new(Mutex::new(window));
|
let win = Arc::new(Mutex::new(window));
|
||||||
let win_p = Arc::clone(&win);
|
let win_p = Arc::clone(&win);
|
||||||
|
@ -252,43 +192,28 @@ impl<A: AppWindow> Window<A> {
|
||||||
if parent.is_null() {
|
if parent.is_null() {
|
||||||
let mut msg: MSG = std::mem::zeroed();
|
let mut msg: MSG = std::mem::zeroed();
|
||||||
loop {
|
loop {
|
||||||
let status = GetEventA(&mut msg, hwnd, 0, 0);
|
let status = GetMessageA(&mut msg, hwnd, 0, 0);
|
||||||
if status == -1 {
|
if status == -1 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TranslateEvent(&mut msg);
|
TranslateMessage(&mut msg);
|
||||||
handle_message(Arc::clone(&win_p), msg.message, msg.wParam, msg.lParam);
|
handle_message(&win_p, msg.message, msg.wParam, msg.lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(&self) {
|
pub fn close(&mut self) {
|
||||||
self.app_window.on_event(Event::WillClose);
|
self.app_window.on_event(Event::WillClose);
|
||||||
|
|
||||||
// todo: see https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L402
|
// todo: see https://github.com/wrl/rutabaga/blob/f30ff67e157375cafdbafe5fb549f1790443a3a8/src/platform/win/window.c#L402
|
||||||
unsafe {
|
unsafe {
|
||||||
wglMakeCurrent(null_mut(), null_mut());
|
|
||||||
wglDeleteContext(self.gl_context);
|
|
||||||
ReleaseDC(self.hwnd, self.hdc);
|
|
||||||
DestroyWindow(self.hwnd);
|
DestroyWindow(self.hwnd);
|
||||||
unregister_wnd_class(self.window_class);
|
unregister_wnd_class(self.window_class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn draw_frame(&mut self) {
|
|
||||||
// todo: pass callback rendering function instead?
|
|
||||||
gl::ClearColor(self.r, self.g, self.b, 1.0);
|
|
||||||
gl::Clear(gl::COLOR_BUFFER_BIT);
|
|
||||||
SwapBuffers(self.hdc);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn handle_mouse_motion(&mut self, x: i32, y: i32) {
|
pub(crate) fn handle_mouse_motion(&mut self, x: i32, y: i32) {
|
||||||
let r = (x as f32) / 1000.0;
|
self.app_window.on_event(Event::CursorMotion(x, y));
|
||||||
let g = (y as f32) / 1000.0;
|
|
||||||
self.r = r;
|
|
||||||
self.g = g;
|
|
||||||
|
|
||||||
self.app_window.on_message(Event::CursorMotion(x, y));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue