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
9use control;
10use drm_ffi as ffi;
11
12/// A handle to a connector
13#[repr(transparent)]
14#[derive(Copy, Clone, Hash, PartialEq, Eq)]
15pub struct Handle(control::RawResourceHandle);
16
17// Safety: Handle is repr(transparent) over NonZeroU32
18unsafe impl bytemuck::ZeroableInOption for Handle {}
19unsafe impl bytemuck::PodInOption for Handle {}
20
21impl From<Handle> for control::RawResourceHandle {
22 fn from(handle: Handle) -> Self {
23 handle.0
24 }
25}
26
27impl From<Handle> for u32 {
28 fn from(handle: Handle) -> Self {
29 handle.0.into()
30 }
31}
32
33impl From<control::RawResourceHandle> for Handle {
34 fn from(handle: control::RawResourceHandle) -> Self {
35 Handle(handle)
36 }
37}
38
39impl control::ResourceHandle for Handle {
40 const FFI_TYPE: u32 = ffi::DRM_MODE_OBJECT_CONNECTOR;
41}
42
43impl 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)]
51pub 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
62impl 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)]
112pub 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
136impl 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
166impl 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
195impl 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)]
226pub enum State {
227 Connected,
228 Disconnected,
229 Unknown,
230}
231
232impl 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
244impl 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