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" )] |
29 | extern crate alloc; |
30 | |
31 | #[cfg (feature = "std" )] |
32 | extern crate std; |
33 | |
34 | mod android; |
35 | mod appkit; |
36 | #[cfg (any(feature = "std" , not(target_os = "android" )))] |
37 | #[cfg_attr (docsrs, doc(cfg(any(feature = "std" , not(target_os = "android" )))))] |
38 | mod borrowed; |
39 | mod haiku; |
40 | mod redox; |
41 | mod uikit; |
42 | mod unix; |
43 | mod web; |
44 | mod windows; |
45 | |
46 | pub use android::{AndroidDisplayHandle, AndroidNdkWindowHandle}; |
47 | pub use appkit::{AppKitDisplayHandle, AppKitWindowHandle}; |
48 | #[cfg (any(feature = "std" , not(target_os = "android" )))] |
49 | pub use borrowed::{ |
50 | Active, ActiveHandle, DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, |
51 | WindowHandle, |
52 | }; |
53 | pub use haiku::{HaikuDisplayHandle, HaikuWindowHandle}; |
54 | pub use redox::{OrbitalDisplayHandle, OrbitalWindowHandle}; |
55 | pub use uikit::{UiKitDisplayHandle, UiKitWindowHandle}; |
56 | pub use unix::{ |
57 | DrmDisplayHandle, DrmWindowHandle, GbmDisplayHandle, GbmWindowHandle, WaylandDisplayHandle, |
58 | WaylandWindowHandle, XcbDisplayHandle, XcbWindowHandle, XlibDisplayHandle, XlibWindowHandle, |
59 | }; |
60 | pub use web::{WebDisplayHandle, WebWindowHandle}; |
61 | pub 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. |
77 | pub unsafe trait HasRawWindowHandle { |
78 | fn raw_window_handle(&self) -> RawWindowHandle; |
79 | } |
80 | |
81 | unsafe 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" )))] |
88 | unsafe 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" )))] |
95 | unsafe 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)] |
123 | pub 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. |
217 | pub unsafe trait HasRawDisplayHandle { |
218 | fn raw_display_handle(&self) -> RawDisplayHandle; |
219 | } |
220 | |
221 | unsafe 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" )))] |
229 | unsafe 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" )))] |
237 | unsafe 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)] |
271 | pub 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 | |
346 | macro_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 | |
356 | from_impl!(RawDisplayHandle, UiKit, UiKitDisplayHandle); |
357 | from_impl!(RawDisplayHandle, AppKit, AppKitDisplayHandle); |
358 | from_impl!(RawDisplayHandle, Orbital, OrbitalDisplayHandle); |
359 | from_impl!(RawDisplayHandle, Xlib, XlibDisplayHandle); |
360 | from_impl!(RawDisplayHandle, Xcb, XcbDisplayHandle); |
361 | from_impl!(RawDisplayHandle, Wayland, WaylandDisplayHandle); |
362 | from_impl!(RawDisplayHandle, Drm, DrmDisplayHandle); |
363 | from_impl!(RawDisplayHandle, Gbm, GbmDisplayHandle); |
364 | from_impl!(RawDisplayHandle, Windows, WindowsDisplayHandle); |
365 | from_impl!(RawDisplayHandle, Web, WebDisplayHandle); |
366 | from_impl!(RawDisplayHandle, Android, AndroidDisplayHandle); |
367 | from_impl!(RawDisplayHandle, Haiku, HaikuDisplayHandle); |
368 | |
369 | from_impl!(RawWindowHandle, UiKit, UiKitWindowHandle); |
370 | from_impl!(RawWindowHandle, AppKit, AppKitWindowHandle); |
371 | from_impl!(RawWindowHandle, Orbital, OrbitalWindowHandle); |
372 | from_impl!(RawWindowHandle, Xlib, XlibWindowHandle); |
373 | from_impl!(RawWindowHandle, Xcb, XcbWindowHandle); |
374 | from_impl!(RawWindowHandle, Wayland, WaylandWindowHandle); |
375 | from_impl!(RawWindowHandle, Drm, DrmWindowHandle); |
376 | from_impl!(RawWindowHandle, Gbm, GbmWindowHandle); |
377 | from_impl!(RawWindowHandle, Win32, Win32WindowHandle); |
378 | from_impl!(RawWindowHandle, WinRt, WinRtWindowHandle); |
379 | from_impl!(RawWindowHandle, Web, WebWindowHandle); |
380 | from_impl!(RawWindowHandle, AndroidNdk, AndroidNdkWindowHandle); |
381 | from_impl!(RawWindowHandle, Haiku, HaikuWindowHandle); |
382 | |