winit/platform_impl/linux/wayland/
output.rs

1use std::num::{NonZeroU16, NonZeroU32};
2
3use sctk::output::{Mode, OutputData};
4use sctk::reexports::client::protocol::wl_output::WlOutput;
5use sctk::reexports::client::Proxy;
6
7use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
8use crate::platform_impl::platform::VideoModeHandle as PlatformVideoModeHandle;
9
10#[derive(Clone, Debug)]
11pub struct MonitorHandle {
12    pub(crate) proxy: WlOutput,
13}
14
15impl MonitorHandle {
16    #[inline]
17    pub(crate) fn new(proxy: WlOutput) -> Self {
18        Self { proxy }
19    }
20
21    #[inline]
22    pub fn name(&self) -> Option<String> {
23        let output_data = self.proxy.data::<OutputData>().unwrap();
24        output_data.with_output_info(|info| info.name.clone())
25    }
26
27    #[inline]
28    pub fn native_identifier(&self) -> u32 {
29        let output_data = self.proxy.data::<OutputData>().unwrap();
30        output_data.with_output_info(|info| info.id)
31    }
32
33    #[inline]
34    pub fn position(&self) -> Option<PhysicalPosition<i32>> {
35        let output_data = self.proxy.data::<OutputData>().unwrap();
36        Some(output_data.with_output_info(|info| {
37            info.logical_position.map_or_else(
38                || {
39                    LogicalPosition::<i32>::from(info.location)
40                        .to_physical(info.scale_factor as f64)
41                },
42                |logical_position| {
43                    LogicalPosition::<i32>::from(logical_position)
44                        .to_physical(info.scale_factor as f64)
45                },
46            )
47        }))
48    }
49
50    #[inline]
51    pub fn scale_factor(&self) -> i32 {
52        let output_data = self.proxy.data::<OutputData>().unwrap();
53        output_data.scale_factor()
54    }
55
56    #[inline]
57    pub fn current_video_mode(&self) -> Option<PlatformVideoModeHandle> {
58        let output_data = self.proxy.data::<OutputData>().unwrap();
59        output_data.with_output_info(|info| {
60            let mode = info.modes.iter().find(|mode| mode.current).cloned();
61
62            mode.map(|mode| {
63                PlatformVideoModeHandle::Wayland(VideoModeHandle::new(self.clone(), mode))
64            })
65        })
66    }
67
68    #[inline]
69    pub fn video_modes(&self) -> impl Iterator<Item = PlatformVideoModeHandle> {
70        let output_data = self.proxy.data::<OutputData>().unwrap();
71        let modes = output_data.with_output_info(|info| info.modes.clone());
72
73        let monitor = self.clone();
74
75        modes.into_iter().map(move |mode| {
76            PlatformVideoModeHandle::Wayland(VideoModeHandle::new(monitor.clone(), mode))
77        })
78    }
79}
80
81impl PartialEq for MonitorHandle {
82    fn eq(&self, other: &Self) -> bool {
83        self.native_identifier() == other.native_identifier()
84    }
85}
86
87impl Eq for MonitorHandle {}
88
89impl PartialOrd for MonitorHandle {
90    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
91        Some(self.cmp(other))
92    }
93}
94
95impl Ord for MonitorHandle {
96    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
97        self.native_identifier().cmp(&other.native_identifier())
98    }
99}
100
101impl std::hash::Hash for MonitorHandle {
102    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
103        self.native_identifier().hash(state);
104    }
105}
106
107#[derive(Debug, Clone, PartialEq, Eq, Hash)]
108pub struct VideoModeHandle {
109    pub(crate) size: PhysicalSize<u32>,
110    pub(crate) refresh_rate_millihertz: Option<NonZeroU32>,
111    pub(crate) monitor: MonitorHandle,
112}
113
114impl VideoModeHandle {
115    fn new(monitor: MonitorHandle, mode: Mode) -> Self {
116        VideoModeHandle {
117            size: (mode.dimensions.0 as u32, mode.dimensions.1 as u32).into(),
118            refresh_rate_millihertz: NonZeroU32::new(mode.refresh_rate as u32),
119            monitor: monitor.clone(),
120        }
121    }
122
123    #[inline]
124    pub fn size(&self) -> PhysicalSize<u32> {
125        self.size
126    }
127
128    #[inline]
129    pub fn bit_depth(&self) -> Option<NonZeroU16> {
130        None
131    }
132
133    #[inline]
134    pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
135        self.refresh_rate_millihertz
136    }
137
138    pub fn monitor(&self) -> MonitorHandle {
139        self.monitor.clone()
140    }
141}