diff options
Diffstat (limited to 'src/win32/mod.rs')
-rw-r--r-- | src/win32/mod.rs | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/src/win32/mod.rs b/src/win32/mod.rs index 5af2691..4e6a803 100644 --- a/src/win32/mod.rs +++ b/src/win32/mod.rs @@ -26,13 +26,10 @@ mod monitor; /// The Win32 implementation of the main `Window` object. pub struct Window { /// Main handle for the window. - window: winapi::HWND, - - /// This represents a "draw context" for the surface of the window. - hdc: winapi::HDC, + window: WindowWrapper, /// OpenGL context. - context: winapi::HGLRC, + context: ContextWrapper, /// Binded to `opengl32.dll`. /// @@ -50,12 +47,25 @@ pub struct Window { unsafe impl Send for Window {} unsafe impl Sync for Window {} -impl Window { - /// See the docs in the crate root file. - pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> { - let (builder, sharing) = builder.extract_non_static(); - let sharing = sharing.map(|w| init::ContextHack(w.context)); - init::new_window(builder, sharing) +/// A simple wrapper that destroys the context when it is destroyed. +struct ContextWrapper(pub winapi::HGLRC); + +impl Drop for ContextWrapper { + fn drop(&mut self) { + unsafe { + gl::wgl::DeleteContext(self.0 as *const libc::c_void); + } + } +} + +/// A simple wrapper that destroys the window when it is destroyed. +struct WindowWrapper(pub winapi::HWND, pub winapi::HDC); + +impl Drop for WindowWrapper { + fn drop(&mut self) { + unsafe { + user32::DestroyWindow(self.0); + } } } @@ -70,6 +80,13 @@ impl WindowProxy { impl Window { /// See the docs in the crate root file. + pub fn new(builder: BuilderAttribs) -> Result<Window, CreationError> { + let (builder, sharing) = builder.extract_non_static(); + let sharing = sharing.map(|w| init::ContextHack(w.context.0)); + init::new_window(builder, sharing) + } + + /// See the docs in the crate root file. pub fn is_closed(&self) -> bool { use std::sync::atomic::Ordering::Relaxed; self.is_closed.load(Relaxed) @@ -80,7 +97,7 @@ impl Window { /// Calls SetWindowText on the HWND. pub fn set_title(&self, text: &str) { unsafe { - user32::SetWindowTextW(self.window, + user32::SetWindowTextW(self.window.0, text.utf16_units().chain(Some(0).into_iter()) .collect::<Vec<u16>>().as_ptr() as winapi::LPCWSTR); } @@ -88,13 +105,13 @@ impl Window { pub fn show(&self) { unsafe { - user32::ShowWindow(self.window, winapi::SW_SHOW); + user32::ShowWindow(self.window.0, winapi::SW_SHOW); } } pub fn hide(&self) { unsafe { - user32::ShowWindow(self.window, winapi::SW_HIDE); + user32::ShowWindow(self.window.0, winapi::SW_HIDE); } } @@ -105,7 +122,7 @@ impl Window { let mut placement: winapi::WINDOWPLACEMENT = unsafe { mem::zeroed() }; placement.length = mem::size_of::<winapi::WINDOWPLACEMENT>() as winapi::UINT; - if unsafe { user32::GetWindowPlacement(self.window, &mut placement) } == 0 { + if unsafe { user32::GetWindowPlacement(self.window.0, &mut placement) } == 0 { return None } @@ -118,9 +135,9 @@ impl Window { use libc; unsafe { - user32::SetWindowPos(self.window, ptr::null_mut(), x as libc::c_int, y as libc::c_int, + user32::SetWindowPos(self.window.0, ptr::null_mut(), x as libc::c_int, y as libc::c_int, 0, 0, winapi::SWP_NOZORDER | winapi::SWP_NOSIZE); - user32::UpdateWindow(self.window); + user32::UpdateWindow(self.window.0); } } @@ -129,7 +146,7 @@ impl Window { use std::mem; let mut rect: winapi::RECT = unsafe { mem::uninitialized() }; - if unsafe { user32::GetClientRect(self.window, &mut rect) } == 0 { + if unsafe { user32::GetClientRect(self.window.0, &mut rect) } == 0 { return None } @@ -144,7 +161,7 @@ impl Window { use std::mem; let mut rect: winapi::RECT = unsafe { mem::uninitialized() }; - if unsafe { user32::GetWindowRect(self.window, &mut rect) } == 0 { + if unsafe { user32::GetWindowRect(self.window.0, &mut rect) } == 0 { return None } @@ -159,9 +176,9 @@ impl Window { use libc; unsafe { - user32::SetWindowPos(self.window, ptr::null_mut(), 0, 0, x as libc::c_int, + user32::SetWindowPos(self.window.0, ptr::null_mut(), 0, 0, x as libc::c_int, y as libc::c_int, winapi::SWP_NOZORDER | winapi::SWP_NOREPOSITION); - user32::UpdateWindow(self.window); + user32::UpdateWindow(self.window.0); } } @@ -186,7 +203,8 @@ impl Window { /// See the docs in the crate root file. pub unsafe fn make_current(&self) { // TODO: check return value - gl::wgl::MakeCurrent(self.hdc as *const libc::c_void, self.context as *const libc::c_void); + gl::wgl::MakeCurrent(self.window.1 as *const libc::c_void, + self.context.0 as *const libc::c_void); } /// See the docs in the crate root file. @@ -204,7 +222,7 @@ impl Window { /// See the docs in the crate root file. pub fn swap_buffers(&self) { unsafe { - gdi32::SwapBuffers(self.hdc); + gdi32::SwapBuffers(self.window.1); } } @@ -213,7 +231,7 @@ impl Window { } pub fn platform_window(&self) -> *mut libc::c_void { - self.window as *mut libc::c_void + self.window.0 as *mut libc::c_void } /// See the docs in the crate root file. @@ -280,10 +298,10 @@ impl<'a> Iterator for WaitEventsIterator<'a> { #[unsafe_destructor] impl Drop for Window { fn drop(&mut self) { - // we don't call MakeCurrent(0, 0) because we are not sure that the context - // is still the current one - unsafe { user32::PostMessageW(self.window, winapi::WM_DESTROY, 0, 0); } - unsafe { gl::wgl::DeleteContext(self.context as *const libc::c_void); } - unsafe { user32::DestroyWindow(self.window); } + unsafe { + // we don't call MakeCurrent(0, 0) because we are not sure that the context + // is still the current one + user32::PostMessageW(self.window.0, winapi::WM_DESTROY, 0, 0); + } } } |