1 | //! Types useful for interacting with a user's monitors. |
2 | //! |
3 | //! If you want to get basic information about a monitor, you can use the |
4 | //! [`MonitorHandle`] type. This is retrieved from one of the following |
5 | //! methods, which return an iterator of [`MonitorHandle`]: |
6 | //! - [`ActiveEventLoop::available_monitors`][crate::event_loop::ActiveEventLoop::available_monitors]. |
7 | //! - [`Window::available_monitors`][crate::window::Window::available_monitors]. |
8 | use crate::dpi::{PhysicalPosition, PhysicalSize}; |
9 | use crate::platform_impl; |
10 | |
11 | /// Deprecated! Use `VideoModeHandle` instead. |
12 | #[deprecated = "Renamed to `VideoModeHandle`" ] |
13 | pub type VideoMode = VideoModeHandle; |
14 | |
15 | /// Describes a fullscreen video mode of a monitor. |
16 | /// |
17 | /// Can be acquired with [`MonitorHandle::video_modes`]. |
18 | #[derive (Clone, PartialEq, Eq, Hash)] |
19 | pub struct VideoModeHandle { |
20 | pub(crate) video_mode: platform_impl::VideoModeHandle, |
21 | } |
22 | |
23 | impl std::fmt::Debug for VideoModeHandle { |
24 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
25 | self.video_mode.fmt(f) |
26 | } |
27 | } |
28 | |
29 | impl PartialOrd for VideoModeHandle { |
30 | fn partial_cmp(&self, other: &VideoModeHandle) -> Option<std::cmp::Ordering> { |
31 | Some(self.cmp(other)) |
32 | } |
33 | } |
34 | |
35 | impl Ord for VideoModeHandle { |
36 | fn cmp(&self, other: &VideoModeHandle) -> std::cmp::Ordering { |
37 | self.monitor().cmp(&other.monitor()).then( |
38 | self.size() |
39 | .cmp(&other.size()) |
40 | .then( |
41 | self.refresh_rate_millihertz() |
42 | .cmp(&other.refresh_rate_millihertz()) |
43 | .then(self.bit_depth().cmp(&other.bit_depth())), |
44 | ) |
45 | .reverse(), |
46 | ) |
47 | } |
48 | } |
49 | |
50 | impl VideoModeHandle { |
51 | /// Returns the resolution of this video mode. |
52 | #[inline ] |
53 | pub fn size(&self) -> PhysicalSize<u32> { |
54 | self.video_mode.size() |
55 | } |
56 | |
57 | /// Returns the bit depth of this video mode, as in how many bits you have |
58 | /// available per color. This is generally 24 bits or 32 bits on modern |
59 | /// systems, depending on whether the alpha channel is counted or not. |
60 | /// |
61 | /// ## Platform-specific |
62 | /// |
63 | /// - **Wayland / Orbital:** Always returns 32. |
64 | /// - **iOS:** Always returns 32. |
65 | #[inline ] |
66 | pub fn bit_depth(&self) -> u16 { |
67 | self.video_mode.bit_depth() |
68 | } |
69 | |
70 | /// Returns the refresh rate of this video mode in mHz. |
71 | #[inline ] |
72 | pub fn refresh_rate_millihertz(&self) -> u32 { |
73 | self.video_mode.refresh_rate_millihertz() |
74 | } |
75 | |
76 | /// Returns the monitor that this video mode is valid for. Each monitor has |
77 | /// a separate set of valid video modes. |
78 | #[inline ] |
79 | pub fn monitor(&self) -> MonitorHandle { |
80 | MonitorHandle { inner: self.video_mode.monitor() } |
81 | } |
82 | } |
83 | |
84 | impl std::fmt::Display for VideoModeHandle { |
85 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
86 | write!( |
87 | f, |
88 | " {}x {} @ {} mHz ( {} bpp)" , |
89 | self.size().width, |
90 | self.size().height, |
91 | self.refresh_rate_millihertz(), |
92 | self.bit_depth() |
93 | ) |
94 | } |
95 | } |
96 | |
97 | /// Handle to a monitor. |
98 | /// |
99 | /// Allows you to retrieve information about a given monitor and can be used in [`Window`] creation. |
100 | /// |
101 | /// [`Window`]: crate::window::Window |
102 | #[derive (Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] |
103 | pub struct MonitorHandle { |
104 | pub(crate) inner: platform_impl::MonitorHandle, |
105 | } |
106 | |
107 | impl MonitorHandle { |
108 | /// Returns a human-readable name of the monitor. |
109 | /// |
110 | /// Returns `None` if the monitor doesn't exist anymore. |
111 | #[inline ] |
112 | pub fn name(&self) -> Option<String> { |
113 | self.inner.name() |
114 | } |
115 | |
116 | /// Returns the monitor's resolution. |
117 | #[inline ] |
118 | pub fn size(&self) -> PhysicalSize<u32> { |
119 | self.inner.size() |
120 | } |
121 | |
122 | /// Returns the top-left corner position of the monitor relative to the larger full |
123 | /// screen area. |
124 | #[inline ] |
125 | pub fn position(&self) -> PhysicalPosition<i32> { |
126 | self.inner.position() |
127 | } |
128 | |
129 | /// The monitor refresh rate used by the system. |
130 | /// |
131 | /// Return `Some` if succeed, or `None` if failed, which usually happens when the monitor |
132 | /// the window is on is removed. |
133 | /// |
134 | /// When using exclusive fullscreen, the refresh rate of the [`VideoModeHandle`] that was |
135 | /// used to enter fullscreen should be used instead. |
136 | #[inline ] |
137 | pub fn refresh_rate_millihertz(&self) -> Option<u32> { |
138 | self.inner.refresh_rate_millihertz() |
139 | } |
140 | |
141 | /// Returns the scale factor of the underlying monitor. To map logical pixels to physical |
142 | /// pixels and vice versa, use [`Window::scale_factor`]. |
143 | /// |
144 | /// See the [`dpi`] module for more information. |
145 | /// |
146 | /// ## Platform-specific |
147 | /// |
148 | /// - **X11:** Can be overridden using the `WINIT_X11_SCALE_FACTOR` environment variable. |
149 | /// - **Wayland:** May differ from [`Window::scale_factor`]. |
150 | /// - **Android:** Always returns 1.0. |
151 | /// |
152 | /// [`Window::scale_factor`]: crate::window::Window::scale_factor |
153 | #[inline ] |
154 | pub fn scale_factor(&self) -> f64 { |
155 | self.inner.scale_factor() |
156 | } |
157 | |
158 | /// Returns all fullscreen video modes supported by this monitor. |
159 | /// |
160 | /// ## Platform-specific |
161 | /// |
162 | /// - **Web:** Always returns an empty iterator |
163 | #[inline ] |
164 | pub fn video_modes(&self) -> impl Iterator<Item = VideoModeHandle> { |
165 | self.inner.video_modes().map(|video_mode| VideoModeHandle { video_mode }) |
166 | } |
167 | } |
168 | |