1 | //! # Connector |
2 | //! |
3 | //! Represents the physical output, such as a DisplayPort or VGA connector. |
4 | //! |
5 | //! A Connector is the physical connection between the display controller and |
6 | //! a display. These objects keep track of connection information and state, |
7 | //! including the modes that the current display supports. |
8 | |
9 | use control; |
10 | use drm_ffi as ffi; |
11 | |
12 | /// A handle to a connector |
13 | #[repr (transparent)] |
14 | #[derive (Copy, Clone, Hash, PartialEq, Eq)] |
15 | pub struct Handle(control::RawResourceHandle); |
16 | |
17 | // Safety: Handle is repr(transparent) over NonZeroU32 |
18 | unsafe impl bytemuck::ZeroableInOption for Handle {} |
19 | unsafe impl bytemuck::PodInOption for Handle {} |
20 | |
21 | impl From<Handle> for control::RawResourceHandle { |
22 | fn from(handle: Handle) -> Self { |
23 | handle.0 |
24 | } |
25 | } |
26 | |
27 | impl From<Handle> for u32 { |
28 | fn from(handle: Handle) -> Self { |
29 | handle.0.into() |
30 | } |
31 | } |
32 | |
33 | impl From<control::RawResourceHandle> for Handle { |
34 | fn from(handle: control::RawResourceHandle) -> Self { |
35 | Handle(handle) |
36 | } |
37 | } |
38 | |
39 | impl control::ResourceHandle for Handle { |
40 | const FFI_TYPE: u32 = ffi::DRM_MODE_OBJECT_CONNECTOR; |
41 | } |
42 | |
43 | impl std::fmt::Debug for Handle { |
44 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
45 | f.debug_tuple(name:"connector::Handle" ).field(&self.0).finish() |
46 | } |
47 | } |
48 | |
49 | /// Information about a connector |
50 | #[derive (Debug, Clone, Hash, PartialEq, Eq)] |
51 | pub struct Info { |
52 | pub(crate) handle: Handle, |
53 | pub(crate) interface: Interface, |
54 | pub(crate) interface_id: u32, |
55 | pub(crate) connection: State, |
56 | pub(crate) size: Option<(u32, u32)>, |
57 | pub(crate) modes: Vec<control::Mode>, |
58 | pub(crate) encoders: Vec<control::encoder::Handle>, |
59 | pub(crate) curr_enc: Option<control::encoder::Handle>, |
60 | } |
61 | |
62 | impl Info { |
63 | /// Returns the handle to this connector. |
64 | pub fn handle(&self) -> Handle { |
65 | self.handle |
66 | } |
67 | |
68 | /// Returns the type of `Interface` of this connector. |
69 | pub fn interface(&self) -> Interface { |
70 | self.interface |
71 | } |
72 | |
73 | /// Returns the interface ID of this connector. |
74 | /// |
75 | /// When multiple connectors have the same `Interface`, they will have |
76 | /// different interface IDs. |
77 | pub fn interface_id(&self) -> u32 { |
78 | self.interface_id |
79 | } |
80 | |
81 | /// Returns the `State` of this connector. |
82 | pub fn state(&self) -> State { |
83 | self.connection |
84 | } |
85 | |
86 | /// Returns the size of the display (in millimeters) if connected. |
87 | pub fn size(&self) -> Option<(u32, u32)> { |
88 | self.size |
89 | } |
90 | |
91 | /// Returns a list of encoders that can be possibly used by this connector. |
92 | pub fn encoders(&self) -> &[control::encoder::Handle] { |
93 | &self.encoders |
94 | } |
95 | |
96 | /// Returns a list of modes this connector reports as supported. |
97 | pub fn modes(&self) -> &[control::Mode] { |
98 | &self.modes |
99 | } |
100 | |
101 | /// Returns the current encoder attached to this connector. |
102 | pub fn current_encoder(&self) -> Option<control::encoder::Handle> { |
103 | self.curr_enc |
104 | } |
105 | } |
106 | |
107 | /// A physical interface type. |
108 | #[allow (missing_docs)] |
109 | #[allow (clippy::upper_case_acronyms)] |
110 | #[non_exhaustive ] |
111 | #[derive (Debug, Copy, Clone, Hash, PartialEq, Eq)] |
112 | pub enum Interface { |
113 | Unknown, |
114 | VGA, |
115 | DVII, |
116 | DVID, |
117 | DVIA, |
118 | Composite, |
119 | SVideo, |
120 | LVDS, |
121 | Component, |
122 | NinePinDIN, |
123 | DisplayPort, |
124 | HDMIA, |
125 | HDMIB, |
126 | TV, |
127 | EmbeddedDisplayPort, |
128 | Virtual, |
129 | DSI, |
130 | DPI, |
131 | Writeback, |
132 | SPI, |
133 | USB, |
134 | } |
135 | |
136 | impl Interface { |
137 | /// Get interface name as string |
138 | pub fn as_str(&self) -> &'static str { |
139 | // source: https://github.com/torvalds/linux/blob/489fa31ea873282b41046d412ec741f93946fc2d/drivers/gpu/drm/drm_connector.c#L89 |
140 | match self { |
141 | Interface::Unknown => "Unknown" , |
142 | Interface::VGA => "VGA" , |
143 | Interface::DVII => "DVI-I" , |
144 | Interface::DVID => "DVI-D" , |
145 | Interface::DVIA => "DVI-A" , |
146 | Interface::Composite => "Composite" , |
147 | Interface::SVideo => "SVIDEO" , |
148 | Interface::LVDS => "LVDS" , |
149 | Interface::Component => "Component" , |
150 | Interface::NinePinDIN => "DIN" , |
151 | Interface::DisplayPort => "DP" , |
152 | Interface::HDMIA => "HDMI-A" , |
153 | Interface::HDMIB => "HDMI-B" , |
154 | Interface::TV => "TV" , |
155 | Interface::EmbeddedDisplayPort => "eDP" , |
156 | Interface::Virtual => "Virtual" , |
157 | Interface::DSI => "DSI" , |
158 | Interface::DPI => "DPI" , |
159 | Interface::Writeback => "Writeback" , |
160 | Interface::SPI => "SPI" , |
161 | Interface::USB => "USB" , |
162 | } |
163 | } |
164 | } |
165 | |
166 | impl From<u32> for Interface { |
167 | fn from(n: u32) -> Self { |
168 | match n { |
169 | ffi::DRM_MODE_CONNECTOR_Unknown => Interface::Unknown, |
170 | ffi::DRM_MODE_CONNECTOR_VGA => Interface::VGA, |
171 | ffi::DRM_MODE_CONNECTOR_DVII => Interface::DVII, |
172 | ffi::DRM_MODE_CONNECTOR_DVID => Interface::DVID, |
173 | ffi::DRM_MODE_CONNECTOR_DVIA => Interface::DVIA, |
174 | ffi::DRM_MODE_CONNECTOR_Composite => Interface::Composite, |
175 | ffi::DRM_MODE_CONNECTOR_SVIDEO => Interface::SVideo, |
176 | ffi::DRM_MODE_CONNECTOR_LVDS => Interface::LVDS, |
177 | ffi::DRM_MODE_CONNECTOR_Component => Interface::Component, |
178 | ffi::DRM_MODE_CONNECTOR_9PinDIN => Interface::NinePinDIN, |
179 | ffi::DRM_MODE_CONNECTOR_DisplayPort => Interface::DisplayPort, |
180 | ffi::DRM_MODE_CONNECTOR_HDMIA => Interface::HDMIA, |
181 | ffi::DRM_MODE_CONNECTOR_HDMIB => Interface::HDMIB, |
182 | ffi::DRM_MODE_CONNECTOR_TV => Interface::TV, |
183 | ffi::DRM_MODE_CONNECTOR_eDP => Interface::EmbeddedDisplayPort, |
184 | ffi::DRM_MODE_CONNECTOR_VIRTUAL => Interface::Virtual, |
185 | ffi::DRM_MODE_CONNECTOR_DSI => Interface::DSI, |
186 | ffi::DRM_MODE_CONNECTOR_DPI => Interface::DPI, |
187 | ffi::DRM_MODE_CONNECTOR_WRITEBACK => Interface::Writeback, |
188 | ffi::DRM_MODE_CONNECTOR_SPI => Interface::SPI, |
189 | ffi::DRM_MODE_CONNECTOR_USB => Interface::USB, |
190 | _ => Interface::Unknown, |
191 | } |
192 | } |
193 | } |
194 | |
195 | impl From<Interface> for u32 { |
196 | fn from(interface: Interface) -> Self { |
197 | match interface { |
198 | Interface::Unknown => ffi::DRM_MODE_CONNECTOR_Unknown, |
199 | Interface::VGA => ffi::DRM_MODE_CONNECTOR_VGA, |
200 | Interface::DVII => ffi::DRM_MODE_CONNECTOR_DVII, |
201 | Interface::DVID => ffi::DRM_MODE_CONNECTOR_DVID, |
202 | Interface::DVIA => ffi::DRM_MODE_CONNECTOR_DVIA, |
203 | Interface::Composite => ffi::DRM_MODE_CONNECTOR_Composite, |
204 | Interface::SVideo => ffi::DRM_MODE_CONNECTOR_SVIDEO, |
205 | Interface::LVDS => ffi::DRM_MODE_CONNECTOR_LVDS, |
206 | Interface::Component => ffi::DRM_MODE_CONNECTOR_Component, |
207 | Interface::NinePinDIN => ffi::DRM_MODE_CONNECTOR_9PinDIN, |
208 | Interface::DisplayPort => ffi::DRM_MODE_CONNECTOR_DisplayPort, |
209 | Interface::HDMIA => ffi::DRM_MODE_CONNECTOR_HDMIA, |
210 | Interface::HDMIB => ffi::DRM_MODE_CONNECTOR_HDMIB, |
211 | Interface::TV => ffi::DRM_MODE_CONNECTOR_TV, |
212 | Interface::EmbeddedDisplayPort => ffi::DRM_MODE_CONNECTOR_eDP, |
213 | Interface::Virtual => ffi::DRM_MODE_CONNECTOR_VIRTUAL, |
214 | Interface::DSI => ffi::DRM_MODE_CONNECTOR_DSI, |
215 | Interface::DPI => ffi::DRM_MODE_CONNECTOR_DPI, |
216 | Interface::Writeback => ffi::DRM_MODE_CONNECTOR_WRITEBACK, |
217 | Interface::SPI => ffi::DRM_MODE_CONNECTOR_SPI, |
218 | Interface::USB => ffi::DRM_MODE_CONNECTOR_USB, |
219 | } |
220 | } |
221 | } |
222 | |
223 | /// The state of a connector. |
224 | #[allow (missing_docs)] |
225 | #[derive (Debug, Copy, Clone, Hash, PartialEq, Eq)] |
226 | pub enum State { |
227 | Connected, |
228 | Disconnected, |
229 | Unknown, |
230 | } |
231 | |
232 | impl From<u32> for State { |
233 | fn from(n: u32) -> Self { |
234 | // These variables are not defined in drm_mode.h for some reason. |
235 | // They were copied from libdrm's xf86DrmMode.h |
236 | match n { |
237 | 1 => State::Connected, |
238 | 2 => State::Disconnected, |
239 | _ => State::Unknown, |
240 | } |
241 | } |
242 | } |
243 | |
244 | impl From<State> for u32 { |
245 | fn from(state: State) -> Self { |
246 | // These variables are not defined in drm_mode.h for some reason. |
247 | // They were copied from libdrm's xf86DrmMode.h |
248 | match state { |
249 | State::Connected => 1, |
250 | State::Disconnected => 2, |
251 | State::Unknown => 3, |
252 | } |
253 | } |
254 | } |
255 | |