• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 crate::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 {
from(handle: Handle) -> Self22     fn from(handle: Handle) -> Self {
23         handle.0
24     }
25 }
26 
27 impl From<Handle> for u32 {
from(handle: Handle) -> Self28     fn from(handle: Handle) -> Self {
29         handle.0.into()
30     }
31 }
32 
33 impl From<control::RawResourceHandle> for Handle {
from(handle: control::RawResourceHandle) -> Self34     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 {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result44     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
45         f.debug_tuple("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     pub(crate) subpixel: SubPixel,
61 }
62 
63 impl Info {
64     /// Returns the handle to this connector.
handle(&self) -> Handle65     pub fn handle(&self) -> Handle {
66         self.handle
67     }
68 
69     /// Returns the type of `Interface` of this connector.
interface(&self) -> Interface70     pub fn interface(&self) -> Interface {
71         self.interface
72     }
73 
74     /// Returns the interface ID of this connector.
75     ///
76     /// When multiple connectors have the same `Interface`, they will have
77     /// different interface IDs.
interface_id(&self) -> u3278     pub fn interface_id(&self) -> u32 {
79         self.interface_id
80     }
81 
82     /// Returns the `State` of this connector.
state(&self) -> State83     pub fn state(&self) -> State {
84         self.connection
85     }
86 
87     /// Returns the size of the display (in millimeters) if connected.
size(&self) -> Option<(u32, u32)>88     pub fn size(&self) -> Option<(u32, u32)> {
89         self.size
90     }
91 
92     /// Returns a list of encoders that can be possibly used by this connector.
encoders(&self) -> &[control::encoder::Handle]93     pub fn encoders(&self) -> &[control::encoder::Handle] {
94         &self.encoders
95     }
96 
97     /// Returns a list of modes this connector reports as supported.
modes(&self) -> &[control::Mode]98     pub fn modes(&self) -> &[control::Mode] {
99         &self.modes
100     }
101 
102     /// Returns the current encoder attached to this connector.
current_encoder(&self) -> Option<control::encoder::Handle>103     pub fn current_encoder(&self) -> Option<control::encoder::Handle> {
104         self.curr_enc
105     }
106 
107     /// Subpixel order of the connected sink
subpixel(&self) -> SubPixel108     pub fn subpixel(&self) -> SubPixel {
109         self.subpixel
110     }
111 }
112 
113 /// A physical interface type.
114 #[allow(missing_docs)]
115 #[allow(clippy::upper_case_acronyms)]
116 #[non_exhaustive]
117 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
118 pub enum Interface {
119     Unknown,
120     VGA,
121     DVII,
122     DVID,
123     DVIA,
124     Composite,
125     SVideo,
126     LVDS,
127     Component,
128     NinePinDIN,
129     DisplayPort,
130     HDMIA,
131     HDMIB,
132     TV,
133     EmbeddedDisplayPort,
134     Virtual,
135     DSI,
136     DPI,
137     Writeback,
138     SPI,
139     USB,
140 }
141 
142 impl Interface {
143     /// Get interface name as string
as_str(&self) -> &'static str144     pub fn as_str(&self) -> &'static str {
145         // source: https://github.com/torvalds/linux/blob/489fa31ea873282b41046d412ec741f93946fc2d/drivers/gpu/drm/drm_connector.c#L89
146         match self {
147             Interface::Unknown => "Unknown",
148             Interface::VGA => "VGA",
149             Interface::DVII => "DVI-I",
150             Interface::DVID => "DVI-D",
151             Interface::DVIA => "DVI-A",
152             Interface::Composite => "Composite",
153             Interface::SVideo => "SVIDEO",
154             Interface::LVDS => "LVDS",
155             Interface::Component => "Component",
156             Interface::NinePinDIN => "DIN",
157             Interface::DisplayPort => "DP",
158             Interface::HDMIA => "HDMI-A",
159             Interface::HDMIB => "HDMI-B",
160             Interface::TV => "TV",
161             Interface::EmbeddedDisplayPort => "eDP",
162             Interface::Virtual => "Virtual",
163             Interface::DSI => "DSI",
164             Interface::DPI => "DPI",
165             Interface::Writeback => "Writeback",
166             Interface::SPI => "SPI",
167             Interface::USB => "USB",
168         }
169     }
170 }
171 
172 impl From<u32> for Interface {
from(n: u32) -> Self173     fn from(n: u32) -> Self {
174         match n {
175             ffi::DRM_MODE_CONNECTOR_Unknown => Interface::Unknown,
176             ffi::DRM_MODE_CONNECTOR_VGA => Interface::VGA,
177             ffi::DRM_MODE_CONNECTOR_DVII => Interface::DVII,
178             ffi::DRM_MODE_CONNECTOR_DVID => Interface::DVID,
179             ffi::DRM_MODE_CONNECTOR_DVIA => Interface::DVIA,
180             ffi::DRM_MODE_CONNECTOR_Composite => Interface::Composite,
181             ffi::DRM_MODE_CONNECTOR_SVIDEO => Interface::SVideo,
182             ffi::DRM_MODE_CONNECTOR_LVDS => Interface::LVDS,
183             ffi::DRM_MODE_CONNECTOR_Component => Interface::Component,
184             ffi::DRM_MODE_CONNECTOR_9PinDIN => Interface::NinePinDIN,
185             ffi::DRM_MODE_CONNECTOR_DisplayPort => Interface::DisplayPort,
186             ffi::DRM_MODE_CONNECTOR_HDMIA => Interface::HDMIA,
187             ffi::DRM_MODE_CONNECTOR_HDMIB => Interface::HDMIB,
188             ffi::DRM_MODE_CONNECTOR_TV => Interface::TV,
189             ffi::DRM_MODE_CONNECTOR_eDP => Interface::EmbeddedDisplayPort,
190             ffi::DRM_MODE_CONNECTOR_VIRTUAL => Interface::Virtual,
191             ffi::DRM_MODE_CONNECTOR_DSI => Interface::DSI,
192             ffi::DRM_MODE_CONNECTOR_DPI => Interface::DPI,
193             ffi::DRM_MODE_CONNECTOR_WRITEBACK => Interface::Writeback,
194             ffi::DRM_MODE_CONNECTOR_SPI => Interface::SPI,
195             ffi::DRM_MODE_CONNECTOR_USB => Interface::USB,
196             _ => Interface::Unknown,
197         }
198     }
199 }
200 
201 impl From<Interface> for u32 {
from(interface: Interface) -> Self202     fn from(interface: Interface) -> Self {
203         match interface {
204             Interface::Unknown => ffi::DRM_MODE_CONNECTOR_Unknown,
205             Interface::VGA => ffi::DRM_MODE_CONNECTOR_VGA,
206             Interface::DVII => ffi::DRM_MODE_CONNECTOR_DVII,
207             Interface::DVID => ffi::DRM_MODE_CONNECTOR_DVID,
208             Interface::DVIA => ffi::DRM_MODE_CONNECTOR_DVIA,
209             Interface::Composite => ffi::DRM_MODE_CONNECTOR_Composite,
210             Interface::SVideo => ffi::DRM_MODE_CONNECTOR_SVIDEO,
211             Interface::LVDS => ffi::DRM_MODE_CONNECTOR_LVDS,
212             Interface::Component => ffi::DRM_MODE_CONNECTOR_Component,
213             Interface::NinePinDIN => ffi::DRM_MODE_CONNECTOR_9PinDIN,
214             Interface::DisplayPort => ffi::DRM_MODE_CONNECTOR_DisplayPort,
215             Interface::HDMIA => ffi::DRM_MODE_CONNECTOR_HDMIA,
216             Interface::HDMIB => ffi::DRM_MODE_CONNECTOR_HDMIB,
217             Interface::TV => ffi::DRM_MODE_CONNECTOR_TV,
218             Interface::EmbeddedDisplayPort => ffi::DRM_MODE_CONNECTOR_eDP,
219             Interface::Virtual => ffi::DRM_MODE_CONNECTOR_VIRTUAL,
220             Interface::DSI => ffi::DRM_MODE_CONNECTOR_DSI,
221             Interface::DPI => ffi::DRM_MODE_CONNECTOR_DPI,
222             Interface::Writeback => ffi::DRM_MODE_CONNECTOR_WRITEBACK,
223             Interface::SPI => ffi::DRM_MODE_CONNECTOR_SPI,
224             Interface::USB => ffi::DRM_MODE_CONNECTOR_USB,
225         }
226     }
227 }
228 
229 /// The state of a connector.
230 #[allow(missing_docs)]
231 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
232 pub enum State {
233     Connected,
234     Disconnected,
235     Unknown,
236 }
237 
238 impl From<u32> for State {
from(n: u32) -> Self239     fn from(n: u32) -> Self {
240         // These variables are not defined in drm_mode.h for some reason.
241         // They were copied from libdrm's xf86DrmMode.h
242         match n {
243             1 => State::Connected,
244             2 => State::Disconnected,
245             _ => State::Unknown,
246         }
247     }
248 }
249 
250 impl From<State> for u32 {
from(state: State) -> Self251     fn from(state: State) -> Self {
252         // These variables are not defined in drm_mode.h for some reason.
253         // They were copied from libdrm's xf86DrmMode.h
254         match state {
255             State::Connected => 1,
256             State::Disconnected => 2,
257             State::Unknown => 3,
258         }
259     }
260 }
261 
262 /// Subpixel order of the connected sink
263 #[non_exhaustive]
264 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
265 pub enum SubPixel {
266     /// Unknown geometry
267     Unknown,
268     /// Horizontal RGB
269     HorizontalRgb,
270     /// Horizontal BGR
271     HorizontalBgr,
272     /// Vertical RGB
273     VerticalRgb,
274     /// Vertical BGR
275     VerticalBgr,
276     /// No geometry
277     None,
278     /// Encountered value not supported by drm-rs
279     NotImplemented,
280 }
281 
282 impl SubPixel {
from_raw(n: u32) -> Self283     pub(super) fn from_raw(n: u32) -> Self {
284         // These values are not defined in drm_mode.h
285         // They were copied from linux's drm_connector.h
286         // Don't mistake those for ones used in xf86DrmMode.h (libdrm offsets those by 1)
287         match n {
288             0 => Self::Unknown,
289             1 => Self::HorizontalRgb,
290             2 => Self::HorizontalBgr,
291             3 => Self::VerticalRgb,
292             4 => Self::VerticalBgr,
293             5 => Self::None,
294             _ => Self::NotImplemented,
295         }
296     }
297 }
298