1
0
Fork 0
This commit is contained in:
Mirko Covizzi 2020-05-29 11:30:43 +02:00
commit 829fa2c9bd
11 changed files with 114 additions and 109 deletions

27
.github/workflows/rust.yml vendored Normal file
View file

@ -0,0 +1,27 @@
name: Rust
on: [push]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v2
- name: install XCB dependencies
run: |
sudo apt update
sudo apt install libx11-xcb-dev libxcb-dri2-0-dev
if: contains(matrix.os, 'ubuntu')
- name: install rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose

View file

@ -1,21 +0,0 @@
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;
}
}
}

View file

@ -1,10 +0,0 @@
fn main() {
let window_open_options = baseview::WindowOpenOptions {
title: "baseview",
width: 512,
height: 512,
parent: baseview::Parent::None,
};
baseview::run(window_open_options);
}

View file

@ -1,21 +1,19 @@
// todo: will deal with conditional compilation/visibility later, use std::ffi::c_void;
// todo: we still have to choose how to organize the code
// todo: for now I need this to be able to check and compile
// todo: We should consider doing it as winit does it
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
mod win; mod win;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
pub use win::*; pub use win::*;
use std::ffi::c_void;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
mod x11; mod x11;
#[cfg(target_os = "linux")]
pub use x11::*;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
mod macos; mod macos;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub use macos::Window; pub use macos::*;
pub enum Parent { pub enum Parent {
None, None,
@ -31,8 +29,3 @@ pub struct WindowOpenOptions<'a> {
pub parent: Parent, pub parent: Parent,
} }
pub fn run(options: WindowOpenOptions) {
#[cfg(target_os = "linux")]
x11::run(options);
}

2
src/macos/mod.rs Normal file
View file

@ -0,0 +1,2 @@
mod window;
pub use window::*;

View file

@ -11,7 +11,7 @@ use crate::WindowOpenOptions;
pub struct Window; pub struct Window;
impl Window { impl Window {
pub fn open(options: WindowOpenOptions) { pub fn open(options: WindowOpenOptions) -> Self {
unsafe { unsafe {
let _pool = NSAutoreleasePool::new(nil); let _pool = NSAutoreleasePool::new(nil);
@ -41,6 +41,8 @@ impl Window {
let current_app = NSRunningApplication::currentApplication(nil); let current_app = NSRunningApplication::currentApplication(nil);
current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps); current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
app.run(); app.run();
Window
} }
} }
} }

View file

@ -1,3 +1,2 @@
mod window; mod window;
pub use window::*; pub use window::*;

View file

@ -1,5 +1,7 @@
extern crate winapi; extern crate winapi;
use std::ptr::null_mut;
use self::winapi::_core::mem::MaybeUninit; use self::winapi::_core::mem::MaybeUninit;
use self::winapi::shared::guiddef::GUID; use self::winapi::shared::guiddef::GUID;
use self::winapi::shared::minwindef::{LPARAM, LPVOID, LRESULT, UINT, WPARAM}; use self::winapi::shared::minwindef::{LPARAM, LPVOID, LRESULT, UINT, WPARAM};
@ -14,7 +16,74 @@ use self::winapi::um::winuser::{
use crate::WindowOpenOptions; 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-{:0X}-{:0X}-{:0X}-{:0X}{:0X}-{:0X}{:0X}{:0X}{:0X}{:0X}{:0X}\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,
(options.title.to_owned() + "\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 { unsafe {
let mut msg: MSG = MaybeUninit::uninit().assume_init(); let mut msg: MSG = MaybeUninit::uninit().assume_init();
loop { loop {
@ -30,7 +99,7 @@ pub fn handle_msg(_window: HWND) -> bool {
} }
} }
pub unsafe extern "system" fn wnd_proc( unsafe extern "system" fn wnd_proc(
hwnd: HWND, hwnd: HWND,
msg: UINT, msg: UINT,
w_param: WPARAM, w_param: WPARAM,
@ -46,58 +115,3 @@ pub unsafe extern "system" fn wnd_proc(
} }
return 0; 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-{:0X}-{:0X}-{:0X}-{:0X}{:0X}-{:0X}{:0X}{:0X}{:0X}{:0X}{:0X}\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,
(w.title.to_owned() + "\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,
);
}
}

2
src/x11/mod.rs Normal file
View file

@ -0,0 +1,2 @@
mod window;
pub use window::*;

View file

@ -8,12 +8,12 @@
use crate::Parent; use crate::Parent;
use crate::WindowOpenOptions; use crate::WindowOpenOptions;
struct X11Window { pub struct Window {
xcb_connection: xcb::Connection, xcb_connection: xcb::Connection,
} }
impl X11Window { impl Window {
pub fn run(options: WindowOpenOptions) -> Self { pub fn open(options: WindowOpenOptions) -> Self {
// Convert the parent to a X11 window ID if we're given one // Convert the parent to a X11 window ID if we're given one
let parent = match options.parent { let parent = match options.parent {
Parent::None => None, Parent::None => None,
@ -107,12 +107,9 @@ impl X11Window {
} }
} }
pub fn run(options: WindowOpenOptions) {
X11Window::run(options);
}
// Figure out the DPI scaling by opening a new temporary connection and asking XCB // 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? // TODO: currently returning (96, 96) on my system, even though I have 4k screens. Problem with my setup perhaps?
#[allow(dead_code)]
pub fn get_scaling() -> (u32, u32) { pub fn get_scaling() -> (u32, u32) {
let (conn, screen_num) = xcb::Connection::connect_with_xlib_display().unwrap(); let (conn, screen_num) = xcb::Connection::connect_with_xlib_display().unwrap();