From 1b33c3c33e5c8ec1b7fe36b197ee089563c9e109 Mon Sep 17 00:00:00 2001 From: Micah Johnston Date: Mon, 25 May 2020 21:10:32 -0500 Subject: [PATCH] unify api and file structure across platforms; make example platform-independent --- examples/open_window.rs | 17 +--- src/lib.rs | 11 ++- src/macos/mod.rs | 2 + src/{macos.rs => macos/window.rs} | 4 +- src/win/mod.rs | 1 - src/win/window.rs | 130 +++++++++++++++++------------- src/x11/mod.rs | 2 + src/{x11.rs => x11/window.rs} | 10 +-- 8 files changed, 88 insertions(+), 89 deletions(-) create mode 100644 src/macos/mod.rs rename src/{macos.rs => macos/window.rs} (95%) create mode 100644 src/x11/mod.rs rename src/{x11.rs => x11/window.rs} (96%) diff --git a/examples/open_window.rs b/examples/open_window.rs index e85d516..924a382 100644 --- a/examples/open_window.rs +++ b/examples/open_window.rs @@ -1,5 +1,3 @@ -use std::ptr::null_mut; - fn main() { let window_open_options = baseview::WindowOpenOptions { title: "baseview", @@ -8,18 +6,5 @@ fn main() { parent: baseview::Parent::None, }; - #[cfg(target_os = "macos")] { - baseview::Window::open(window_open_options); - } - #[cfg(target_os = "windows")] { - baseview::create_window(window_open_options); - loop { - if !baseview::handle_msg(null_mut()) { - break; - } - } - } - #[cfg(target_os = "linux")] { - baseview::run(window_open_options); - } + baseview::Window::open(window_open_options); } diff --git a/src/lib.rs b/src/lib.rs index 16820da..079dff6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,12 +4,16 @@ use std::ffi::c_void; mod win; #[cfg(target_os = "windows")] pub use win::*; + #[cfg(target_os = "linux")] mod x11; +#[cfg(target_os = "linux")] +pub use x11::*; + #[cfg(target_os = "macos")] mod macos; #[cfg(target_os = "macos")] -pub use macos::Window; +pub use macos::*; pub enum Parent { None, @@ -25,8 +29,3 @@ pub struct WindowOpenOptions<'a> { pub parent: Parent, } - -#[cfg(target_os = "linux")] -pub fn run(options: WindowOpenOptions) { - x11::run(options); -} diff --git a/src/macos/mod.rs b/src/macos/mod.rs new file mode 100644 index 0000000..01e0b8e --- /dev/null +++ b/src/macos/mod.rs @@ -0,0 +1,2 @@ +mod window; +pub use window::*; diff --git a/src/macos.rs b/src/macos/window.rs similarity index 95% rename from src/macos.rs rename to src/macos/window.rs index 64ca90d..89de4e5 100644 --- a/src/macos.rs +++ b/src/macos/window.rs @@ -11,7 +11,7 @@ use crate::WindowOpenOptions; pub struct Window; impl Window { - pub fn open(options: WindowOpenOptions) { + pub fn open(options: WindowOpenOptions) -> Self { unsafe { let _pool = NSAutoreleasePool::new(nil); @@ -41,6 +41,8 @@ impl Window { let current_app = NSRunningApplication::currentApplication(nil); current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps); app.run(); + + Window } } } diff --git a/src/win/mod.rs b/src/win/mod.rs index b0fcdd9..1c54e26 100644 --- a/src/win/mod.rs +++ b/src/win/mod.rs @@ -1,3 +1,2 @@ mod window; - pub use window::*; diff --git a/src/win/window.rs b/src/win/window.rs index 4684907..16d95ab 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -1,5 +1,7 @@ extern crate winapi; +use std::ptr::null_mut; + use self::winapi::_core::mem::MaybeUninit; use self::winapi::shared::guiddef::GUID; use self::winapi::shared::minwindef::{LPARAM, LPVOID, LRESULT, UINT, WPARAM}; @@ -14,7 +16,75 @@ use self::winapi::um::winuser::{ use crate::WindowOpenOptions; -pub fn handle_msg(_window: HWND) -> bool { +pub struct Window; + +impl Window { + pub fn open(options: WindowOpenOptions) -> Self { + unsafe { + // We generate a unique name for the new window class to prevent name collisions + let mut guid: GUID = MaybeUninit::uninit().assume_init(); + CoCreateGuid(&mut guid); + let class_name = format!( + "Baseview-{}-{}-{}-{}{}{}{}{}{}{}{}\0", + guid.Data1, + guid.Data2, + guid.Data3, + guid.Data4[0], + guid.Data4[1], + guid.Data4[2], + guid.Data4[3], + guid.Data4[4], + guid.Data4[5], + guid.Data4[6], + guid.Data4[7] + ); + + let hinstance = GetModuleHandleA(0 as *const i8); + let wnd_class = WNDCLASSA { + // todo: for OpenGL, will use it later + style: CS_OWNDC | CS_HREDRAW | CS_VREDRAW, + lpfnWndProc: Some(wnd_proc), + hInstance: hinstance, + lpszClassName: class_name.as_ptr() as *const i8, + cbClsExtra: 0, + cbWndExtra: 0, + hIcon: 0 as HICON, + hCursor: 0 as HICON, + hbrBackground: 0 as HBRUSH, + lpszMenuName: 0 as *const i8, + }; + RegisterClassA(&wnd_class); + + let _hwnd = CreateWindowExA( + 0, + class_name.as_ptr() as *const i8, + // todo: change title based on options struct + "Baseview\0".as_ptr() as *const i8, + // todo: fine for now, will have to change with a parent + WS_OVERLAPPEDWINDOW | WS_VISIBLE, + CW_USEDEFAULT, + CW_USEDEFAULT, + // todo: check if usize fits into i32 + options.width as i32, + options.height as i32, + 0 as HWND, + 0 as HMENU, + hinstance, + 0 as LPVOID, + ); + + loop { + if !handle_msg(null_mut()) { + break; + } + } + } + + Window + } +} + +fn handle_msg(_window: HWND) -> bool { unsafe { let mut msg: MSG = MaybeUninit::uninit().assume_init(); loop { @@ -30,7 +100,7 @@ pub fn handle_msg(_window: HWND) -> bool { } } -pub unsafe extern "system" fn wnd_proc( +unsafe extern "system" fn wnd_proc( hwnd: HWND, msg: UINT, w_param: WPARAM, @@ -46,59 +116,3 @@ pub unsafe extern "system" fn wnd_proc( } return 0; } - -pub fn create_window(w: WindowOpenOptions) { - unsafe { - // We generate a unique name for the new window class to prevent name collisions - let mut guid: GUID = MaybeUninit::uninit().assume_init(); - CoCreateGuid(&mut guid); - let class_name = format!( - "Baseview-{}-{}-{}-{}{}{}{}{}{}{}{}\0", - guid.Data1, - guid.Data2, - guid.Data3, - guid.Data4[0], - guid.Data4[1], - guid.Data4[2], - guid.Data4[3], - guid.Data4[4], - guid.Data4[5], - guid.Data4[6], - guid.Data4[7] - ); - - let hinstance = GetModuleHandleA(0 as *const i8); - let wnd_class = WNDCLASSA { - // todo: for OpenGL, will use it later - style: CS_OWNDC | CS_HREDRAW | CS_VREDRAW, - lpfnWndProc: Some(wnd_proc), - hInstance: hinstance, - lpszClassName: class_name.as_ptr() as *const i8, - cbClsExtra: 0, - cbWndExtra: 0, - hIcon: 0 as HICON, - hCursor: 0 as HICON, - hbrBackground: 0 as HBRUSH, - lpszMenuName: 0 as *const i8, - }; - RegisterClassA(&wnd_class); - - let _hwnd = CreateWindowExA( - 0, - class_name.as_ptr() as *const i8, - // todo: change title based on options struct - "Baseview\0".as_ptr() as *const i8, - // todo: fine for now, will have to change with a parent - WS_OVERLAPPEDWINDOW | WS_VISIBLE, - CW_USEDEFAULT, - CW_USEDEFAULT, - // todo: check if usize fits into i32 - w.width as i32, - w.height as i32, - 0 as HWND, - 0 as HMENU, - hinstance, - 0 as LPVOID, - ); - } -} diff --git a/src/x11/mod.rs b/src/x11/mod.rs new file mode 100644 index 0000000..01e0b8e --- /dev/null +++ b/src/x11/mod.rs @@ -0,0 +1,2 @@ +mod window; +pub use window::*; diff --git a/src/x11.rs b/src/x11/window.rs similarity index 96% rename from src/x11.rs rename to src/x11/window.rs index 14e62dd..e64a55c 100644 --- a/src/x11.rs +++ b/src/x11/window.rs @@ -8,12 +8,12 @@ use crate::Parent; use crate::WindowOpenOptions; -struct X11Window { +pub struct Window { xcb_connection: xcb::Connection, } -impl X11Window { - pub fn run(options: WindowOpenOptions) -> Self { +impl Window { + pub fn open(options: WindowOpenOptions) -> Self { // Convert the parent to a X11 window ID if we're given one let parent = match options.parent { Parent::None => None, @@ -107,10 +107,6 @@ impl X11Window { } } -pub fn run(options: WindowOpenOptions) { - X11Window::run(options); -} - // Figure out the DPI scaling by opening a new temporary connection and asking XCB // TODO: currently returning (96, 96) on my system, even though I have 4k screens. Problem with my setup perhaps? #[allow(dead_code)]