raw_window_handle_ffi/
lib.rs

1mod handles;
2
3pub use handles::*;
4use thiserror::Error;
5
6//Debug,  PartialEq, Eq, Hash
7
8#[repr(C)]
9#[derive(Clone, Copy)]
10pub struct RawWindowHandle {
11    pub kind: RawWindowHandleKind,
12    pub data: RawWindowHandleData,
13}
14
15#[repr(u8)]
16#[derive(Debug, Error)]
17pub enum Error {
18    #[error("unknown window handle variant was passed")]
19    UnknownUnexaustiveVariant,
20}
21
22impl TryFrom<raw_window_handle::RawWindowHandle> for RawWindowHandle {
23    type Error = Error;
24
25    fn try_from(value: raw_window_handle::RawWindowHandle) -> Result<Self, Self::Error> {
26        match value {
27            raw_window_handle::RawWindowHandle::UiKit(ui_kit_window_handle) => Ok(Self {
28                kind: RawWindowHandleKind::UiKitWindowHandle,
29                data: RawWindowHandleData {
30                    ui_kit: UiKitWindowHandle::from(ui_kit_window_handle),
31                },
32            }),
33            raw_window_handle::RawWindowHandle::AppKit(app_kit_window_handle) => Ok(Self {
34                kind: RawWindowHandleKind::AppKitWindowHandle,
35                data: RawWindowHandleData {
36                    app_kit: AppKitWindowHandle::from(app_kit_window_handle),
37                },
38            }),
39            raw_window_handle::RawWindowHandle::Orbital(orbital_window_handle) => Ok(Self {
40                kind: RawWindowHandleKind::OrbitalWindowHandle,
41                data: RawWindowHandleData {
42                    orbital: OrbitalWindowHandle::from(orbital_window_handle),
43                },
44            }),
45            raw_window_handle::RawWindowHandle::OhosNdk(ohos_ndk_window_handle) => Ok(Self {
46                kind: RawWindowHandleKind::OhosNdkWindowHandle,
47                data: RawWindowHandleData {
48                    ohos_ndk: OhosNdkWindowHandle::from(ohos_ndk_window_handle),
49                },
50            }),
51            raw_window_handle::RawWindowHandle::Xlib(xlib_window_handle) => Ok(Self {
52                kind: RawWindowHandleKind::XlibWindowHandle,
53                data: RawWindowHandleData {
54                    xlib: XlibWindowHandle::from(xlib_window_handle),
55                },
56            }),
57            raw_window_handle::RawWindowHandle::Xcb(xcb_window_handle) => Ok(Self {
58                kind: RawWindowHandleKind::XcbWindowHandle,
59                data: RawWindowHandleData {
60                    xcb: XcbWindowHandle::from(xcb_window_handle),
61                },
62            }),
63            raw_window_handle::RawWindowHandle::Wayland(wayland_window_handle) => Ok(Self {
64                kind: RawWindowHandleKind::WaylandWindowHandle,
65                data: RawWindowHandleData {
66                    wayland: WaylandWindowHandle::from(wayland_window_handle),
67                },
68            }),
69            raw_window_handle::RawWindowHandle::Drm(drm_window_handle) => Ok(Self {
70                kind: RawWindowHandleKind::DrmWindowHandle,
71                data: RawWindowHandleData {
72                    drm: DrmWindowHandle::from(drm_window_handle),
73                },
74            }),
75            raw_window_handle::RawWindowHandle::Gbm(gbm_window_handle) => Ok(Self {
76                kind: RawWindowHandleKind::GbmWindowHandle,
77                data: RawWindowHandleData {
78                    gbm: GbmWindowHandle::from(gbm_window_handle),
79                },
80            }),
81            raw_window_handle::RawWindowHandle::Win32(win32_window_handle) => Ok(Self {
82                kind: RawWindowHandleKind::Win32WindowHandle,
83                data: RawWindowHandleData {
84                    win32: Win32WindowHandle::from(win32_window_handle),
85                },
86            }),
87            raw_window_handle::RawWindowHandle::WinRt(win_rt_window_handle) => Ok(Self {
88                kind: RawWindowHandleKind::WinRtWindowHandle,
89                data: RawWindowHandleData {
90                    win_rt: WinRtWindowHandle::from(win_rt_window_handle),
91                },
92            }),
93            raw_window_handle::RawWindowHandle::Web(web_window_handle) => Ok(Self {
94                kind: RawWindowHandleKind::WebWindowHandle,
95                data: RawWindowHandleData {
96                    web: WebWindowHandle::from(web_window_handle),
97                },
98            }),
99            raw_window_handle::RawWindowHandle::WebCanvas(web_canvas_window_handle) => Ok(Self {
100                kind: RawWindowHandleKind::WebCanvasWindowHandle,
101                data: RawWindowHandleData {
102                    web_canvas: WebCanvasWindowHandle::from(web_canvas_window_handle),
103                },
104            }),
105            raw_window_handle::RawWindowHandle::WebOffscreenCanvas(
106                web_offscreen_canvas_window_handle,
107            ) => Ok(Self {
108                kind: RawWindowHandleKind::WebOffscreenCanvasWindowHandle,
109                data: RawWindowHandleData {
110                    web_offscreen_canvas: WebOffscreenCanvasWindowHandle::from(
111                        web_offscreen_canvas_window_handle,
112                    ),
113                },
114            }),
115            raw_window_handle::RawWindowHandle::AndroidNdk(android_ndk_window_handle) => Ok(Self {
116                kind: RawWindowHandleKind::AndroidNdkWindowHandle,
117                data: RawWindowHandleData {
118                    android_ndk: AndroidNdkWindowHandle::from(android_ndk_window_handle),
119                },
120            }),
121            raw_window_handle::RawWindowHandle::Haiku(haiku_window_handle) => Ok(Self {
122                kind: RawWindowHandleKind::HaikuWindowHandle,
123                data: RawWindowHandleData {
124                    haiku: HaikuWindowHandle::from(haiku_window_handle),
125                },
126            }),
127            _ => Err(Error::UnknownUnexaustiveVariant),
128        }
129    }
130}
131
132impl RawWindowHandle {
133    /// Converts FFI type back to the [`raw_window_handle::RawWindowHandle`].
134    ///
135    /// # Safety
136    /// Unsafe because all non-FFI values are `#[non_exaustive]` and its impossible to safely convert to those.
137    pub unsafe fn into_handle(self) -> raw_window_handle::RawWindowHandle {
138        unsafe {
139            match self.kind {
140                RawWindowHandleKind::UiKitWindowHandle => {
141                    raw_window_handle::RawWindowHandle::UiKit(self.data.ui_kit.into())
142                }
143                RawWindowHandleKind::AppKitWindowHandle => {
144                    raw_window_handle::RawWindowHandle::AppKit(self.data.app_kit.into())
145                }
146                RawWindowHandleKind::OrbitalWindowHandle => {
147                    raw_window_handle::RawWindowHandle::Orbital(self.data.orbital.into())
148                }
149                RawWindowHandleKind::OhosNdkWindowHandle => {
150                    raw_window_handle::RawWindowHandle::OhosNdk(self.data.ohos_ndk.into())
151                }
152                RawWindowHandleKind::XlibWindowHandle => {
153                    raw_window_handle::RawWindowHandle::Xlib(self.data.xlib.into())
154                }
155                RawWindowHandleKind::XcbWindowHandle => {
156                    raw_window_handle::RawWindowHandle::Xcb(self.data.xcb.into())
157                }
158                RawWindowHandleKind::WaylandWindowHandle => {
159                    raw_window_handle::RawWindowHandle::Wayland(self.data.wayland.into())
160                }
161                RawWindowHandleKind::DrmWindowHandle => {
162                    raw_window_handle::RawWindowHandle::Drm(self.data.drm.into())
163                }
164                RawWindowHandleKind::GbmWindowHandle => {
165                    raw_window_handle::RawWindowHandle::Gbm(self.data.gbm.into())
166                }
167                RawWindowHandleKind::Win32WindowHandle => {
168                    raw_window_handle::RawWindowHandle::Win32(self.data.win32.into())
169                }
170                RawWindowHandleKind::WinRtWindowHandle => {
171                    raw_window_handle::RawWindowHandle::WinRt(self.data.win_rt.into())
172                }
173                RawWindowHandleKind::WebWindowHandle => {
174                    raw_window_handle::RawWindowHandle::Web(self.data.web.into())
175                }
176                RawWindowHandleKind::WebCanvasWindowHandle => {
177                    raw_window_handle::RawWindowHandle::WebCanvas(self.data.web_canvas.into())
178                }
179                RawWindowHandleKind::WebOffscreenCanvasWindowHandle => {
180                    raw_window_handle::RawWindowHandle::WebOffscreenCanvas(
181                        self.data.web_offscreen_canvas.into(),
182                    )
183                }
184                RawWindowHandleKind::AndroidNdkWindowHandle => {
185                    raw_window_handle::RawWindowHandle::AndroidNdk(self.data.android_ndk.into())
186                }
187                RawWindowHandleKind::HaikuWindowHandle => {
188                    raw_window_handle::RawWindowHandle::Haiku(self.data.haiku.into())
189                }
190            }
191        }
192    }
193}
194
195impl std::fmt::Debug for RawWindowHandle {
196    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197        unsafe {
198            let handle: raw_window_handle::RawWindowHandle = self.into_handle();
199            handle.fmt(f)
200        }
201    }
202}
203
204impl PartialEq for RawWindowHandle {
205    fn eq(&self, other: &Self) -> bool {
206        if self.kind != other.kind {
207            return false;
208        }
209
210        unsafe {
211            match self.kind {
212                RawWindowHandleKind::UiKitWindowHandle => self.data.ui_kit == other.data.ui_kit,
213                RawWindowHandleKind::AppKitWindowHandle => self.data.app_kit == other.data.app_kit,
214                RawWindowHandleKind::OrbitalWindowHandle => self.data.orbital == other.data.orbital,
215                RawWindowHandleKind::OhosNdkWindowHandle => {
216                    self.data.ohos_ndk == other.data.ohos_ndk
217                }
218                RawWindowHandleKind::XlibWindowHandle => self.data.xlib == other.data.xlib,
219                RawWindowHandleKind::XcbWindowHandle => self.data.xcb == other.data.xcb,
220                RawWindowHandleKind::WaylandWindowHandle => self.data.wayland == other.data.wayland,
221                RawWindowHandleKind::DrmWindowHandle => self.data.drm == other.data.drm,
222                RawWindowHandleKind::GbmWindowHandle => self.data.gbm == other.data.gbm,
223                RawWindowHandleKind::Win32WindowHandle => self.data.win32 == other.data.win32,
224                RawWindowHandleKind::WinRtWindowHandle => self.data.win_rt == other.data.win_rt,
225                RawWindowHandleKind::WebWindowHandle => self.data.web == other.data.web,
226                RawWindowHandleKind::WebCanvasWindowHandle => {
227                    self.data.web_canvas == other.data.web_canvas
228                }
229                RawWindowHandleKind::WebOffscreenCanvasWindowHandle => {
230                    self.data.web_offscreen_canvas == other.data.web_offscreen_canvas
231                }
232                RawWindowHandleKind::AndroidNdkWindowHandle => {
233                    self.data.android_ndk == other.data.android_ndk
234                }
235                RawWindowHandleKind::HaikuWindowHandle => self.data.haiku == other.data.haiku,
236            }
237        }
238    }
239}
240
241impl Eq for RawWindowHandle {}
242
243#[repr(u8)]
244#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
245pub enum RawWindowHandleKind {
246    /// A raw window handle for UIKit (Apple's non-macOS windowing library).
247    ///
248    /// ## Availability Hints
249    /// This variant is likely to be used on iOS, tvOS, (in theory) watchOS, and
250    /// Mac Catalyst (`$arch-apple-ios-macabi` targets, which can notably use
251    /// UIKit *or* AppKit), as these are the targets that (currently) support
252    /// UIKit.
253    UiKitWindowHandle,
254    /// A raw window handle for AppKit.
255    ///
256    /// ## Availability Hints
257    /// This variant is likely to be used on macOS, although Mac Catalyst
258    /// (`$arch-apple-ios-macabi` targets, which can notably use UIKit *or*
259    /// AppKit) can also use it despite being `target_os = "ios"`.
260    AppKitWindowHandle,
261    /// A raw window handle for the Redox operating system.
262    ///
263    /// ## Availability Hints
264    /// This variant is used by the Orbital Windowing System in the Redox
265    /// operating system.
266    OrbitalWindowHandle,
267    /// A raw window handle for the OpenHarmony OS NDK
268    ///
269    /// ## Availability Hints
270    /// This variant is used on OpenHarmony OS (`target_env = "ohos"`).
271    OhosNdkWindowHandle,
272    /// A raw window handle for Xlib.
273    ///
274    /// ## Availability Hints
275    /// This variant is likely to show up anywhere someone manages to get X11
276    /// working that Xlib can be built for, which is to say, most (but not all)
277    /// Unix systems.
278    XlibWindowHandle,
279    /// A raw window handle for Xcb.
280    ///
281    /// ## Availability Hints
282    /// This variant is likely to show up anywhere someone manages to get X11
283    /// working that XCB can be built for, which is to say, most (but not all)
284    /// Unix systems.
285    XcbWindowHandle,
286    /// A raw window handle for Wayland.
287    ///
288    /// ## Availability Hints
289    /// This variant should be expected anywhere Wayland works, which is
290    /// currently some subset of unix systems.
291    WaylandWindowHandle,
292    /// A raw window handle for the Linux Kernel Mode Set/Direct Rendering Manager
293    ///
294    /// ## Availability Hints
295    /// This variant is used on Linux when neither X nor Wayland are available
296    DrmWindowHandle,
297    /// A raw window handle for the Linux Generic Buffer Manager.
298    ///
299    /// ## Availability Hints
300    /// This variant is present regardless of windowing backend and likely to be used with
301    /// EGL_MESA_platform_gbm or EGL_KHR_platform_gbm.
302    GbmWindowHandle,
303    /// A raw window handle for Win32.
304    ///
305    /// ## Availability Hints
306    /// This variant is used on Windows systems.
307    Win32WindowHandle,
308    /// A raw window handle for WinRT.
309    ///
310    /// ## Availability Hints
311    /// This variant is used on Windows systems.
312    WinRtWindowHandle,
313    /// A raw window handle for the Web.
314    ///
315    /// ## Availability Hints
316    /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
317    WebWindowHandle,
318    /// A raw window handle for a Web canvas registered via [`wasm-bindgen`].
319    ///
320    /// ## Availability Hints
321    /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
322    ///
323    /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
324    WebCanvasWindowHandle,
325    /// A raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`].
326    ///
327    /// ## Availability Hints
328    /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
329    ///
330    /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
331    WebOffscreenCanvasWindowHandle,
332    /// A raw window handle for Android NDK.
333    ///
334    /// ## Availability Hints
335    /// This variant is used on Android targets.
336    AndroidNdkWindowHandle,
337    /// A raw window handle for Haiku.
338    ///
339    /// ## Availability Hints
340    /// This variant is used on HaikuOS.
341    HaikuWindowHandle,
342}
343
344#[repr(C)]
345#[derive(Clone, Copy)]
346pub union RawWindowHandleData {
347    /// A raw window handle for UIKit (Apple's non-macOS windowing library).
348    ///
349    /// ## Availability Hints
350    /// This variant is likely to be used on iOS, tvOS, (in theory) watchOS, and
351    /// Mac Catalyst (`$arch-apple-ios-macabi` targets, which can notably use
352    /// UIKit *or* AppKit), as these are the targets that (currently) support
353    /// UIKit.
354    ui_kit: UiKitWindowHandle,
355    /// A raw window handle for AppKit.
356    ///
357    /// ## Availability Hints
358    /// This variant is likely to be used on macOS, although Mac Catalyst
359    /// (`$arch-apple-ios-macabi` targets, which can notably use UIKit *or*
360    /// AppKit) can also use it despite being `target_os = "ios"`.
361    app_kit: AppKitWindowHandle,
362    /// A raw window handle for the Redox operating system.
363    ///
364    /// ## Availability Hints
365    /// This variant is used by the Orbital Windowing System in the Redox
366    /// operating system.
367    orbital: OrbitalWindowHandle,
368    /// A raw window handle for the OpenHarmony OS NDK
369    ///
370    /// ## Availability Hints
371    /// This variant is used on OpenHarmony OS (`target_env = "ohos"`).
372    ohos_ndk: OhosNdkWindowHandle,
373    /// A raw window handle for Xlib.
374    ///
375    /// ## Availability Hints
376    /// This variant is likely to show up anywhere someone manages to get X11
377    /// working that Xlib can be built for, which is to say, most (but not all)
378    /// Unix systems.
379    xlib: XlibWindowHandle,
380    /// A raw window handle for Xcb.
381    ///
382    /// ## Availability Hints
383    /// This variant is likely to show up anywhere someone manages to get X11
384    /// working that XCB can be built for, which is to say, most (but not all)
385    /// Unix systems.
386    xcb: XcbWindowHandle,
387    /// A raw window handle for Wayland.
388    ///
389    /// ## Availability Hints
390    /// This variant should be expected anywhere Wayland works, which is
391    /// currently some subset of unix systems.
392    wayland: WaylandWindowHandle,
393    /// A raw window handle for the Linux Kernel Mode Set/Direct Rendering Manager
394    ///
395    /// ## Availability Hints
396    /// This variant is used on Linux when neither X nor Wayland are available
397    drm: DrmWindowHandle,
398    /// A raw window handle for the Linux Generic Buffer Manager.
399    ///
400    /// ## Availability Hints
401    /// This variant is present regardless of windowing backend and likely to be used with
402    /// EGL_MESA_platform_gbm or EGL_KHR_platform_gbm.
403    gbm: GbmWindowHandle,
404    /// A raw window handle for Win32.
405    ///
406    /// ## Availability Hints
407    /// This variant is used on Windows systems.
408    win32: Win32WindowHandle,
409    /// A raw window handle for WinRT.
410    ///
411    /// ## Availability Hints
412    /// This variant is used on Windows systems.
413    win_rt: WinRtWindowHandle,
414    /// A raw window handle for the Web.
415    ///
416    /// ## Availability Hints
417    /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
418    web: WebWindowHandle,
419    /// A raw window handle for a Web canvas registered via [`wasm-bindgen`].
420    ///
421    /// ## Availability Hints
422    /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
423    ///
424    /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
425    web_canvas: WebCanvasWindowHandle,
426    /// A raw window handle for a Web offscreen canvas registered via [`wasm-bindgen`].
427    ///
428    /// ## Availability Hints
429    /// This variant is used on Wasm or asm.js targets when targeting the Web/HTML5.
430    ///
431    /// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
432    web_offscreen_canvas: WebOffscreenCanvasWindowHandle,
433    /// A raw window handle for Android NDK.
434    ///
435    /// ## Availability Hints
436    /// This variant is used on Android targets.
437    android_ndk: AndroidNdkWindowHandle,
438    /// A raw window handle for Haiku.
439    ///
440    /// ## Availability Hints
441    /// This variant is used on HaikuOS.
442    haiku: HaikuWindowHandle,
443}