d00f3c756c8a50fc196fdb2ec221adc584ae44db
1 #include <stdio.h>
2 #include <iostream>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <cassert>
7 #include "kms++.h"
8 #include "helpers.h"
10 using namespace std;
12 #define DEF_CONN(c) [DRM_MODE_CONNECTOR_##c] = #c
14 namespace kms
15 {
17 static const char * connector_names[] = {
18 DEF_CONN(Unknown),
19 DEF_CONN(VGA),
20 DEF_CONN(DVII),
21 DEF_CONN(DVID),
22 DEF_CONN(DVIA),
23 DEF_CONN(Composite),
24 DEF_CONN(SVIDEO),
25 DEF_CONN(LVDS),
26 DEF_CONN(Component),
27 DEF_CONN(9PinDIN),
28 DEF_CONN(DisplayPort),
29 DEF_CONN(HDMIA),
30 DEF_CONN(HDMIB),
31 DEF_CONN(TV),
32 DEF_CONN(eDP),
33 DEF_CONN(VIRTUAL),
34 DEF_CONN(DSI),
35 };
37 static const char *connection_str[] = {
38 [0] = "<unknown>",
39 [DRM_MODE_CONNECTED] = "Connected",
40 [DRM_MODE_DISCONNECTED] = "Disconnected",
41 [DRM_MODE_UNKNOWNCONNECTION] = "Unknown",
42 };
44 struct ConnectorPriv
45 {
46 drmModeConnectorPtr drm_connector;
47 };
49 Connector::Connector(Card &card, uint32_t id, uint32_t idx)
50 :DrmObject(card, id, DRM_MODE_OBJECT_CONNECTOR, idx)
51 {
52 m_priv = new ConnectorPriv();
54 m_priv->drm_connector = drmModeGetConnector(this->card().fd(), this->id());
55 assert(m_priv->drm_connector);
57 auto name = connector_names[m_priv->drm_connector->connector_type];
58 m_fullname = std::string(string(name) + std::to_string(m_priv->drm_connector->connector_type_id));
59 }
62 Connector::~Connector()
63 {
64 drmModeFreeConnector(m_priv->drm_connector);
65 delete m_priv;
66 }
68 void Connector::setup()
69 {
70 if (m_priv->drm_connector->encoder_id != 0)
71 m_current_encoder = card().get_encoder(m_priv->drm_connector->encoder_id);
72 else
73 m_current_encoder = 0;
75 if (m_current_encoder)
76 m_saved_crtc = m_current_encoder->get_crtc();
77 else
78 m_saved_crtc = 0;
79 }
81 void Connector::restore_mode()
82 {
83 if (m_saved_crtc)
84 m_saved_crtc->restore_mode(this);
85 }
87 void Connector::print_short() const
88 {
89 auto c = m_priv->drm_connector;
91 printf("Connector %d, %s, %dx%dmm, %s\n", id(), m_fullname.c_str(),
92 c->mmWidth, c->mmHeight, connection_str[c->connection]);
93 }
95 Videomode Connector::get_default_mode() const
96 {
97 drmModeModeInfo drmmode = m_priv->drm_connector->modes[0];
99 return drm_mode_to_video_mode(drmmode);
100 }
102 Videomode Connector::get_mode(const string& mode) const
103 {
104 auto c = m_priv->drm_connector;
106 for (int i = 0; i < c->count_modes; i++)
107 if (mode == c->modes[i].name)
108 return drm_mode_to_video_mode(c->modes[i]);
110 throw invalid_argument(mode + ": mode not found");
111 }
113 bool Connector::connected() const
114 {
115 return m_priv->drm_connector->connection == DRM_MODE_CONNECTED;
116 }
118 vector<Crtc*> Connector::get_possible_crtcs() const
119 {
120 vector<Crtc*> crtcs;
122 for (int i = 0; i < m_priv->drm_connector->count_encoders; ++i) {
123 auto enc = card().get_encoder(m_priv->drm_connector->encoders[i]);
125 auto l = enc->get_possible_crtcs();
127 crtcs.insert(crtcs.end(), l.begin(), l.end());
128 }
130 return crtcs;
131 }
133 Crtc* Connector::get_current_crtc() const
134 {
135 if (m_current_encoder)
136 return m_current_encoder->get_crtc();
137 else
138 return 0;
139 }
141 }