1 | use std::num::NonZeroU32; |
2 | |
3 | use glutin::context::PossiblyCurrentContext; |
4 | use glutin::surface::{ |
5 | GlSurface, ResizeableSurface, Surface, SurfaceAttributes, SurfaceAttributesBuilder, |
6 | SurfaceTypeTrait, WindowSurface, |
7 | }; |
8 | use raw_window_handle::HasRawWindowHandle; |
9 | use winit::window::Window; |
10 | |
11 | /// [`Window`] extensions for working with [`glutin`] surfaces. |
12 | pub trait GlWindow { |
13 | /// Build the surface attributes suitable to create a window surface. |
14 | /// |
15 | /// # Panics |
16 | /// Panics if either window inner dimension is zero. |
17 | /// |
18 | /// # Example |
19 | /// ```no_run |
20 | /// use glutin_winit::GlWindow; |
21 | /// # let winit_window: winit::window::Window = unimplemented!(); |
22 | /// |
23 | /// let attrs = winit_window.build_surface_attributes(<_>::default()); |
24 | /// ``` |
25 | fn build_surface_attributes( |
26 | &self, |
27 | builder: SurfaceAttributesBuilder<WindowSurface>, |
28 | ) -> SurfaceAttributes<WindowSurface>; |
29 | |
30 | /// Resize the surface to the window inner size. |
31 | /// |
32 | /// No-op if either window size is zero. |
33 | /// |
34 | /// # Example |
35 | /// ```no_run |
36 | /// use glutin_winit::GlWindow; |
37 | /// # use glutin::surface::{Surface, WindowSurface}; |
38 | /// # let winit_window: winit::window::Window = unimplemented!(); |
39 | /// # let (gl_surface, gl_context): (Surface<WindowSurface>, _) = unimplemented!(); |
40 | /// |
41 | /// winit_window.resize_surface(&gl_surface, &gl_context); |
42 | /// ``` |
43 | fn resize_surface( |
44 | &self, |
45 | surface: &Surface<impl SurfaceTypeTrait + ResizeableSurface>, |
46 | context: &PossiblyCurrentContext, |
47 | ); |
48 | } |
49 | |
50 | impl GlWindow for Window { |
51 | fn build_surface_attributes( |
52 | &self, |
53 | builder: SurfaceAttributesBuilder<WindowSurface>, |
54 | ) -> SurfaceAttributes<WindowSurface> { |
55 | let (w: NonZero, h: NonZero) = self.inner_size().non_zero().expect(msg:"invalid zero inner size" ); |
56 | builder.build(self.raw_window_handle(), width:w, height:h) |
57 | } |
58 | |
59 | fn resize_surface( |
60 | &self, |
61 | surface: &Surface<impl SurfaceTypeTrait + ResizeableSurface>, |
62 | context: &PossiblyCurrentContext, |
63 | ) { |
64 | if let Some((w: NonZero, h: NonZero)) = self.inner_size().non_zero() { |
65 | surface.resize(context, width:w, height:h) |
66 | } |
67 | } |
68 | } |
69 | |
70 | /// [`winit::dpi::PhysicalSize<u32>`] non-zero extensions. |
71 | trait NonZeroU32PhysicalSize { |
72 | /// Converts to non-zero `(width, height)`. |
73 | fn non_zero(self) -> Option<(NonZeroU32, NonZeroU32)>; |
74 | } |
75 | impl NonZeroU32PhysicalSize for winit::dpi::PhysicalSize<u32> { |
76 | fn non_zero(self) -> Option<(NonZeroU32, NonZeroU32)> { |
77 | let w: NonZero = NonZeroU32::new(self.width)?; |
78 | let h: NonZero = NonZeroU32::new(self.height)?; |
79 | Some((w, h)) |
80 | } |
81 | } |
82 | |