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}