Merge pull request #1 from MirkoCovizzi/master
Add Windows initial code
This commit is contained in:
commit
4cb132a767
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
||||||
/target
|
/target
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
.idea
|
||||||
# CLion stuff
|
*.iml
|
||||||
.idea/
|
|
||||||
|
|
|
@ -3,14 +3,17 @@ name = "baseview"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = [
|
authors = [
|
||||||
"William Light <git@wrl.lhiaudio.com>",
|
"William Light <git@wrl.lhiaudio.com>",
|
||||||
"Charles Saracco <crsaracco@gmail.com>"
|
"Charles Saracco <crsaracco@gmail.com>",
|
||||||
|
"Mirko Covizzi <mrkcvzz@gmail.com>"
|
||||||
]
|
]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
[target.'cfg(target_os="linux")'.dependencies]
|
[target.'cfg(target_os="linux")'.dependencies]
|
||||||
xcb = { version = "0.9", features = ["thread", "xlib_xcb", "dri2"] }
|
xcb = { version = "0.9", features = ["thread", "xlib_xcb", "dri2"] }
|
||||||
|
|
||||||
# [target.'cfg(target_os="windows")'.dependencies]
|
[target.'cfg(target_os="windows")'.dependencies]
|
||||||
|
winapi = { version = "0.3.8", features = ["libloaderapi", "winuser", "windef", "minwindef", "guiddef", "combaseapi"] }
|
||||||
|
|
||||||
# [target.'cfg(target_os="macos")'.dependencies]
|
# [target.'cfg(target_os="macos")'.dependencies]
|
||||||
|
|
21
examples/windows.rs
Normal file
21
examples/windows.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use std::ptr::null_mut;
|
||||||
|
|
||||||
|
use baseview::Parent;
|
||||||
|
use baseview::{create_window, handle_msg, WindowOpenOptions};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let window = WindowOpenOptions {
|
||||||
|
title: "Baseview",
|
||||||
|
width: 800,
|
||||||
|
height: 400,
|
||||||
|
parent: Parent::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
create_window(window);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if !handle_msg(null_mut()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,7 @@
|
||||||
|
mod win;
|
||||||
|
|
||||||
|
pub use win::*;
|
||||||
|
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
|
|
||||||
mod x11;
|
mod x11;
|
||||||
|
|
3
src/win/mod.rs
Normal file
3
src/win/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
mod window;
|
||||||
|
|
||||||
|
pub use window::*;
|
104
src/win/window.rs
Normal file
104
src/win/window.rs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
extern crate winapi;
|
||||||
|
|
||||||
|
use self::winapi::_core::mem::MaybeUninit;
|
||||||
|
use self::winapi::shared::guiddef::GUID;
|
||||||
|
use self::winapi::shared::minwindef::{LPARAM, LPVOID, LRESULT, UINT, WPARAM};
|
||||||
|
use self::winapi::shared::windef::{HBRUSH, HICON, HMENU, HWND};
|
||||||
|
use self::winapi::um::combaseapi::CoCreateGuid;
|
||||||
|
use self::winapi::um::libloaderapi::GetModuleHandleA;
|
||||||
|
use self::winapi::um::winuser::{
|
||||||
|
CreateWindowExA, DefWindowProcA, DispatchMessageA, PeekMessageA, PostQuitMessage,
|
||||||
|
RegisterClassA, TranslateMessage, CS_HREDRAW, CS_OWNDC, CS_VREDRAW, CW_USEDEFAULT, MSG,
|
||||||
|
PM_REMOVE, WM_DESTROY, WM_QUIT, WNDCLASSA, WS_OVERLAPPEDWINDOW, WS_VISIBLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::WindowOpenOptions;
|
||||||
|
|
||||||
|
pub fn handle_msg(_window: HWND) -> bool {
|
||||||
|
unsafe {
|
||||||
|
let mut msg: MSG = MaybeUninit::uninit().assume_init();
|
||||||
|
loop {
|
||||||
|
if PeekMessageA(&mut msg, 0 as HWND, 0, 0, PM_REMOVE) == 0 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if msg.message == WM_QUIT {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessageA(&msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe extern "system" fn wnd_proc(
|
||||||
|
hwnd: HWND,
|
||||||
|
msg: UINT,
|
||||||
|
w_param: WPARAM,
|
||||||
|
l_param: LPARAM,
|
||||||
|
) -> LRESULT {
|
||||||
|
match msg {
|
||||||
|
WM_DESTROY => {
|
||||||
|
PostQuitMessage(0);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return DefWindowProcA(hwnd, msg, w_param, l_param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue