1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3
4//! Interoperability library for Rust Windowing applications.
5//!
6//! This library provides standard types for accessing a window's platform-specific raw window
7//! handle and platforms display handle. This does not provide any utilities for creating and
8//! managing windows; instead, it provides a common interface that window creation libraries (e.g.
9//! Winit, SDL) can use to easily talk with graphics libraries (e.g. gfx-hal).
10//!
11//! ## Safety guarantees
12//!
13//! Please see the docs of [`HasRawWindowHandle`] and [`HasRawDisplayHandle`].
14//!
15//! ## Platform handle initialization
16//!
17//! Each platform handle struct is purposefully non-exhaustive, so that additional fields may be
18//! added without breaking backwards compatibility. Each struct provides an `empty` method that may
19//! be used along with the struct update syntax to construct it. See each specific struct for
20//! examples.
21//!
22//! ## Display Handles
23//!
24//! Some windowing systems use a separate display handle for some operations. The display usually
25//! represents a connection to some display server, but it is not necessarily tied to a particular
26//! window. See [`RawDisplayHandle`] for more details.
27
28#[cfg(feature = "alloc")]
29extern crate alloc;
30
31#[cfg(feature = "std")]
32extern crate std;
33
34mod android;
35mod appkit;
36#[cfg(any(feature = "std", not(target_os = "android")))]
37#[cfg_attr(docsrs, doc(cfg(any(feature = "std", not(target_os = "android")))))]
38mod borrowed;
39mod haiku;
40mod redox;
41mod uikit;
42mod unix;
43mod web;
44mod windows;
45
46pub use android::{AndroidDisplayHandle, AndroidNdkWindowHandle};
47pub use appkit::{AppKitDisplayHandle, AppKitWindowHandle};
48#[cfg(any(feature = "std", not(target_os = "android")))]
49pub use borrowed::{
50 Active, ActiveHandle, DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle,
51 WindowHandle,
52};
53pub use haiku::{HaikuDisplayHandle, HaikuWindowHandle};
54pub use redox::{OrbitalDisplayHandle, OrbitalWindowHandle};
55pub use uikit::{UiKitDisplayHandle, UiKitWindowHandle};
56pub use unix::{
57 DrmDisplayHandle, DrmWindowHandle, GbmDisplayHandle, GbmWindowHandle, WaylandDisplayHandle,
58 WaylandWindowHandle, XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle,
59};
60pub use web::{WebDisplayHandle, WebWindowHandle};
61pub use windows::{Win32WindowHandle, WinRtWindowHandle, WindowsDisplayHandle};
62
63/// Window that wraps around a raw window handle.
64///
65/// # Safety
66///
67/// Users can safely assume that non-`null`/`0` fields are valid handles, and it is up to the
68/// implementer of this trait to ensure that condition is upheld.
69///
70/// Despite that qualification, implementers should still make a best-effort attempt to fill in all
71/// available fields. If an implementation doesn't, and a downstream user needs the field, it should
72/// try to derive the field from other fields the implementer *does* provide via whatever methods the
73/// platform provides.
74///
75/// The exact handles returned by `raw_window_handle` must remain consistent between multiple calls
76/// to `raw_window_handle` as long as not indicated otherwise by platform specific events.
77pub unsafe trait HasRawWindowHandle {
78 fn raw_window_handle(&self) -> RawWindowHandle;
79}
80
81unsafe impl<'a, T: HasRawWindowHandle + ?Sized> HasRawWindowHandle for &'a T {
82 fn raw_window_handle(&self) -> RawWindowHandle {
83 (*self).raw_window_handle()
84 }
85}
86#[cfg(feature = "alloc")]
87#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
88unsafe impl<T: HasRawWindowHandle + ?Sized> HasRawWindowHandle for alloc::rc::Rc<T> {
89 fn raw_window_handle(&self) -> RawWindowHandle {
90 (**self).raw_window_handle()
91 }
92}
93#[cfg(feature = "alloc")]
94#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
95unsafe impl<T: HasRawWindowHandle + ?Sized> HasRawWindowHandle for alloc::sync::Arc<T> {
96 fn raw_window_handle(&self) -> RawWindowHandle {
97 (**self).raw_window_handle()
98 }
99}
100
101/// A window handle for a particular windowing system.
102///
103/// Each variant contains a struct with fields specific to that windowing system
104/// (e.g. [`Win32WindowHandle`] will include a [HWND], [`WaylandWindowHandle`] uses [wl_surface],
105/// etc.)
106///
107/// [HWND]: https://learn.microsoft.com/en-us/windows/win32/winmsg/about-windows#window-handle
108/// [wl_surface]: https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_surface
109///
110/// # Variant Availability
111///
112/// Note that all variants are present on all targets (none are disabled behind
113/// `#[cfg]`s), but see the "Availability Hints" section on each variant for
114/// some hints on where this variant might be expected.
115///
116/// Note that these "Availability Hints" are not normative. That is to say, a
117/// [`HasRawWindowHandle`] implementor is completely allowed to return something
118/// unexpected. (For example, it's legal for someone to return a
119/// [`RawWindowHandle::Xlib`] on macOS, it would just be weird, and probably
120/// requires something like XQuartz be used).
121#[non_exhaustive]
122#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
123pub enum RawWindowHandle {
124 /// A raw window handle for UIKit (Apple's non-macOS windowing library).
125 ///
126 /// ## Availability Hints
127 /// This variant is likely to be used on iOS, tvOS, (in theory) watchOS, and
128 /// Mac Catalyst (`$arch-apple-ios-macabi` targets, which can notably use
129 /// UIKit *or* AppKit), as these are the targets that (currently) support
130 /// UIKit.
131 UiKit(UiKitWindowHandle),
132 /// A raw window handle for AppKit.
133 ///
134 /// ## Availability Hints
135 /// This variant is likely to be used on macOS, although Mac Catalyst
136 /// (`$arch-apple-ios-macabi` targets, which can notably use UIKit *or*
137 /// AppKit) can also use it despite being `target_os = "ios"`.
138 AppKit(AppKitWindowHandle),
139 /// A raw window handle for the Redox operating system.
140 ///
141 /// ## Availability Hints
142 /// This variant is used by the Orbital Windowing System in the Redox
143 /// operating system.
144 Orbital(OrbitalWindowHandle),
145 /// A raw window handle for Xlib.
146 ///
147 /// ## Availability Hints
148 /// This variant is likely to show up anywhere someone manages to get X11
149 /// working that Xlib can be built for, which is to say, most (but not all)
150 /// Unix systems.
151 Xlib(XlibWindowHandle),
152 /// A raw window handle for Xcb.
153 ///
154 /// ## Availability Hints
155 /// This variant is likely to show up anywhere someone manages to get X11
156 /// working that XCB can be built for, which is to say, most (but not all)
157 /// Unix systems.
158 Xcb(XcbWindowHandle),
159 /// A raw window handle for Wayland.
160 ///
161 /// ## Availability Hints
162 /// This variant should be expected anywhere Wayland works, which is
163 /// currently some subset of unix systems.
164 Wayland(WaylandWindowHandle),
165 /// A raw window handle for the Linux Kernel Mode Set/Direct Rendering Manager
166 ///
167 /// ## Availability Hints
168 /// This variant is used on Linux when neither X nor Wayland are available
169 Drm(DrmWindowHandle),
170 /// A raw window handle for the Linux Generic Buffer Manager.
171 ///
172 /// ## Availability Hints
173 /// This variant is present regardless of windowing backend and likely to be used with
174 /// EGL_MESA_platfrom_gbm or EGL_KHR_platfrom_gbm.
175 Gbm(GbmWindowHandle),
176 /// A raw window handle for Win32.
177 ///
178 /// ## Availability Hints
179 /// This variant is used on Windows systems.
180 Win32(Win32WindowHandle),
181 /// A raw window handle for WinRT.
182 ///
183 /// ## Availability Hints
184 /// This variant is used on Windows systems.
185 WinRt(WinRtWindowHandle),
186 /// A raw window handle for the Web.
187 ///
188 /// ## Availability Hints
189 /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
190 Web(WebWindowHandle),
191 /// A raw window handle for Android NDK.
192 ///
193 /// ## Availability Hints
194 /// This variant is used on Android targets.
195 AndroidNdk(AndroidNdkWindowHandle),
196 /// A raw window handle for Haiku.
197 ///
198 /// ## Availability Hints
199 /// This variant is used on HaikuOS.
200 Haiku(HaikuWindowHandle),
201}
202
203/// Display that wraps around a raw display handle.
204///
205/// # Safety
206///
207/// Users can safely assume that non-`null`/`0` fields are valid handles, and it is up to the
208/// implementer of this trait to ensure that condition is upheld.
209///
210/// Despite that qualification, implementers should still make a best-effort attempt to fill in all
211/// available fields. If an implementation doesn't, and a downstream user needs the field, it should
212/// try to derive the field from other fields the implementer *does* provide via whatever methods the
213/// platform provides.
214///
215/// The exact handles returned by `raw_display_handle` must remain consistent between multiple calls
216/// to `raw_display_handle` as long as not indicated otherwise by platform specific events.
217pub unsafe trait HasRawDisplayHandle {
218 fn raw_display_handle(&self) -> RawDisplayHandle;
219}
220
221unsafe impl<'a, T: HasRawDisplayHandle + ?Sized> HasRawDisplayHandle for &'a T {
222 fn raw_display_handle(&self) -> RawDisplayHandle {
223 (*self).raw_display_handle()
224 }
225}
226
227#[cfg(feature = "alloc")]
228#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
229unsafe impl<T: HasRawDisplayHandle + ?Sized> HasRawDisplayHandle for alloc::rc::Rc<T> {
230 fn raw_display_handle(&self) -> RawDisplayHandle {
231 (**self).raw_display_handle()
232 }
233}
234
235#[cfg(feature = "alloc")]
236#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
237unsafe impl<T: HasRawDisplayHandle + ?Sized> HasRawDisplayHandle for alloc::sync::Arc<T> {
238 fn raw_display_handle(&self) -> RawDisplayHandle {
239 (**self).raw_display_handle()
240 }
241}
242
243/// A display server handle for a particular windowing system.
244///
245/// The display usually represents a connection to some display server, but it is not necessarily
246/// tied to a particular window. Some APIs can use the display handle without ever creating a window
247/// handle (e.g. offscreen rendering, headless event handling).
248///
249/// Each variant contains a struct with fields specific to that windowing system
250/// (e.g. [`XlibDisplayHandle`] contains a [Display] connection to an X Server,
251/// [`WaylandDisplayHandle`] uses [wl_display] to connect to a compositor). Not all windowing
252/// systems have a separate display handle (or they haven't been implemented yet) and their variants
253/// contain empty structs.
254///
255/// [Display]: https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#Display_Functions
256/// [wl_display]: https://wayland.freedesktop.org/docs/html/apb.html#Client-classwl__display
257///
258/// # Variant Availability
259///
260/// Note that all variants are present on all targets (none are disabled behind
261/// `#[cfg]`s), but see the "Availability Hints" section on each variant for
262/// some hints on where this variant might be expected.
263///
264/// Note that these "Availability Hints" are not normative. That is to say, a
265/// [`HasRawDisplayHandle`] implementor is completely allowed to return something
266/// unexpected. (For example, it's legal for someone to return a
267/// [`RawDisplayHandle::Xlib`] on macOS, it would just be weird, and probably
268/// requires something like XQuartz be used).
269#[non_exhaustive]
270#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
271pub enum RawDisplayHandle {
272 /// A raw display handle for UIKit (Apple's non-macOS windowing library).
273 ///
274 /// ## Availability Hints
275 /// This variant is likely to be used on iOS, tvOS, (in theory) watchOS, and
276 /// Mac Catalyst (`$arch-apple-ios-macabi` targets, which can notably use
277 /// UIKit *or* AppKit), as these are the targets that (currently) support
278 /// UIKit.
279 UiKit(UiKitDisplayHandle),
280 /// A raw display handle for AppKit.
281 ///
282 /// ## Availability Hints
283 /// This variant is likely to be used on macOS, although Mac Catalyst
284 /// (`$arch-apple-ios-macabi` targets, which can notably use UIKit *or*
285 /// AppKit) can also use it despite being `target_os = "ios"`.
286 AppKit(AppKitDisplayHandle),
287 /// A raw display handle for the Redox operating system.
288 ///
289 /// ## Availability Hints
290 /// This variant is used by the Orbital Windowing System in the Redox
291 /// operating system.
292 Orbital(OrbitalDisplayHandle),
293 /// A raw display handle for Xlib.
294 ///
295 /// ## Availability Hints
296 /// This variant is likely to show up anywhere someone manages to get X11
297 /// working that Xlib can be built for, which is to say, most (but not all)
298 /// Unix systems.
299 Xlib(XlibDisplayHandle),
300 /// A raw display handle for Xcb.
301 ///
302 /// ## Availability Hints
303 /// This variant is likely to show up anywhere someone manages to get X11
304 /// working that XCB can be built for, which is to say, most (but not all)
305 /// Unix systems.
306 Xcb(XcbDisplayHandle),
307 /// A raw display handle for Wayland.
308 ///
309 /// ## Availability Hints
310 /// This variant should be expected anywhere Wayland works, which is
311 /// currently some subset of unix systems.
312 Wayland(WaylandDisplayHandle),
313 /// A raw display handle for the Linux Kernel Mode Set/Direct Rendering Manager
314 ///
315 /// ## Availability Hints
316 /// This variant is used on Linux when neither X nor Wayland are available
317 Drm(DrmDisplayHandle),
318 /// A raw display handle for the Linux Generic Buffer Manager.
319 ///
320 /// ## Availability Hints
321 /// This variant is present regardless of windowing backend and likely to be used with
322 /// EGL_MESA_platfrom_gbm or EGL_KHR_platfrom_gbm.
323 Gbm(GbmDisplayHandle),
324 /// A raw display handle for Win32.
325 ///
326 /// ## Availability Hints
327 /// This variant is used on Windows systems.
328 Windows(WindowsDisplayHandle),
329 /// A raw display handle for the Web.
330 ///
331 /// ## Availability Hints
332 /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
333 Web(WebDisplayHandle),
334 /// A raw display handle for Android NDK.
335 ///
336 /// ## Availability Hints
337 /// This variant is used on Android targets.
338 Android(AndroidDisplayHandle),
339 /// A raw display handle for Haiku.
340 ///
341 /// ## Availability Hints
342 /// This variant is used on HaikuOS.
343 Haiku(HaikuDisplayHandle),
344}
345
346macro_rules! from_impl {
347 ($($to:ident, $enum:ident, $from:ty)*) => ($(
348 impl From<$from> for $to {
349 fn from(value: $from) -> Self {
350 $to::$enum(value)
351 }
352 }
353 )*)
354}
355
356from_impl!(RawDisplayHandle, UiKit, UiKitDisplayHandle);
357from_impl!(RawDisplayHandle, AppKit, AppKitDisplayHandle);
358from_impl!(RawDisplayHandle, Orbital, OrbitalDisplayHandle);
359from_impl!(RawDisplayHandle, Xlib, XlibDisplayHandle);
360from_impl!(RawDisplayHandle, Xcb, XcbDisplayHandle);
361from_impl!(RawDisplayHandle, Wayland, WaylandDisplayHandle);
362from_impl!(RawDisplayHandle, Drm, DrmDisplayHandle);
363from_impl!(RawDisplayHandle, Gbm, GbmDisplayHandle);
364from_impl!(RawDisplayHandle, Windows, WindowsDisplayHandle);
365from_impl!(RawDisplayHandle, Web, WebDisplayHandle);
366from_impl!(RawDisplayHandle, Android, AndroidDisplayHandle);
367from_impl!(RawDisplayHandle, Haiku, HaikuDisplayHandle);
368
369from_impl!(RawWindowHandle, UiKit, UiKitWindowHandle);
370from_impl!(RawWindowHandle, AppKit, AppKitWindowHandle);
371from_impl!(RawWindowHandle, Orbital, OrbitalWindowHandle);
372from_impl!(RawWindowHandle, Xlib, XlibWindowHandle);
373from_impl!(RawWindowHandle, Xcb, XcbWindowHandle);
374from_impl!(RawWindowHandle, Wayland, WaylandWindowHandle);
375from_impl!(RawWindowHandle, Drm, DrmWindowHandle);
376from_impl!(RawWindowHandle, Gbm, GbmWindowHandle);
377from_impl!(RawWindowHandle, Win32, Win32WindowHandle);
378from_impl!(RawWindowHandle, WinRt, WinRtWindowHandle);
379from_impl!(RawWindowHandle, Web, WebWindowHandle);
380from_impl!(RawWindowHandle, AndroidNdk, AndroidNdkWindowHandle);
381from_impl!(RawWindowHandle, Haiku, HaikuWindowHandle);
382