Vendor things

This commit is contained in:
John Doty 2024-03-08 11:03:01 -08:00
parent 5deceec006
commit 977e3c17e5
19434 changed files with 10682014 additions and 0 deletions

View file

@ -0,0 +1,43 @@
use core::ffi::c_void;
use core::ptr;
/// Raw display handle for Android.
///
/// ## Construction
/// ```
/// # use raw_window_handle::AndroidDisplayHandle;
/// let mut display_handle = AndroidDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AndroidDisplayHandle;
impl AndroidDisplayHandle {
pub fn empty() -> Self {
Self {}
}
}
/// Raw window handle for Android NDK.
///
/// ## Construction
/// ```
/// # use raw_window_handle::AndroidNdkWindowHandle;
/// let mut window_handle = AndroidNdkWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AndroidNdkWindowHandle {
/// A pointer to an `ANativeWindow`.
pub a_native_window: *mut c_void,
}
impl AndroidNdkWindowHandle {
pub fn empty() -> Self {
Self {
a_native_window: ptr::null_mut(),
}
}
}

View file

@ -0,0 +1,47 @@
use core::ffi::c_void;
use core::ptr;
/// Raw display handle for AppKit.
///
/// ## Construction
/// ```
/// # use raw_window_handle::AppKitDisplayHandle;
/// let mut display_handle = AppKitDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AppKitDisplayHandle;
impl AppKitDisplayHandle {
pub fn empty() -> Self {
Self {}
}
}
/// Raw window handle for AppKit.
///
/// ## Construction
/// ```
/// # use raw_window_handle::AppKitWindowHandle;
/// let mut window_handle = AppKitWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct AppKitWindowHandle {
/// A pointer to an `NSWindow` object.
pub ns_window: *mut c_void,
/// A pointer to an `NSView` object.
pub ns_view: *mut c_void,
// TODO: WHAT ABOUT ns_window_controller and ns_view_controller?
}
impl AppKitWindowHandle {
pub fn empty() -> Self {
Self {
ns_window: ptr::null_mut(),
ns_view: ptr::null_mut(),
}
}
}

View file

@ -0,0 +1,615 @@
//! Borrowable window handles based on the ones in this crate.
//!
//! These should be 100% safe to pass around and use, no possibility of dangling or invalidity.
#[cfg(all(not(feature = "std"), target_os = "android"))]
compile_error!("Using borrowed handles on Android requires the `std` feature to be enabled.");
use core::fmt;
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
use crate::{HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle};
/// Keeps track of whether the application is currently active.
///
/// On certain platforms (e.g. Android), it is possible for the application to enter a "suspended"
/// state. While in this state, all previously valid window handles become invalid. Therefore, in
/// order for window handles to be valid, the application must be active.
///
/// On platforms where the graphical user interface is always active, this type is a ZST and all
/// of its methods are noops. On Android, this type acts as a reference counter that keeps track
/// of all currently active window handles. Before the application enters the suspended state, it
/// blocks until all of the currently active window handles are dropped.
///
/// ## Explanation
///
/// On Android, there is an [Activity]-global [`ANativeWindow`] object that is used for drawing. This
/// handle is used [within the `RawWindowHandle` type] for Android NDK, since it is necessary for GFX
/// APIs to draw to the screen.
///
/// However, the [`ANativeWindow`] type can be arbitrarily invalidated by the underlying Android runtime.
/// The reasoning for this is complicated, but this idea is exposed to native code through the
/// [`onNativeWindowCreated`] and [`onNativeWindowDestroyed`] callbacks. To save you a click, the
/// conditions associated with these callbacks are:
///
/// - [`onNativeWindowCreated`] provides a valid [`ANativeWindow`] pointer that can be used for drawing.
/// - [`onNativeWindowDestroyed`] indicates that the previous [`ANativeWindow`] pointer is no longer
/// valid. The documentation clarifies that, *once the function returns*, the [`ANativeWindow`] pointer
/// can no longer be used for drawing without resulting in undefined behavior.
///
/// In [`winit`], these are exposed via the [`Resumed`] and [`Suspended`] events, respectively. Therefore,
/// between the last [`Suspended`] event and the next [`Resumed`] event, it is undefined behavior to use
/// the raw window handle. This condition makes it tricky to define an API that safely wraps the raw
/// window handles, since an existing window handle can be made invalid at any time.
///
/// The Android docs specifies that the [`ANativeWindow`] pointer is still valid while the application
/// is still in the [`onNativeWindowDestroyed`] block, and suggests that synchronization needs to take
/// place to ensure that the pointer has been invalidated before the function returns. `Active` aims
/// to be the solution to this problem. It keeps track of all currently active window handles, and
/// blocks until all of them are dropped before allowing the application to enter the suspended state.
///
/// [Activity]: https://developer.android.com/reference/android/app/Activity
/// [`ANativeWindow`]: https://developer.android.com/ndk/reference/group/a-native-window
/// [within the `RawWindowHandle` type]: struct.AndroidNdkWindowHandle.html#structfield.a_native_window
/// [`onNativeWindowCreated`]: https://developer.android.com/ndk/reference/struct/a-native-activity-callbacks#onnativewindowcreated
/// [`onNativeWindowDestroyed`]: https://developer.android.com/ndk/reference/struct/a-native-activity-callbacks#onnativewindowdestroyed
/// [`Resumed`]: https://docs.rs/winit/latest/winit/event/enum.Event.html#variant.Resumed
/// [`Suspended`]: https://docs.rs/winit/latest/winit/event/enum.Event.html#variant.Suspended
/// [`sdl2`]: https://crates.io/crates/sdl2
/// [`RawWindowHandle`]: https://docs.rs/raw-window-handle/latest/raw_window_handle/enum.RawWindowHandle.html
/// [`HasRawWindowHandle`]: https://docs.rs/raw-window-handle/latest/raw_window_handle/trait.HasRawWindowHandle.html
/// [`winit`]: https://crates.io/crates/winit
pub struct Active(imp::Active);
impl fmt::Debug for Active {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Active { .. }")
}
}
/// Represents a live window handle.
///
/// This is carried around by the [`Active`] type, and is used to ensure that the application doesn't
/// enter the suspended state while there are still live window handles. See documentation on the
/// [`Active`] type for more information.
///
/// On non-Android platforms, this is a ZST. On Android, this is a reference counted handle that
/// keeps the application active while it is alive.
#[derive(Clone)]
pub struct ActiveHandle<'a>(imp::ActiveHandle<'a>);
impl<'a> fmt::Debug for ActiveHandle<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("ActiveHandle { .. }")
}
}
impl Active {
/// Create a new `Active` tracker.
///
/// Only one of these should exist per display connection.
///
/// # Example
///
/// ```
/// use raw_window_handle::Active;
/// let active = Active::new();
/// ```
pub const fn new() -> Self {
Self(imp::Active::new())
}
/// Get a live window handle.
///
/// This function returns an active handle if the application is active, and `None` otherwise.
///
/// # Example
///
/// ```
/// use raw_window_handle::Active;
///
/// // Set the application to be active.
/// let active = Active::new();
/// unsafe { active.set_active() };
///
/// // Get a live window handle.
/// let handle = active.handle();
///
/// // Drop it and set the application to be inactive.
/// drop(handle);
/// active.set_inactive();
/// ```
pub fn handle(&self) -> Option<ActiveHandle<'_>> {
self.0.handle().map(ActiveHandle)
}
/// Set the application to be inactive.
///
/// This function may block until there are no more active handles.
///
/// # Example
///
/// ```
/// use raw_window_handle::Active;
///
/// // Set the application to be active.
/// let active = Active::new();
/// unsafe { active.set_active() };
///
/// // Set the application to be inactive.
/// active.set_inactive();
/// ```
pub fn set_inactive(&self) {
self.0.set_inactive()
}
/// Set the application to be active.
///
/// # Safety
///
/// The application must actually be active. Setting to active when the application is not active
/// will result in undefined behavior.
///
/// # Example
///
/// ```
/// use raw_window_handle::Active;
///
/// // Set the application to be active.
/// let active = Active::new();
/// unsafe { active.set_active() };
///
/// // Set the application to be inactive.
/// active.set_inactive();
/// ```
pub unsafe fn set_active(&self) {
self.0.set_active()
}
}
impl ActiveHandle<'_> {
/// Create a new freestanding active handle.
///
/// This function acts as an "escape hatch" to allow the user to create a live window handle
/// without having to go through the [`Active`] type. This is useful if the user *knows* that the
/// application is active, and wants to create a live window handle without having to go through
/// the [`Active`] type.
///
/// # Safety
///
/// The application must actually be active.
///
/// # Example
///
/// ```
/// use raw_window_handle::ActiveHandle;
///
/// // Create a freestanding active handle.
/// // SAFETY: The application must actually be active.
/// let handle = unsafe { ActiveHandle::new_unchecked() };
/// ```
pub unsafe fn new_unchecked() -> Self {
Self(imp::ActiveHandle::new_unchecked())
}
}
/// A display that acts as a wrapper around a display handle.
///
/// Objects that implement this trait should be able to return a [`DisplayHandle`] for the display
/// that they are associated with. This handle should last for the lifetime of the object, and should
/// return an error if the application is inactive.
///
/// Implementors of this trait will be windowing systems, like [`winit`] and [`sdl2`]. These windowing
/// systems should implement this trait on types that already implement [`HasRawDisplayHandle`]. It
/// should be implemented by tying the lifetime of the [`DisplayHandle`] to the lifetime of the
/// display object.
///
/// Users of this trait will include graphics libraries, like [`wgpu`] and [`glutin`]. These APIs
/// should be generic over a type that implements `HasDisplayHandle`, and should use the
/// [`DisplayHandle`] type to access the display handle.
///
/// # Safety
///
/// The safety requirements of [`HasRawDisplayHandle`] apply here as well. To reiterate, the
/// [`DisplayHandle`] must contain a valid window handle for its lifetime.
///
/// It is not possible to invalidate a [`DisplayHandle`] on any platform without additional unsafe code.
///
/// Note that these requirements are not enforced on `HasDisplayHandle`, rather, they are enforced on the
/// constructors of [`DisplayHandle`]. This is because the `HasDisplayHandle` trait is safe to implement.
///
/// [`HasRawDisplayHandle`]: crate::HasRawDisplayHandle
/// [`winit`]: https://crates.io/crates/winit
/// [`sdl2`]: https://crates.io/crates/sdl2
/// [`wgpu`]: https://crates.io/crates/wgpu
/// [`glutin`]: https://crates.io/crates/glutin
pub trait HasDisplayHandle {
/// Get a handle to the display controller of the windowing system.
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError>;
}
impl<H: HasDisplayHandle + ?Sized> HasDisplayHandle for &H {
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
(**self).display_handle()
}
}
#[cfg(feature = "alloc")]
impl<H: HasDisplayHandle + ?Sized> HasDisplayHandle for alloc::boxed::Box<H> {
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
(**self).display_handle()
}
}
#[cfg(feature = "alloc")]
impl<H: HasDisplayHandle + ?Sized> HasDisplayHandle for alloc::rc::Rc<H> {
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
(**self).display_handle()
}
}
#[cfg(feature = "alloc")]
impl<H: HasDisplayHandle + ?Sized> HasDisplayHandle for alloc::sync::Arc<H> {
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
(**self).display_handle()
}
}
/// The handle to the display controller of the windowing system.
///
/// This is the primary return type of the [`HasDisplayHandle`] trait. It is guaranteed to contain
/// a valid platform-specific display handle for its lifetime.
///
/// Get the underlying raw display handle with the [`HasRawDisplayHandle`] trait.
#[repr(transparent)]
#[derive(PartialEq, Eq, Hash)]
pub struct DisplayHandle<'a> {
raw: RawDisplayHandle,
_marker: PhantomData<&'a *const ()>,
}
impl fmt::Debug for DisplayHandle<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("DisplayHandle").field(&self.raw).finish()
}
}
impl<'a> Clone for DisplayHandle<'a> {
fn clone(&self) -> Self {
Self {
raw: self.raw,
_marker: PhantomData,
}
}
}
impl<'a> DisplayHandle<'a> {
/// Create a `DisplayHandle` from a [`RawDisplayHandle`].
///
/// # Safety
///
/// The `RawDisplayHandle` must be valid for the lifetime.
pub unsafe fn borrow_raw(raw: RawDisplayHandle) -> Self {
Self {
raw,
_marker: PhantomData,
}
}
}
unsafe impl HasRawDisplayHandle for DisplayHandle<'_> {
fn raw_display_handle(&self) -> RawDisplayHandle {
self.raw
}
}
impl<'a> HasDisplayHandle for DisplayHandle<'a> {
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
Ok(self.clone())
}
}
/// A handle to a window.
///
/// Objects that implement this trait should be able to return a [`WindowHandle`] for the window
/// that they are associated with. This handle should last for the lifetime of the object, and should
/// return an error if the application is inactive.
///
/// Implementors of this trait will be windowing systems, like [`winit`] and [`sdl2`]. These windowing
/// systems should implement this trait on types that already implement [`HasRawWindowHandle`]. First,
/// it should be made sure that the display type contains a unique [`Active`] ref-counted handle.
/// To create a [`WindowHandle`], the [`Active`] should be used to create an [`ActiveHandle`] that is
/// then used to create a [`WindowHandle`]. Finally, the raw window handle should be retrieved from
/// the type and used to create a [`WindowHandle`].
///
/// Users of this trait will include graphics libraries, like [`wgpu`] and [`glutin`]. These APIs
/// should be generic over a type that implements `HasWindowHandle`, and should use the
/// [`WindowHandle`] type to access the window handle. The window handle should be acquired and held
/// while the window is being used, in order to ensure that the window is not deleted while it is in
/// use.
///
/// # Safety
///
/// All pointers within the resulting [`WindowHandle`] must be valid and not dangling for the lifetime of
/// the handle.
///
/// Note that this guarantee only applies to *pointers*, and not any window ID types in the handle.
/// This includes Window IDs (XIDs) from X11 and the window ID for web platforms. There is no way for
/// Rust to enforce any kind of invariant on these types, since:
///
/// - For all three listed platforms, it is possible for safe code in the same process to delete
/// the window.
/// - For X11, it is possible for code in a different process to delete the window. In fact, it is
/// possible for code on a different *machine* to delete the window.
///
/// It is *also* possible for the window to be replaced with another, valid-but-different window. User
/// code should be aware of this possibility, and should be ready to soundly handle the possible error
/// conditions that can arise from this.
///
/// In addition, the window handle must not be invalidated for the duration of the [`ActiveHandle`] token.
///
/// Note that these requirements are not enforced on `HasWindowHandle`, rather, they are enforced on the
/// constructors of [`WindowHandle`]. This is because the `HasWindowHandle` trait is safe to implement.
///
/// [`winit`]: https://crates.io/crates/winit
/// [`sdl2`]: https://crates.io/crates/sdl2
/// [`wgpu`]: https://crates.io/crates/wgpu
/// [`glutin`]: https://crates.io/crates/glutin
pub trait HasWindowHandle {
/// Get a handle to the window.
fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError>;
}
impl<H: HasWindowHandle + ?Sized> HasWindowHandle for &H {
fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
(**self).window_handle()
}
}
#[cfg(feature = "alloc")]
impl<H: HasWindowHandle + ?Sized> HasWindowHandle for alloc::boxed::Box<H> {
fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
(**self).window_handle()
}
}
#[cfg(feature = "alloc")]
impl<H: HasWindowHandle + ?Sized> HasWindowHandle for alloc::rc::Rc<H> {
fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
(**self).window_handle()
}
}
#[cfg(feature = "alloc")]
impl<H: HasWindowHandle + ?Sized> HasWindowHandle for alloc::sync::Arc<H> {
fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
(**self).window_handle()
}
}
/// The handle to a window.
///
/// This is the primary return type of the [`HasWindowHandle`] trait. All *pointers* within this type
/// are guaranteed to be valid and not dangling for the lifetime of the handle. This excludes window IDs
/// like XIDs and the window ID for web platforms. See the documentation on the [`HasWindowHandle`]
/// trait for more information about these safety requirements.
///
/// This handle is guaranteed to be safe and valid. Get the underlying raw window handle with the
/// [`HasRawWindowHandle`] trait.
#[derive(Clone)]
pub struct WindowHandle<'a> {
raw: RawWindowHandle,
_active: ActiveHandle<'a>,
_marker: PhantomData<&'a *const ()>,
}
impl fmt::Debug for WindowHandle<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("WindowHandle").field(&self.raw).finish()
}
}
impl PartialEq for WindowHandle<'_> {
fn eq(&self, other: &Self) -> bool {
self.raw == other.raw
}
}
impl Eq for WindowHandle<'_> {}
impl Hash for WindowHandle<'_> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.raw.hash(state);
}
}
impl<'a> WindowHandle<'a> {
/// Borrow a `WindowHandle` from a [`RawWindowHandle`].
///
/// # Safety
///
/// The [`RawWindowHandle`] must be valid for the lifetime and the application must not be
/// suspended. The [`Active`] object that the [`ActiveHandle`] was created from must be
/// associated directly with the display that the window handle is associated with.
pub unsafe fn borrow_raw(raw: RawWindowHandle, active: ActiveHandle<'a>) -> Self {
Self {
raw,
_active: active,
_marker: PhantomData,
}
}
}
unsafe impl HasRawWindowHandle for WindowHandle<'_> {
fn raw_window_handle(&self) -> RawWindowHandle {
self.raw
}
}
impl HasWindowHandle for WindowHandle<'_> {
fn window_handle(&self) -> Result<Self, HandleError> {
Ok(self.clone())
}
}
/// The error type returned when a handle cannot be obtained.
#[derive(Debug)]
#[non_exhaustive]
pub enum HandleError {
/// The handle is not currently active.
///
/// See documentation on [`Active`] for more information.
Inactive,
}
impl fmt::Display for HandleError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Inactive => write!(f, "the handle is not currently active"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for HandleError {}
/// ```compile_fail
/// use raw_window_handle::{Active, DisplayHandle, WindowHandle};
/// fn _assert<T: Send + Sync>() {}
/// _assert::<Active<'static>>();
/// _assert::<DisplayHandle<'static>>();
/// _assert::<WindowHandle<'static>>();
/// ```
fn _not_send_or_sync() {}
#[cfg(not(any(target_os = "android", raw_window_handle_force_refcount)))]
#[cfg_attr(docsrs, doc(cfg(not(target_os = "android"))))]
mod imp {
//! We don't need to refcount the handles, so we can just use no-ops.
use core::cell::UnsafeCell;
use core::marker::PhantomData;
pub(super) struct Active;
#[derive(Clone)]
pub(super) struct ActiveHandle<'a> {
_marker: PhantomData<&'a UnsafeCell<()>>,
}
impl Active {
pub(super) const fn new() -> Self {
Self
}
pub(super) fn handle(&self) -> Option<ActiveHandle<'_>> {
// SAFETY: The handle is always active.
Some(unsafe { ActiveHandle::new_unchecked() })
}
pub(super) unsafe fn set_active(&self) {}
pub(super) fn set_inactive(&self) {}
}
impl ActiveHandle<'_> {
pub(super) unsafe fn new_unchecked() -> Self {
Self {
_marker: PhantomData,
}
}
}
impl Drop for ActiveHandle<'_> {
fn drop(&mut self) {
// Done for consistency with the refcounted version.
}
}
impl super::ActiveHandle<'_> {
/// Create a new `ActiveHandle`.
///
/// This is safe because the handle is always active.
///
/// # Example
///
/// ```
/// use raw_window_handle::ActiveHandle;
/// let handle = ActiveHandle::new();
/// ```
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
// SAFETY: The handle is always active.
unsafe { super::ActiveHandle::new_unchecked() }
}
}
}
#[cfg(any(target_os = "android", raw_window_handle_force_refcount))]
#[cfg_attr(docsrs, doc(cfg(any(target_os = "android"))))]
mod imp {
//! We need to refcount the handles, so we use an `RwLock` to do so.
use std::sync::{RwLock, RwLockReadGuard};
pub(super) struct Active {
active: RwLock<bool>,
}
pub(super) struct ActiveHandle<'a> {
inner: Option<Inner<'a>>,
}
struct Inner<'a> {
_read_guard: RwLockReadGuard<'a, bool>,
active: &'a Active,
}
impl Clone for ActiveHandle<'_> {
fn clone(&self) -> Self {
Self {
inner: self.inner.as_ref().map(|inner| Inner {
_read_guard: inner.active.active.read().unwrap(),
active: inner.active,
}),
}
}
}
impl Active {
pub(super) const fn new() -> Self {
Self {
active: RwLock::new(false),
}
}
pub(super) fn handle(&self) -> Option<ActiveHandle<'_>> {
let active = self.active.read().ok()?;
if !*active {
return None;
}
Some(ActiveHandle {
inner: Some(Inner {
_read_guard: active,
active: self,
}),
})
}
pub(super) unsafe fn set_active(&self) {
*self.active.write().unwrap() = true;
}
pub(super) fn set_inactive(&self) {
*self.active.write().unwrap() = false;
}
}
impl ActiveHandle<'_> {
pub(super) unsafe fn new_unchecked() -> Self {
Self { inner: None }
}
}
}

View file

@ -0,0 +1,46 @@
use core::ffi::c_void;
use core::ptr;
/// Raw display handle for Haiku.
///
/// ## Construction
/// ```
/// # use raw_window_handle::HaikuDisplayHandle;
/// let mut display_handle = HaikuDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HaikuDisplayHandle;
impl HaikuDisplayHandle {
pub fn empty() -> Self {
Self {}
}
}
/// Raw window handle for Haiku.
///
/// ## Construction
/// ```
/// # use raw_window_handle::HaikuWindowHandle;
/// let mut window_handle = HaikuWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HaikuWindowHandle {
/// A pointer to a BWindow object
pub b_window: *mut c_void,
/// A pointer to a BDirectWindow object that might be null
pub b_direct_window: *mut c_void,
}
impl HaikuWindowHandle {
pub fn empty() -> Self {
Self {
b_window: ptr::null_mut(),
b_direct_window: ptr::null_mut(),
}
}
}

View file

@ -0,0 +1,381 @@
#![no_std]
#![cfg_attr(docsrs, feature(doc_cfg))]
//! Interoperability library for Rust Windowing applications.
//!
//! This library provides standard types for accessing a window's platform-specific raw window
//! handle and platforms display handle. This does not provide any utilities for creating and
//! managing windows; instead, it provides a common interface that window creation libraries (e.g.
//! Winit, SDL) can use to easily talk with graphics libraries (e.g. gfx-hal).
//!
//! ## Safety guarantees
//!
//! Please see the docs of [`HasRawWindowHandle`] and [`HasRawDisplayHandle`].
//!
//! ## Platform handle initialization
//!
//! Each platform handle struct is purposefully non-exhaustive, so that additional fields may be
//! added without breaking backwards compatibility. Each struct provides an `empty` method that may
//! be used along with the struct update syntax to construct it. See each specific struct for
//! examples.
//!
//! ## Display Handles
//!
//! Some windowing systems use a separate display handle for some operations. The display usually
//! represents a connection to some display server, but it is not necessarily tied to a particular
//! window. See [`RawDisplayHandle`] for more details.
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
mod android;
mod appkit;
#[cfg(any(feature = "std", not(target_os = "android")))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(target_os = "android")))))]
mod borrowed;
mod haiku;
mod redox;
mod uikit;
mod unix;
mod web;
mod windows;
pub use android::{AndroidDisplayHandle, AndroidNdkWindowHandle};
pub use appkit::{AppKitDisplayHandle, AppKitWindowHandle};
#[cfg(any(feature = "std", not(target_os = "android")))]
pub use borrowed::{
Active, ActiveHandle, DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle,
WindowHandle,
};
pub use haiku::{HaikuDisplayHandle, HaikuWindowHandle};
pub use redox::{OrbitalDisplayHandle, OrbitalWindowHandle};
pub use uikit::{UiKitDisplayHandle, UiKitWindowHandle};
pub use unix::{
DrmDisplayHandle, DrmWindowHandle, GbmDisplayHandle, GbmWindowHandle, WaylandDisplayHandle,
WaylandWindowHandle, XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle,
};
pub use web::{WebDisplayHandle, WebWindowHandle};
pub use windows::{Win32WindowHandle, WinRtWindowHandle, WindowsDisplayHandle};
/// Window that wraps around a raw window handle.
///
/// # Safety
///
/// Users can safely assume that non-`null`/`0` fields are valid handles, and it is up to the
/// implementer of this trait to ensure that condition is upheld.
///
/// Despite that qualification, implementers should still make a best-effort attempt to fill in all
/// available fields. If an implementation doesn't, and a downstream user needs the field, it should
/// try to derive the field from other fields the implementer *does* provide via whatever methods the
/// platform provides.
///
/// The exact handles returned by `raw_window_handle` must remain consistent between multiple calls
/// to `raw_window_handle` as long as not indicated otherwise by platform specific events.
pub unsafe trait HasRawWindowHandle {
fn raw_window_handle(&self) -> RawWindowHandle;
}
unsafe impl<'a, T: HasRawWindowHandle + ?Sized> HasRawWindowHandle for &'a T {
fn raw_window_handle(&self) -> RawWindowHandle {
(*self).raw_window_handle()
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
unsafe impl<T: HasRawWindowHandle + ?Sized> HasRawWindowHandle for alloc::rc::Rc<T> {
fn raw_window_handle(&self) -> RawWindowHandle {
(**self).raw_window_handle()
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
unsafe impl<T: HasRawWindowHandle + ?Sized> HasRawWindowHandle for alloc::sync::Arc<T> {
fn raw_window_handle(&self) -> RawWindowHandle {
(**self).raw_window_handle()
}
}
/// A window handle for a particular windowing system.
///
/// Each variant contains a struct with fields specific to that windowing system
/// (e.g. [`Win32WindowHandle`] will include a [HWND], [`WaylandWindowHandle`] uses [wl_surface],
/// etc.)
///
/// [HWND]: https://learn.microsoft.com/en-us/windows/win32/winmsg/about-windows#window-handle
/// [wl_surface]: https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_surface
///
/// # Variant Availability
///
/// Note that all variants are present on all targets (none are disabled behind
/// `#[cfg]`s), but see the "Availability Hints" section on each variant for
/// some hints on where this variant might be expected.
///
/// Note that these "Availability Hints" are not normative. That is to say, a
/// [`HasRawWindowHandle`] implementor is completely allowed to return something
/// unexpected. (For example, it's legal for someone to return a
/// [`RawWindowHandle::Xlib`] on macOS, it would just be weird, and probably
/// requires something like XQuartz be used).
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RawWindowHandle {
/// A raw window handle for UIKit (Apple's non-macOS windowing library).
///
/// ## Availability Hints
/// This variant is likely to be used on iOS, tvOS, (in theory) watchOS, and
/// Mac Catalyst (`$arch-apple-ios-macabi` targets, which can notably use
/// UIKit *or* AppKit), as these are the targets that (currently) support
/// UIKit.
UiKit(UiKitWindowHandle),
/// A raw window handle for AppKit.
///
/// ## Availability Hints
/// This variant is likely to be used on macOS, although Mac Catalyst
/// (`$arch-apple-ios-macabi` targets, which can notably use UIKit *or*
/// AppKit) can also use it despite being `target_os = "ios"`.
AppKit(AppKitWindowHandle),
/// A raw window handle for the Redox operating system.
///
/// ## Availability Hints
/// This variant is used by the Orbital Windowing System in the Redox
/// operating system.
Orbital(OrbitalWindowHandle),
/// A raw window handle for Xlib.
///
/// ## Availability Hints
/// This variant is likely to show up anywhere someone manages to get X11
/// working that Xlib can be built for, which is to say, most (but not all)
/// Unix systems.
Xlib(XlibWindowHandle),
/// A raw window handle for Xcb.
///
/// ## Availability Hints
/// This variant is likely to show up anywhere someone manages to get X11
/// working that XCB can be built for, which is to say, most (but not all)
/// Unix systems.
Xcb(XcbWindowHandle),
/// A raw window handle for Wayland.
///
/// ## Availability Hints
/// This variant should be expected anywhere Wayland works, which is
/// currently some subset of unix systems.
Wayland(WaylandWindowHandle),
/// A raw window handle for the Linux Kernel Mode Set/Direct Rendering Manager
///
/// ## Availability Hints
/// This variant is used on Linux when neither X nor Wayland are available
Drm(DrmWindowHandle),
/// A raw window handle for the Linux Generic Buffer Manager.
///
/// ## Availability Hints
/// This variant is present regardless of windowing backend and likely to be used with
/// EGL_MESA_platfrom_gbm or EGL_KHR_platfrom_gbm.
Gbm(GbmWindowHandle),
/// A raw window handle for Win32.
///
/// ## Availability Hints
/// This variant is used on Windows systems.
Win32(Win32WindowHandle),
/// A raw window handle for WinRT.
///
/// ## Availability Hints
/// This variant is used on Windows systems.
WinRt(WinRtWindowHandle),
/// A raw window handle for the Web.
///
/// ## Availability Hints
/// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
Web(WebWindowHandle),
/// A raw window handle for Android NDK.
///
/// ## Availability Hints
/// This variant is used on Android targets.
AndroidNdk(AndroidNdkWindowHandle),
/// A raw window handle for Haiku.
///
/// ## Availability Hints
/// This variant is used on HaikuOS.
Haiku(HaikuWindowHandle),
}
/// Display that wraps around a raw display handle.
///
/// # Safety
///
/// Users can safely assume that non-`null`/`0` fields are valid handles, and it is up to the
/// implementer of this trait to ensure that condition is upheld.
///
/// Despite that qualification, implementers should still make a best-effort attempt to fill in all
/// available fields. If an implementation doesn't, and a downstream user needs the field, it should
/// try to derive the field from other fields the implementer *does* provide via whatever methods the
/// platform provides.
///
/// The exact handles returned by `raw_display_handle` must remain consistent between multiple calls
/// to `raw_display_handle` as long as not indicated otherwise by platform specific events.
pub unsafe trait HasRawDisplayHandle {
fn raw_display_handle(&self) -> RawDisplayHandle;
}
unsafe impl<'a, T: HasRawDisplayHandle + ?Sized> HasRawDisplayHandle for &'a T {
fn raw_display_handle(&self) -> RawDisplayHandle {
(*self).raw_display_handle()
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
unsafe impl<T: HasRawDisplayHandle + ?Sized> HasRawDisplayHandle for alloc::rc::Rc<T> {
fn raw_display_handle(&self) -> RawDisplayHandle {
(**self).raw_display_handle()
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
unsafe impl<T: HasRawDisplayHandle + ?Sized> HasRawDisplayHandle for alloc::sync::Arc<T> {
fn raw_display_handle(&self) -> RawDisplayHandle {
(**self).raw_display_handle()
}
}
/// A display server handle for a particular windowing system.
///
/// The display usually represents a connection to some display server, but it is not necessarily
/// tied to a particular window. Some APIs can use the display handle without ever creating a window
/// handle (e.g. offscreen rendering, headless event handling).
///
/// Each variant contains a struct with fields specific to that windowing system
/// (e.g. [`XlibDisplayHandle`] contains a [Display] connection to an X Server,
/// [`WaylandDisplayHandle`] uses [wl_display] to connect to a compositor). Not all windowing
/// systems have a separate display handle (or they haven't been implemented yet) and their variants
/// contain empty structs.
///
/// [Display]: https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#Display_Functions
/// [wl_display]: https://wayland.freedesktop.org/docs/html/apb.html#Client-classwl__display
///
/// # Variant Availability
///
/// Note that all variants are present on all targets (none are disabled behind
/// `#[cfg]`s), but see the "Availability Hints" section on each variant for
/// some hints on where this variant might be expected.
///
/// Note that these "Availability Hints" are not normative. That is to say, a
/// [`HasRawDisplayHandle`] implementor is completely allowed to return something
/// unexpected. (For example, it's legal for someone to return a
/// [`RawDisplayHandle::Xlib`] on macOS, it would just be weird, and probably
/// requires something like XQuartz be used).
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RawDisplayHandle {
/// A raw display handle for UIKit (Apple's non-macOS windowing library).
///
/// ## Availability Hints
/// This variant is likely to be used on iOS, tvOS, (in theory) watchOS, and
/// Mac Catalyst (`$arch-apple-ios-macabi` targets, which can notably use
/// UIKit *or* AppKit), as these are the targets that (currently) support
/// UIKit.
UiKit(UiKitDisplayHandle),
/// A raw display handle for AppKit.
///
/// ## Availability Hints
/// This variant is likely to be used on macOS, although Mac Catalyst
/// (`$arch-apple-ios-macabi` targets, which can notably use UIKit *or*
/// AppKit) can also use it despite being `target_os = "ios"`.
AppKit(AppKitDisplayHandle),
/// A raw display handle for the Redox operating system.
///
/// ## Availability Hints
/// This variant is used by the Orbital Windowing System in the Redox
/// operating system.
Orbital(OrbitalDisplayHandle),
/// A raw display handle for Xlib.
///
/// ## Availability Hints
/// This variant is likely to show up anywhere someone manages to get X11
/// working that Xlib can be built for, which is to say, most (but not all)
/// Unix systems.
Xlib(XlibDisplayHandle),
/// A raw display handle for Xcb.
///
/// ## Availability Hints
/// This variant is likely to show up anywhere someone manages to get X11
/// working that XCB can be built for, which is to say, most (but not all)
/// Unix systems.
Xcb(XcbDisplayHandle),
/// A raw display handle for Wayland.
///
/// ## Availability Hints
/// This variant should be expected anywhere Wayland works, which is
/// currently some subset of unix systems.
Wayland(WaylandDisplayHandle),
/// A raw display handle for the Linux Kernel Mode Set/Direct Rendering Manager
///
/// ## Availability Hints
/// This variant is used on Linux when neither X nor Wayland are available
Drm(DrmDisplayHandle),
/// A raw display handle for the Linux Generic Buffer Manager.
///
/// ## Availability Hints
/// This variant is present regardless of windowing backend and likely to be used with
/// EGL_MESA_platfrom_gbm or EGL_KHR_platfrom_gbm.
Gbm(GbmDisplayHandle),
/// A raw display handle for Win32.
///
/// ## Availability Hints
/// This variant is used on Windows systems.
Windows(WindowsDisplayHandle),
/// A raw display handle for the Web.
///
/// ## Availability Hints
/// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
Web(WebDisplayHandle),
/// A raw display handle for Android NDK.
///
/// ## Availability Hints
/// This variant is used on Android targets.
Android(AndroidDisplayHandle),
/// A raw display handle for Haiku.
///
/// ## Availability Hints
/// This variant is used on HaikuOS.
Haiku(HaikuDisplayHandle),
}
macro_rules! from_impl {
($($to:ident, $enum:ident, $from:ty)*) => ($(
impl From<$from> for $to {
fn from(value: $from) -> Self {
$to::$enum(value)
}
}
)*)
}
from_impl!(RawDisplayHandle, UiKit, UiKitDisplayHandle);
from_impl!(RawDisplayHandle, AppKit, AppKitDisplayHandle);
from_impl!(RawDisplayHandle, Orbital, OrbitalDisplayHandle);
from_impl!(RawDisplayHandle, Xlib, XlibDisplayHandle);
from_impl!(RawDisplayHandle, Xcb, XcbDisplayHandle);
from_impl!(RawDisplayHandle, Wayland, WaylandDisplayHandle);
from_impl!(RawDisplayHandle, Drm, DrmDisplayHandle);
from_impl!(RawDisplayHandle, Gbm, GbmDisplayHandle);
from_impl!(RawDisplayHandle, Windows, WindowsDisplayHandle);
from_impl!(RawDisplayHandle, Web, WebDisplayHandle);
from_impl!(RawDisplayHandle, Android, AndroidDisplayHandle);
from_impl!(RawDisplayHandle, Haiku, HaikuDisplayHandle);
from_impl!(RawWindowHandle, UiKit, UiKitWindowHandle);
from_impl!(RawWindowHandle, AppKit, AppKitWindowHandle);
from_impl!(RawWindowHandle, Orbital, OrbitalWindowHandle);
from_impl!(RawWindowHandle, Xlib, XlibWindowHandle);
from_impl!(RawWindowHandle, Xcb, XcbWindowHandle);
from_impl!(RawWindowHandle, Wayland, WaylandWindowHandle);
from_impl!(RawWindowHandle, Drm, DrmWindowHandle);
from_impl!(RawWindowHandle, Gbm, GbmWindowHandle);
from_impl!(RawWindowHandle, Win32, Win32WindowHandle);
from_impl!(RawWindowHandle, WinRt, WinRtWindowHandle);
from_impl!(RawWindowHandle, Web, WebWindowHandle);
from_impl!(RawWindowHandle, AndroidNdk, AndroidNdkWindowHandle);
from_impl!(RawWindowHandle, Haiku, HaikuWindowHandle);

View file

@ -0,0 +1,43 @@
use core::ffi::c_void;
use core::ptr;
/// Raw display handle for the Redox operating system.
///
/// ## Construction
/// ```
/// # use raw_window_handle::OrbitalDisplayHandle;
/// let mut display_handle = OrbitalDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OrbitalDisplayHandle;
impl OrbitalDisplayHandle {
pub fn empty() -> Self {
Self {}
}
}
/// Raw window handle for the Redox operating system.
///
/// ## Construction
/// ```
/// # use raw_window_handle::OrbitalWindowHandle;
/// let mut window_handle = OrbitalWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OrbitalWindowHandle {
/// A pointer to an orbclient window.
pub window: *mut c_void,
}
impl OrbitalWindowHandle {
pub fn empty() -> Self {
Self {
window: ptr::null_mut(),
}
}
}

View file

@ -0,0 +1,49 @@
use core::ffi::c_void;
use core::ptr;
/// Raw display handle for UIKit.
///
/// ## Construction
/// ```
/// # use raw_window_handle::UiKitDisplayHandle;
/// let mut display_handle = UiKitDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct UiKitDisplayHandle;
impl UiKitDisplayHandle {
pub fn empty() -> Self {
Self {}
}
}
/// Raw window handle for UIKit.
///
/// ## Construction
/// ```
/// # use raw_window_handle::UiKitWindowHandle;
/// let mut window_handle = UiKitWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct UiKitWindowHandle {
/// A pointer to an `UIWindow` object.
pub ui_window: *mut c_void,
/// A pointer to an `UIView` object.
pub ui_view: *mut c_void,
/// A pointer to an `UIViewController` object.
pub ui_view_controller: *mut c_void,
}
impl UiKitWindowHandle {
pub fn empty() -> Self {
Self {
ui_window: ptr::null_mut(),
ui_view: ptr::null_mut(),
ui_view_controller: ptr::null_mut(),
}
}
}

View file

@ -0,0 +1,250 @@
use core::ffi::{c_int, c_ulong, c_void};
use core::ptr;
/// Raw display handle for Xlib.
///
/// ## Construction
/// ```
/// # use raw_window_handle::XlibDisplayHandle;
/// let display_handle = XlibDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct XlibDisplayHandle {
/// A pointer to an Xlib `Display`.
pub display: *mut c_void,
/// An X11 screen to use with this display handle.
///
/// Note, that X11 could have multiple screens, however
/// graphics APIs could work only with one screen at the time,
/// given that multiple screens usually reside on different GPUs.
pub screen: c_int,
}
/// Raw window handle for Xlib.
///
/// ## Construction
/// ```
/// # use raw_window_handle::XlibWindowHandle;
/// let window_handle = XlibWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct XlibWindowHandle {
/// An Xlib `Window`.
pub window: c_ulong,
/// An Xlib visual ID, or 0 if unknown.
pub visual_id: c_ulong,
}
/// Raw display handle for Xcb.
///
/// ## Construction
/// ```
/// # use raw_window_handle::XcbDisplayHandle;
/// let display_handle = XcbDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct XcbDisplayHandle {
/// A pointer to an X server `xcb_connection_t`.
pub connection: *mut c_void,
/// An X11 screen to use with this display handle.
///
/// Note, that X11 could have multiple screens, however
/// graphics APIs could work only with one screen at the time,
/// given that multiple screens usually reside on different GPUs.
pub screen: c_int,
}
/// Raw window handle for Xcb.
///
/// ## Construction
/// ```
/// # use raw_window_handle::XcbWindowHandle;
/// let window_handle = XcbWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct XcbWindowHandle {
/// An X11 `xcb_window_t`.
pub window: u32, // Based on xproto.h
/// An X11 `xcb_visualid_t`, or 0 if unknown.
pub visual_id: u32,
}
/// Raw display handle for Wayland.
///
/// ## Construction
/// ```
/// # use raw_window_handle::WaylandDisplayHandle;
/// let display_handle = WaylandDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WaylandDisplayHandle {
/// A pointer to a `wl_display`.
pub display: *mut c_void,
}
/// Raw window handle for Wayland.
///
/// ## Construction
/// ```
/// # use raw_window_handle::WaylandWindowHandle;
/// let window_handle = WaylandWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WaylandWindowHandle {
/// A pointer to a `wl_surface`.
pub surface: *mut c_void,
}
/// Raw display handle for the Linux Kernel Mode Set/Direct Rendering Manager.
///
/// ## Construction
/// ```
/// # use raw_window_handle::DrmDisplayHandle;
/// let display_handle = DrmDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DrmDisplayHandle {
/// The drm file descriptor.
pub fd: i32,
}
/// Raw window handle for the Linux Kernel Mode Set/Direct Rendering Manager.
///
/// ## Construction
/// ```
/// # use raw_window_handle::DrmWindowHandle;
/// let handle = DrmWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DrmWindowHandle {
/// The primary drm plane handle.
pub plane: u32,
}
/// Raw display handle for the Linux Generic Buffer Manager.
///
/// ## Construction
/// ```
/// # use raw_window_handle::GbmDisplayHandle;
/// let display_handle = GbmDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct GbmDisplayHandle {
/// The gbm device.
pub gbm_device: *mut c_void,
}
/// Raw window handle for the Linux Generic Buffer Manager.
///
/// ## Construction
/// ```
/// # use raw_window_handle::GbmWindowHandle;
/// let handle = GbmWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct GbmWindowHandle {
/// The gbm surface.
pub gbm_surface: *mut c_void,
}
impl XlibDisplayHandle {
pub fn empty() -> Self {
Self {
display: ptr::null_mut(),
screen: 0,
}
}
}
impl XlibWindowHandle {
pub fn empty() -> Self {
Self {
window: 0,
visual_id: 0,
}
}
}
impl XcbDisplayHandle {
pub fn empty() -> Self {
Self {
connection: ptr::null_mut(),
screen: 0,
}
}
}
impl XcbWindowHandle {
pub fn empty() -> Self {
Self {
window: 0,
visual_id: 0,
}
}
}
impl WaylandDisplayHandle {
pub fn empty() -> Self {
Self {
display: ptr::null_mut(),
}
}
}
impl WaylandWindowHandle {
pub fn empty() -> Self {
Self {
surface: ptr::null_mut(),
}
}
}
impl DrmDisplayHandle {
pub fn empty() -> Self {
Self { fd: 0 }
}
}
impl DrmWindowHandle {
pub fn empty() -> Self {
Self { plane: 0 }
}
}
impl GbmDisplayHandle {
pub fn empty() -> Self {
Self {
gbm_device: ptr::null_mut(),
}
}
}
impl GbmWindowHandle {
pub fn empty() -> Self {
Self {
gbm_surface: ptr::null_mut(),
}
}
}

View file

@ -0,0 +1,45 @@
/// Raw display handle for the Web.
///
/// ## Construction
/// ```
/// # use raw_window_handle::WebDisplayHandle;
/// let mut display_handle = WebDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WebDisplayHandle;
impl WebDisplayHandle {
pub fn empty() -> Self {
Self {}
}
}
/// Raw window handle for the Web.
///
/// ## Construction
/// ```
/// # use raw_window_handle::WebWindowHandle;
/// let mut window_handle = WebWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WebWindowHandle {
/// An ID value inserted into the [data attributes] of the canvas element as '`raw-handle`'.
///
/// When accessing from JS, the attribute will automatically be called `rawHandle`.
///
/// Each canvas created by the windowing system should be assigned their own unique ID.
/// 0 should be reserved for invalid / null IDs.
///
/// [data attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*
pub id: u32,
}
impl WebWindowHandle {
pub fn empty() -> Self {
Self { id: 0 }
}
}

View file

@ -0,0 +1,71 @@
use core::ffi::c_void;
use core::ptr;
/// Raw display handle for Windows.
///
/// It could be used regardless of Windows window backend.
///
/// ## Construction
/// ```
/// # use raw_window_handle::WindowsDisplayHandle;
/// let mut display_handle = WindowsDisplayHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WindowsDisplayHandle;
impl WindowsDisplayHandle {
pub fn empty() -> Self {
Self
}
}
/// Raw window handle for Win32.
///
/// ## Construction
/// ```
/// # use raw_window_handle::Win32WindowHandle;
/// let mut window_handle = Win32WindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Win32WindowHandle {
/// A Win32 `HWND` handle.
pub hwnd: *mut c_void,
/// The `HINSTANCE` associated with this type's `HWND`.
pub hinstance: *mut c_void,
}
impl Win32WindowHandle {
pub fn empty() -> Self {
Self {
hwnd: ptr::null_mut(),
hinstance: ptr::null_mut(),
}
}
}
/// Raw window handle for WinRT.
///
/// ## Construction
/// ```
/// # use raw_window_handle::WinRtWindowHandle;
/// let mut window_handle = WinRtWindowHandle::empty();
/// /* set fields */
/// ```
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct WinRtWindowHandle {
/// A WinRT `CoreWindow` handle.
pub core_window: *mut c_void,
}
impl WinRtWindowHandle {
pub fn empty() -> Self {
Self {
core_window: ptr::null_mut(),
}
}
}