2023-01-05 06:58:08 -07:00
|
|
|
#![cfg(target_os = "redox")]
|
|
|
|
|
|
2024-07-23 19:59:37 +02:00
|
|
|
use std::num::{NonZeroU16, NonZeroU32};
|
2024-09-06 17:20:11 +03:00
|
|
|
use std::{fmt, str};
|
2023-01-05 06:58:08 -07:00
|
|
|
|
2024-02-08 01:55:11 -07:00
|
|
|
use smol_str::SmolStr;
|
|
|
|
|
|
2024-11-13 15:29:05 +03:00
|
|
|
pub(crate) use self::event_loop::{ActiveEventLoop, EventLoop};
|
2024-02-08 01:55:11 -07:00
|
|
|
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
|
|
|
|
use crate::keyboard::Key;
|
2023-01-05 06:58:08 -07:00
|
|
|
mod event_loop;
|
|
|
|
|
|
|
|
|
|
pub use self::window::Window;
|
|
|
|
|
mod window;
|
|
|
|
|
|
2024-09-06 17:20:11 +03:00
|
|
|
pub(crate) use crate::cursor::{
|
|
|
|
|
NoCustomCursor as PlatformCustomCursor, NoCustomCursor as PlatformCustomCursorSource,
|
|
|
|
|
};
|
|
|
|
|
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
|
|
|
|
|
2023-01-05 06:58:08 -07:00
|
|
|
struct RedoxSocket {
|
|
|
|
|
fd: usize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl RedoxSocket {
|
|
|
|
|
fn event() -> syscall::Result<Self> {
|
|
|
|
|
Self::open_raw("event:")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn orbital(properties: &WindowProperties<'_>) -> syscall::Result<Self> {
|
2023-01-27 07:18:58 +03:00
|
|
|
Self::open_raw(&format!("{properties}"))
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Paths should be checked to ensure they are actually sockets and not normal files. If a
|
|
|
|
|
// non-socket path is used, it could cause read and write to not function as expected. For
|
|
|
|
|
// example, the seek would change in a potentially unpredictable way if either read or write
|
|
|
|
|
// were called at the same time by multiple threads.
|
|
|
|
|
fn open_raw(path: &str) -> syscall::Result<Self> {
|
|
|
|
|
let fd = syscall::open(path, syscall::O_RDWR | syscall::O_CLOEXEC)?;
|
|
|
|
|
Ok(Self { fd })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn read(&self, buf: &mut [u8]) -> syscall::Result<()> {
|
|
|
|
|
let count = syscall::read(self.fd, buf)?;
|
|
|
|
|
if count == buf.len() {
|
|
|
|
|
Ok(())
|
|
|
|
|
} else {
|
|
|
|
|
Err(syscall::Error::new(syscall::EINVAL))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn write(&self, buf: &[u8]) -> syscall::Result<()> {
|
|
|
|
|
let count = syscall::write(self.fd, buf)?;
|
|
|
|
|
if count == buf.len() {
|
|
|
|
|
Ok(())
|
|
|
|
|
} else {
|
|
|
|
|
Err(syscall::Error::new(syscall::EINVAL))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn fpath<'a>(&self, buf: &'a mut [u8]) -> syscall::Result<&'a str> {
|
|
|
|
|
let count = syscall::fpath(self.fd, buf)?;
|
|
|
|
|
str::from_utf8(&buf[..count]).map_err(|_err| syscall::Error::new(syscall::EINVAL))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for RedoxSocket {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
let _ = syscall::close(self.fd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct TimeSocket(RedoxSocket);
|
|
|
|
|
|
|
|
|
|
impl TimeSocket {
|
|
|
|
|
fn open() -> syscall::Result<Self> {
|
|
|
|
|
RedoxSocket::open_raw("time:4").map(Self)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Read current time.
|
|
|
|
|
fn current_time(&self) -> syscall::Result<syscall::TimeSpec> {
|
|
|
|
|
let mut timespec = syscall::TimeSpec::default();
|
|
|
|
|
self.0.read(&mut timespec)?;
|
|
|
|
|
Ok(timespec)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write a timeout.
|
|
|
|
|
fn timeout(&self, timespec: &syscall::TimeSpec) -> syscall::Result<()> {
|
|
|
|
|
self.0.write(timespec)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wake immediately.
|
|
|
|
|
fn wake(&self) -> syscall::Result<()> {
|
|
|
|
|
// Writing a default TimeSpec will always trigger a time event.
|
|
|
|
|
self.timeout(&syscall::TimeSpec::default())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
|
|
|
pub(crate) struct PlatformSpecificEventLoopAttributes {}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
2024-01-31 17:29:59 +04:00
|
|
|
pub struct PlatformSpecificWindowAttributes;
|
2023-01-05 06:58:08 -07:00
|
|
|
|
|
|
|
|
struct WindowProperties<'a> {
|
|
|
|
|
flags: &'a str,
|
|
|
|
|
x: i32,
|
|
|
|
|
y: i32,
|
|
|
|
|
w: u32,
|
|
|
|
|
h: u32,
|
|
|
|
|
title: &'a str,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> WindowProperties<'a> {
|
|
|
|
|
fn new(path: &'a str) -> Self {
|
|
|
|
|
// orbital:flags/x/y/w/h/t
|
|
|
|
|
let mut parts = path.splitn(6, '/');
|
|
|
|
|
let flags = parts.next().unwrap_or("");
|
|
|
|
|
let x = parts.next().map_or(0, |part| part.parse::<i32>().unwrap_or(0));
|
|
|
|
|
let y = parts.next().map_or(0, |part| part.parse::<i32>().unwrap_or(0));
|
|
|
|
|
let w = parts.next().map_or(0, |part| part.parse::<u32>().unwrap_or(0));
|
|
|
|
|
let h = parts.next().map_or(0, |part| part.parse::<u32>().unwrap_or(0));
|
|
|
|
|
let title = parts.next().unwrap_or("");
|
|
|
|
|
Self { flags, x, y, w, h, title }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> fmt::Display for WindowProperties<'a> {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
write!(
|
|
|
|
|
f,
|
|
|
|
|
"orbital:{}/{}/{}/{}/{}/{}",
|
|
|
|
|
self.flags, self.x, self.y, self.w, self.h, self.title
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
|
|
|
|
pub struct MonitorHandle;
|
|
|
|
|
|
|
|
|
|
impl MonitorHandle {
|
|
|
|
|
pub fn name(&self) -> Option<String> {
|
2024-07-23 19:59:37 +02:00
|
|
|
None
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 19:59:37 +02:00
|
|
|
pub fn position(&self) -> Option<PhysicalPosition<i32>> {
|
|
|
|
|
None
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn scale_factor(&self) -> f64 {
|
|
|
|
|
1.0 // TODO
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-21 00:01:43 +02:00
|
|
|
pub fn current_video_mode(&self) -> Option<VideoModeHandle> {
|
2023-01-05 06:58:08 -07:00
|
|
|
// (it is guaranteed to support 32 bit color though)
|
2024-07-23 19:59:37 +02:00
|
|
|
Some(VideoModeHandle { monitor: self.clone() })
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
2024-07-21 00:01:43 +02:00
|
|
|
|
|
|
|
|
pub fn video_modes(&self) -> impl Iterator<Item = VideoModeHandle> {
|
|
|
|
|
self.current_video_mode().into_iter()
|
|
|
|
|
}
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
2023-12-26 22:12:33 +01:00
|
|
|
pub struct VideoModeHandle {
|
2023-01-05 06:58:08 -07:00
|
|
|
monitor: MonitorHandle,
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-26 22:12:33 +01:00
|
|
|
impl VideoModeHandle {
|
2023-01-05 06:58:08 -07:00
|
|
|
pub fn size(&self) -> PhysicalSize<u32> {
|
2024-07-23 19:59:37 +02:00
|
|
|
// TODO
|
|
|
|
|
PhysicalSize::default()
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 19:59:37 +02:00
|
|
|
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
|
|
|
|
None
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
2024-07-23 19:59:37 +02:00
|
|
|
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
2024-07-21 00:40:57 +02:00
|
|
|
// TODO
|
|
|
|
|
None
|
2023-01-05 06:58:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn monitor(&self) -> MonitorHandle {
|
|
|
|
|
self.monitor.clone()
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-28 20:02:59 +02:00
|
|
|
|
2024-02-08 01:55:11 -07:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
|
|
|
|
pub struct KeyEventExtra {
|
|
|
|
|
pub key_without_modifiers: Key,
|
|
|
|
|
pub text_with_all_modifiers: Option<SmolStr>,
|
|
|
|
|
}
|