Merge
This commit is contained in:
commit
829fa2c9bd
27
.github/workflows/rust.yml
vendored
Normal file
27
.github/workflows/rust.yml
vendored
Normal 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
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
17
src/lib.rs
17
src/lib.rs
|
@ -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
2
src/macos/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
mod window;
|
||||||
|
pub use window::*;
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,2 @@
|
||||||
mod window;
|
mod window;
|
||||||
|
|
||||||
pub use window::*;
|
pub use window::*;
|
||||||
|
|
|
@ -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
2
src/x11/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
mod window;
|
||||||
|
pub use window::*;
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue