diff --git a/Cargo.toml b/Cargo.toml index f88d0d5..9fc19f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,13 @@ authors = ["The Loki Authors"] keywords = ["windowing"] categories = ["gui"] +[features] +default = ["raw-window-handle"] +raw-window-handle = ["dep:raw-window-handle"] + +[dependencies] +raw-window-handle = { version = "0.5.2", optional = true } + [target.'cfg(target_os = "linux")'.dependencies] loki-linux = { path = "./loki-linux" } diff --git a/src/lok.rs b/src/lok.rs index 2e172ea..4b947a3 100644 --- a/src/lok.rs +++ b/src/lok.rs @@ -44,6 +44,19 @@ pub trait LokinitBackend { fn fetch_monitors(&mut self) -> Vec { unimplemented!() } + + #[cfg(feature = "raw-window-handle")] + fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle; + + #[cfg(feature = "raw-window-handle")] + fn raw_window_handle_for(&self, window_handle: WindowHandle) -> raw_window_handle::RawWindowHandle; +} + +#[cfg(feature = "raw-window-handle")] +unsafe impl raw_window_handle::HasRawDisplayHandle for dyn LokinitBackend { + fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { + self.raw_display_handle() + } } thread_local! { @@ -75,7 +88,13 @@ pub fn init_backend() { pub fn with(callback: impl FnOnce(&mut dyn LokinitBackend) -> R) -> R { INSTANCE.with(|instance| { let mut instance = instance.borrow_mut(); - let instance = instance.as_deref_mut().expect("Lokinit is not initialized"); + let instance = instance + .as_deref_mut() + .expect(if INITIALIZED.load(Ordering::Relaxed) { + "Accessing Lokinit from a non-main thread" + } else { + "Lokinit is not initialized" + }); (callback)(instance) }) } @@ -99,3 +118,13 @@ pub fn set_screen_mode(handle: WindowHandle, screen_mode: ScreenMode) { pub fn fetch_monitors() -> Vec { with(|instance| instance.fetch_monitors()) } + +#[cfg(feature = "raw-window-handle")] +pub fn raw_display_handle() -> raw_window_handle::RawDisplayHandle { + with(|instance| instance.raw_display_handle()) +} + +#[cfg(feature = "raw-window-handle")] +pub fn raw_window_handle(window_handle: WindowHandle) -> raw_window_handle::RawWindowHandle { + with(|instance| instance.raw_window_handle_for(window_handle)) +} diff --git a/src/native/linux/mod.rs b/src/native/linux/mod.rs index 4e669ac..49cc7cb 100644 --- a/src/native/linux/mod.rs +++ b/src/native/linux/mod.rs @@ -43,6 +43,22 @@ impl LokinitBackend for LinuxBackend { } } + #[cfg(feature = "raw-window-handle")] + fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { + match self { + Self::X11(_x11) => todo!(), + Self::Wayland(_wl) => todo!(), + } + } + + #[cfg(feature = "raw-window-handle")] + fn raw_window_handle_for(&self, window_handle: WindowHandle) -> raw_window_handle::RawWindowHandle { + match self { + Self::X11(_x11) => todo!(), + Self::Wayland(_wl) => todo!(), + } + } + fn set_screen_mode(&mut self, handle: WindowHandle, screen_mode: ScreenMode) { match self { Self::X11(x11) => x11.set_screen_mode(handle, screen_mode), diff --git a/src/native/macos/mod.rs b/src/native/macos/mod.rs index a6b0eac..a10b34c 100644 --- a/src/native/macos/mod.rs +++ b/src/native/macos/mod.rs @@ -181,4 +181,14 @@ impl LokinitBackend for MacosBackend { } } } + + #[cfg(feature = "raw-window-handle")] + fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { + todo!() + } + + #[cfg(feature = "raw-window-handle")] + fn raw_window_handle_for(&self, window_handle: WindowHandle) -> raw_window_handle::RawWindowHandle { + todo!() + } } diff --git a/src/window.rs b/src/window.rs index a64e543..2d74d8d 100644 --- a/src/window.rs +++ b/src/window.rs @@ -118,3 +118,17 @@ impl WindowBuilder { #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowHandle(pub(crate) usize); + +#[cfg(feature = "raw-window-handle")] +unsafe impl raw_window_handle::HasRawWindowHandle for WindowHandle { + fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { + crate::lok::raw_window_handle(*self) + } +} + +#[cfg(feature = "raw-window-handle")] +unsafe impl raw_window_handle::HasRawDisplayHandle for WindowHandle { + fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle { + crate::lok::raw_display_handle() + } +}