Add Redox/Orbital support
This commit is contained in:
parent
939bcc44d8
commit
7351d68814
4 changed files with 116 additions and 1 deletions
|
|
@ -37,6 +37,9 @@ wasm-bindgen = "0.2.78"
|
||||||
version = "0.3.55"
|
version = "0.3.55"
|
||||||
features = ["CanvasRenderingContext2d", "Document", "Element", "HtmlCanvasElement", "ImageData", "Window"]
|
features = ["CanvasRenderingContext2d", "Document", "Element", "HtmlCanvasElement", "ImageData", "Window"]
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "redox")'.dependencies]
|
||||||
|
redox_syscall = "0.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
instant = "0.1.12"
|
instant = "0.1.12"
|
||||||
winit = "0.27.2"
|
winit = "0.27.2"
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ For now, the priority for new platforms is:
|
||||||
✅: Present | ❌: Absent
|
✅: Present | ❌: Absent
|
||||||
- AndroidNdk ❌
|
- AndroidNdk ❌
|
||||||
- AppKit ✅ (Thanks to [Seo Sanghyeon](https://github.com/sanxiyn) and [lunixbochs](https://github.com/lunixbochs)!)
|
- AppKit ✅ (Thanks to [Seo Sanghyeon](https://github.com/sanxiyn) and [lunixbochs](https://github.com/lunixbochs)!)
|
||||||
- Orbital ❌
|
- Orbital ✅
|
||||||
- UiKit ❌
|
- UiKit ❌
|
||||||
- Wayland ✅ (Wayland support in winit is immature at the moment, so it might be wise to force X11 if you're using winit)
|
- Wayland ✅ (Wayland support in winit is immature at the moment, so it might be wise to force X11 if you're using winit)
|
||||||
- Web ✅ (Thanks to [Liamolucko](https://github.com/Liamolucko)!)
|
- Web ✅ (Thanks to [Liamolucko](https://github.com/Liamolucko)!)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ mod x11;
|
||||||
mod wayland;
|
mod wayland;
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
mod web;
|
mod web;
|
||||||
|
#[cfg(target_os = "redox")]
|
||||||
|
mod orbital;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
|
|
||||||
|
|
@ -52,6 +54,8 @@ impl<W: HasRawWindowHandle + HasRawDisplayHandle> GraphicsContext<W> {
|
||||||
(RawWindowHandle::AppKit(appkit_handle), _) => Box::new(cg::CGImpl::new(appkit_handle)?),
|
(RawWindowHandle::AppKit(appkit_handle), _) => Box::new(cg::CGImpl::new(appkit_handle)?),
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
(RawWindowHandle::Web(web_handle), _) => Box::new(web::WebImpl::new(web_handle)?),
|
(RawWindowHandle::Web(web_handle), _) => Box::new(web::WebImpl::new(web_handle)?),
|
||||||
|
#[cfg(target_os = "redox")]
|
||||||
|
(RawWindowHandle::Orbital(orbital_handle), _) => Box::new(orbital::OrbitalImpl::new(orbital_handle)?),
|
||||||
(unimplemented_window_handle, unimplemented_display_handle) => return Err(SoftBufferError::UnsupportedPlatform {
|
(unimplemented_window_handle, unimplemented_display_handle) => return Err(SoftBufferError::UnsupportedPlatform {
|
||||||
window,
|
window,
|
||||||
human_readable_window_platform_name: window_handle_type_name(&unimplemented_window_handle),
|
human_readable_window_platform_name: window_handle_type_name(&unimplemented_window_handle),
|
||||||
|
|
|
||||||
108
src/orbital.rs
Normal file
108
src/orbital.rs
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
use raw_window_handle::HasRawWindowHandle;
|
||||||
|
use raw_window_handle::OrbitalWindowHandle;
|
||||||
|
use std::{
|
||||||
|
cmp,
|
||||||
|
slice,
|
||||||
|
str,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::GraphicsContextImpl;
|
||||||
|
use crate::SoftBufferError;
|
||||||
|
|
||||||
|
struct OrbitalMap {
|
||||||
|
address: usize,
|
||||||
|
size: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OrbitalMap {
|
||||||
|
unsafe fn new(fd: usize, size_unaligned: usize) -> syscall::Result<Self> {
|
||||||
|
// Page align size
|
||||||
|
let pages = (size_unaligned + syscall::PAGE_SIZE - 1) / syscall::PAGE_SIZE;
|
||||||
|
let size = pages * syscall::PAGE_SIZE;
|
||||||
|
|
||||||
|
// Map window buffer
|
||||||
|
let address = syscall::fmap(fd, &syscall::Map {
|
||||||
|
offset: 0,
|
||||||
|
size,
|
||||||
|
flags: syscall::PROT_READ | syscall::PROT_WRITE,
|
||||||
|
address: 0,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(Self { address, size })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for OrbitalMap {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
// Unmap window buffer on drop
|
||||||
|
syscall::funmap(self.address, self.size)
|
||||||
|
.expect("failed to unmap orbital window");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OrbitalImpl {
|
||||||
|
handle: OrbitalWindowHandle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OrbitalImpl {
|
||||||
|
pub fn new<W: HasRawWindowHandle>(handle: OrbitalWindowHandle) -> Result<Self, SoftBufferError<W>> {
|
||||||
|
Ok(Self { handle })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GraphicsContextImpl for OrbitalImpl {
|
||||||
|
unsafe fn set_buffer(&mut self, buffer: &[u32], width_u16: u16, height_u16: u16) {
|
||||||
|
let window_fd = self.handle.window as usize;
|
||||||
|
|
||||||
|
// Read the current width and size
|
||||||
|
let mut window_width = 0;
|
||||||
|
let mut window_height = 0;
|
||||||
|
{
|
||||||
|
let mut buf: [u8; 4096] = [0; 4096];
|
||||||
|
let count = syscall::fpath(window_fd, &mut buf).unwrap();
|
||||||
|
let path = str::from_utf8(&buf[..count]).unwrap();
|
||||||
|
// orbital:/x/y/w/h/t
|
||||||
|
let mut parts = path.split('/').skip(3);
|
||||||
|
if let Some(w) = parts.next() {
|
||||||
|
window_width = w.parse::<usize>().unwrap_or(0);
|
||||||
|
}
|
||||||
|
if let Some(h) = parts.next() {
|
||||||
|
window_height = h.parse::<usize>().unwrap_or(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Map window buffer
|
||||||
|
let window_map = OrbitalMap::new(
|
||||||
|
window_fd,
|
||||||
|
window_width * window_height * 4
|
||||||
|
).expect("failed to map orbital window");
|
||||||
|
|
||||||
|
// Window buffer is u32 color data in 0xAABBGGRR format
|
||||||
|
let window_data = slice::from_raw_parts_mut(
|
||||||
|
window_map.address as *mut u32,
|
||||||
|
window_width * window_height
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy each line, cropping to fit
|
||||||
|
let width = width_u16 as usize;
|
||||||
|
let height = height_u16 as usize;
|
||||||
|
let min_width = cmp::min(width, window_width);
|
||||||
|
let min_height = cmp::min(height, window_height);
|
||||||
|
for y in 0..min_height {
|
||||||
|
let offset_buffer = y * width;
|
||||||
|
let offset_data = y * window_width;
|
||||||
|
window_data[offset_data..offset_data + min_width].copy_from_slice(
|
||||||
|
&buffer[offset_buffer..offset_buffer + min_width]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window buffer map is dropped here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell orbital to show the latest window data
|
||||||
|
syscall::fsync(window_fd).expect("failed to sync orbital window");
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue