raw_window_handle/web.rs
1use core::ffi::c_void;
2use core::ptr::NonNull;
3
4use super::DisplayHandle;
5
6/// Raw display handle for the Web.
7#[non_exhaustive]
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9pub struct WebDisplayHandle {}
10
11impl WebDisplayHandle {
12 /// Create a new empty display handle.
13 ///
14 ///
15 /// # Example
16 ///
17 /// ```
18 /// # use raw_window_handle::WebDisplayHandle;
19 /// let handle = WebDisplayHandle::new();
20 /// ```
21 pub fn new() -> Self {
22 Self {}
23 }
24}
25
26impl DisplayHandle<'static> {
27 /// Create a Web-based display handle.
28 ///
29 /// As no data is borrowed by this handle, it is completely safe to create. This function
30 /// may be useful to windowing framework implementations that want to avoid unsafe code.
31 ///
32 /// # Example
33 ///
34 /// ```
35 /// # use raw_window_handle::{DisplayHandle, HasDisplayHandle};
36 /// # fn do_something(rwh: impl HasDisplayHandle) { let _ = rwh; }
37 /// let handle = DisplayHandle::web();
38 /// do_something(handle);
39 /// ```
40 pub fn web() -> Self {
41 // SAFETY: No data is borrowed.
42 unsafe { Self::borrow_raw(WebDisplayHandle::new().into()) }
43 }
44}
45
46/// Raw window handle for the Web.
47#[non_exhaustive]
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
49pub struct WebWindowHandle {
50 /// An ID value inserted into the [data attributes] of the canvas element as '`raw-handle`'.
51 ///
52 /// When accessing from JS, the attribute will automatically be called `rawHandle`.
53 ///
54 /// Each canvas created by the windowing system should be assigned their own unique ID.
55 ///
56 /// [data attributes]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*
57 pub id: u32,
58}
59
60impl WebWindowHandle {
61 /// Create a new handle to a canvas element.
62 ///
63 ///
64 /// # Example
65 ///
66 /// ```
67 /// # use raw_window_handle::WebWindowHandle;
68 /// #
69 /// let id: u32 = 0; // canvas.rawHandle;
70 /// let handle = WebWindowHandle::new(id);
71 /// ```
72 pub fn new(id: u32) -> Self {
73 Self { id }
74 }
75}
76
77/// Raw window handle for a Web canvas registered via [`wasm-bindgen`].
78///
79/// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
80#[non_exhaustive]
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
82pub struct WebCanvasWindowHandle {
83 /// A pointer to the [`JsValue`] of an [`HtmlCanvasElement`].
84 ///
85 /// Note: This uses [`c_void`] to avoid depending on `wasm-bindgen`
86 /// directly.
87 ///
88 /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html
89 /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html
90 //
91 // SAFETY: Not using `JsValue` is sound because `wasm-bindgen` guarantees
92 // that there's only one version of itself in any given binary, and hence
93 // we can't have a type-confusion where e.g. one library used `JsValue`
94 // from `v0.2` of `wasm-bindgen`, and another used `JsValue` from `v1.0`;
95 // the binary will simply fail to compile!
96 //
97 // Reference: TODO
98 pub obj: NonNull<c_void>,
99}
100
101impl WebCanvasWindowHandle {
102 /// Create a new handle from a pointer to [`HtmlCanvasElement`].
103 ///
104 /// [`HtmlCanvasElement`]: https://docs.rs/web-sys/latest/web_sys/struct.HtmlCanvasElement.html
105 ///
106 /// # Example
107 ///
108 /// ```
109 /// # use core::ffi::c_void;
110 /// # use core::ptr::NonNull;
111 /// # use raw_window_handle::WebCanvasWindowHandle;
112 /// # type HtmlCanvasElement = ();
113 /// # type JsValue = ();
114 /// let canvas: &HtmlCanvasElement;
115 /// # canvas = &();
116 /// let value: &JsValue = &canvas; // Deref to `JsValue`
117 /// let obj: NonNull<c_void> = NonNull::from(value).cast();
118 /// let mut handle = WebCanvasWindowHandle::new(obj);
119 /// ```
120 pub fn new(obj: NonNull<c_void>) -> Self {
121 Self { obj }
122 }
123}
124
125#[cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2"))]
126#[cfg_attr(
127 docsrs,
128 doc(cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2")))
129)]
130/// These implementations are only available when `wasm-bindgen-0-2` is enabled.
131impl WebCanvasWindowHandle {
132 /// Create a new `WebCanvasWindowHandle` from a [`wasm_bindgen::JsValue`].
133 ///
134 /// The `JsValue` should refer to a `HtmlCanvasElement`, and the lifetime
135 /// of the value should be at least as long as the lifetime of this.
136 pub fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self {
137 Self::new(NonNull::from(js_value).cast())
138 }
139
140 /// Convert to the underlying [`wasm_bindgen::JsValue`].
141 ///
142 /// # Safety
143 ///
144 /// The inner pointer must be valid. This is ensured if this handle was
145 /// borrowed from [`WindowHandle`][crate::WindowHandle].
146 pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue {
147 unsafe { self.obj.cast().as_ref() }
148 }
149}
150
151/// Raw window handle for a Web offscreen canvas registered via
152/// [`wasm-bindgen`].
153///
154/// [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
155#[non_exhaustive]
156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
157pub struct WebOffscreenCanvasWindowHandle {
158 /// A pointer to the [`JsValue`] of an [`OffscreenCanvas`].
159 ///
160 /// Note: This uses [`c_void`] to avoid depending on `wasm-bindgen`
161 /// directly.
162 ///
163 /// [`JsValue`]: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html
164 /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html
165 //
166 // SAFETY: See WebCanvasWindowHandle.
167 pub obj: NonNull<c_void>,
168}
169
170impl WebOffscreenCanvasWindowHandle {
171 /// Create a new handle from a pointer to an [`OffscreenCanvas`].
172 ///
173 /// [`OffscreenCanvas`]: https://docs.rs/web-sys/latest/web_sys/struct.OffscreenCanvas.html
174 ///
175 /// # Example
176 ///
177 /// ```
178 /// # use core::ffi::c_void;
179 /// # use core::ptr::NonNull;
180 /// # use raw_window_handle::WebOffscreenCanvasWindowHandle;
181 /// # type OffscreenCanvas = ();
182 /// # type JsValue = ();
183 /// let canvas: &OffscreenCanvas;
184 /// # canvas = &();
185 /// let value: &JsValue = &canvas; // Deref to `JsValue`
186 /// let obj: NonNull<c_void> = NonNull::from(value).cast();
187 /// let mut handle = WebOffscreenCanvasWindowHandle::new(obj);
188 /// ```
189 pub fn new(obj: NonNull<c_void>) -> Self {
190 Self { obj }
191 }
192}
193
194#[cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2"))]
195#[cfg_attr(
196 docsrs,
197 doc(cfg(all(target_family = "wasm", feature = "wasm-bindgen-0-2")))
198)]
199/// These implementations are only available when `wasm-bindgen-0-2` is enabled.
200impl WebOffscreenCanvasWindowHandle {
201 /// Create a new `WebOffscreenCanvasWindowHandle` from a
202 /// [`wasm_bindgen::JsValue`].
203 ///
204 /// The `JsValue` should refer to a `HtmlCanvasElement`, and the lifetime
205 /// of the value should be at least as long as the lifetime of this.
206 pub fn from_wasm_bindgen_0_2(js_value: &wasm_bindgen::JsValue) -> Self {
207 Self::new(NonNull::from(js_value).cast())
208 }
209
210 /// Convert to the underlying [`wasm_bindgen::JsValue`].
211 ///
212 /// # Safety
213 ///
214 /// The inner pointer must be valid. This is ensured if this handle was
215 /// borrowed from [`WindowHandle`][crate::WindowHandle].
216 pub unsafe fn as_wasm_bindgen_0_2(&self) -> &wasm_bindgen::JsValue {
217 unsafe { self.obj.cast().as_ref() }
218 }
219}