From a9b0a118534c6b07fac7d773ee05ce3a1f933866 Mon Sep 17 00:00:00 2001 From: Daniel Collin Date: Fri, 27 Nov 2015 21:25:50 +0100 Subject: [PATCH] Window gets created --- Cargo.toml | 3 +- examples/noise.rs | 22 +++--- src/lib.rs | 10 +-- src/windows.rs | 173 ++++++++++++++++++++++++++++------------------ 4 files changed, 129 insertions(+), 79 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9d79e7c..c2e89df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,5 @@ gcc = "0.3.19" [dependencies] libc = "0.1.10" user32-sys = "0.1.2" - +winapi = "0.2.4" +kernel32-sys = "0.1.4" diff --git a/examples/noise.rs b/examples/noise.rs index d1bf858..98029b1 100644 --- a/examples/noise.rs +++ b/examples/noise.rs @@ -1,20 +1,25 @@ extern crate minifb; +use minifb::*; + const WIDTH: usize = 640; const HEIGHT: usize = 360; fn main() { - let mut noise; - let mut carry; - let mut seed = 0xbeefu32; + //let mut noise; + //let mut carry; + //let mut seed = 0xbeefu32; - let mut buffer: [u32; WIDTH * HEIGHT] = [0; WIDTH * HEIGHT]; + //let mut buffer: [u32; WIDTH * HEIGHT] = [0; WIDTH * HEIGHT]; - if !(minifb::open("Noise Test - Press ESC to exit", WIDTH, HEIGHT)) { - return; + let mut mfb = Minifb::new("Noise Test - Press ESC to exit", WIDTH, HEIGHT).unwrap(); + + while mfb.update() { } - while minifb::update(&buffer) { + /* + while mfb.update() { + for i in buffer.iter_mut() { noise = seed; noise >>= 3; @@ -27,6 +32,7 @@ fn main() { *i = (noise << 16) | (noise << 8) | noise; } } + */ - minifb::close(); + //minifb::close(); } diff --git a/src/lib.rs b/src/lib.rs index 72aa947..3aed2ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,11 @@ extern crate libc; -use std::ffi::CString; -use std::mem::transmute; -use libc::{c_char, c_int, c_void}; - #[cfg(target_os = "windows")] pub mod windows; +pub use windows::*; + +/* + #[cfg(target_os = "macos")] #[link(name = "Cocoa", kind = "framework")] extern { @@ -76,3 +76,5 @@ pub fn close() { mfb_close(); } } + +*/ diff --git a/src/windows.rs b/src/windows.rs index 63ab418..fbf6fd7 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -1,79 +1,120 @@ -extern crate user; +extern crate user32; +extern crate kernel32; +extern crate winapi; +use std::ffi::CString; +use std::ptr; +use std::os::windows::ffi::OsStrExt; +use std::ffi::OsStr; +use std::mem; -static winapi::HANDLE HWND_HANDLE = 0; -static bool CLOSE_APP = false; +use self::winapi::windef::HWND; +use self::winapi::winuser::WS_OVERLAPPEDWINDOW; +use self::winapi::winuser::WNDCLASSW; -unsafe extern "system" fn callback(window: winapi::HWND, msg: winapi::UINT, +static mut CLOSE_APP: bool = false; + +unsafe extern "system" fn wnd_proc(window: winapi::HWND, msg: winapi::UINT, wparam: winapi::WPARAM, lparam: winapi::LPARAM) -> winapi::LRESULT { match msg { - winapi::WM_PAINT => { + winapi::winuser::WM_KEYDOWN => { + if (wparam & 0xff) == 27 { + CLOSE_APP = true; + } + } + _ => (), + } + + return user32::DefWindowProcW(window, msg, wparam, lparam); +} + +pub enum MinifbError { + UnableToCreateWindow, +} + +fn to_wstring(str : &str) -> *const u16 { + let v : Vec = OsStr::new(str).encode_wide(). chain(Some(0).into_iter()).collect(); + v.as_ptr() +} + +pub struct Minifb { + window: HWND, +} + +impl Minifb { + fn open_window(name: &str, width: usize, height: usize) -> HWND { + unsafe { + let class_name = to_wstring("minifb_window"); + let s = CString::new(name).unwrap(); + + let class = WNDCLASSW { + style: winapi::CS_HREDRAW | winapi::CS_VREDRAW | winapi::CS_OWNDC, + lpfnWndProc: Some(wnd_proc), + cbClsExtra: 0, + cbWndExtra: 0, + hInstance: kernel32::GetModuleHandleA(ptr::null()), + hIcon: ptr::null_mut(), + hCursor: ptr::null_mut(), + hbrBackground: ptr::null_mut(), + lpszMenuName: ptr::null(), + lpszClassName: class_name, + }; + + user32::RegisterClassW(&class); + + let mut rect = winapi::RECT { + left: 0, right: width as winapi::LONG, + top: 0, bottom: height as winapi::LONG, + }; + + user32::AdjustWindowRect(&mut rect, winapi::WS_POPUP | winapi::WS_SYSMENU | winapi::WS_CAPTION, 0); + + rect.right -= rect.left; + rect.bottom -= rect.top; + + let handle = user32::CreateWindowExA(0, + "minifb_window".as_ptr() as *mut _, s.as_ptr(), + winapi::WS_OVERLAPPEDWINDOW & !winapi::WS_MAXIMIZEBOX & !winapi::WS_THICKFRAME, + winapi::CW_USEDEFAULT, winapi::CW_USEDEFAULT, + rect.right, rect.bottom, + ptr::null_mut(), ptr::null_mut(), ptr::null_mut(), ptr::null_mut()); + + if !handle.is_null() { + user32::ShowWindow(handle, winapi::SW_NORMAL); + } + + return handle; + } + } + + pub fn new(name: &str, width: usize, height: usize) -> Option { + let handle = Minifb::open_window(name, width, height); + + match handle.is_null() { + true => None, + false => Some(Minifb { window : handle }), + } + } + + pub fn update(&mut self) -> bool { + unsafe { + let mut msg = mem::uninitialized(); + + user32::InvalidateRect(self.window, ptr::null_mut(), winapi::TRUE); + + while user32::PeekMessageW(&mut msg, self.window, 0, 0, winapi::winuser::PM_REMOVE) != 0 { + user32::TranslateMessage(&mut msg); + user32::DispatchMessageW(&mut msg); + } + } + + unsafe { + return !CLOSE_APP; } } } -pub fn open(name: &str, width: usize, height: usize) -> bool { - let class_name = CString::new("minifb_window").unwrap(); - let s = CString::new(name).unwrap(); - - unsafe { - let class = winapi::WNDCLASSEXA { - cbSize: mem::size_of::() as winapi::UINT, - style: winapi::CS_HREDRAW | winapi::CS_VREDRAW | winapi::CS_OWNDC, - lpfnWndProc: Some(callback::callback), - cbClsExtra: 0, - cbWndExtra: 0, - hInstance: kernel32::GetModuleHandleA(ptr::null()), - hIcon: ptr::null_mut(), - hCursor: ptr::null_mut(), - hbrBackground: ptr::null_mut(), - lpszMenuName: ptr::null(), - lpszClassName: class_name.as_ptr(), - hIconSm: ptr::null_mut(), - }; - - user32::RegisterClassExA(&class); - - let mut rect = winapi::RECT { - left: 0, right: width as winapi::LONG, - top: 0, bottom: height as winapi::LONG, - } - - user32::AdjustWindowRect(&mut rect, winapi::WS_POPUP | winapi::WS_SYSMENU | winapi::WS_CAPTION, 0); - - rect.right -= rect.left; - rect.bottom -= rect.top; - - let handle = user32::CreateWindowExA(0, - class_name.as_ptr(), s.as_ptr(), - winapi::WS_OVERLAPPEDWINDOW & ~winapi::WS_MAXIMIZEBOX & ~winapi::WS_TICKFRAME, - winapi::CW_USEDEFAULT, winapi::CW_USEDEFAULT, - rect.right, rect.bottom, - ptr::null_mut(), ptr::null_mut(), ptr::null_mut(), ptr::null_mut()); - - if handle.is_null() { - return false; - } - - user32::ShowWindow(handle, winapi::SW_NORMAL); - - HWND_HANDLE = handle; -} - -fn update() -> bool { - - let mut msg = mem::uninitialized(); - - user32::InvalidateRect(HWND_HANDLE, ptr::null_mut(), winapi::TRUE); - - while user32::PeekMessage(&mut msg, HWND_HANDLE, 0, 0, winapi::PM_REMOTE) { - user32::TranslateMessage(&mut msg); - user32::DispatchMessage(&mut msg); - } - - CLOSE_APP, -}