libkms++/connector: Add methods for getting details of the DRM object
[android/external-libkmsxx.git] / libkms++ / connector.cpp
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 namespace kms
13 {
16 static const map<int, string> connector_names = {
17 #define DEF_CONN(c) { DRM_MODE_CONNECTOR_##c, #c }
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 #undef DEF_CONN
36 };
38 static const map<int, string> connection_str = {
39         { 0, "<unknown>" },
40         { DRM_MODE_CONNECTED, "Connected" },
41         { DRM_MODE_DISCONNECTED, "Disconnected" },
42         { DRM_MODE_UNKNOWNCONNECTION, "Unknown" },
43 };
45 static const map<int, string> subpix_str = {
46 #define DEF_SUBPIX(c) { DRM_MODE_SUBPIXEL_##c, #c }
47         DEF_SUBPIX(UNKNOWN),
48         DEF_SUBPIX(HORIZONTAL_RGB),
49         DEF_SUBPIX(HORIZONTAL_BGR),
50         DEF_SUBPIX(VERTICAL_RGB),
51         DEF_SUBPIX(VERTICAL_BGR),
52         DEF_SUBPIX(NONE),
53 #undef DEF_SUBPIX
54 };
56 struct ConnectorPriv
57 {
58         drmModeConnectorPtr drm_connector;
59 };
61 Connector::Connector(Card &card, uint32_t id, uint32_t idx)
62         :DrmObject(card, id, DRM_MODE_OBJECT_CONNECTOR, idx)
63 {
64         m_priv = new ConnectorPriv();
66         m_priv->drm_connector = drmModeGetConnector(this->card().fd(), this->id());
67         assert(m_priv->drm_connector);
69         const auto& name = connector_names.at(m_priv->drm_connector->connector_type);
70         m_fullname = name + to_string(m_priv->drm_connector->connector_type_id);
71 }
74 Connector::~Connector()
75 {
76         drmModeFreeConnector(m_priv->drm_connector);
77         delete m_priv;
78 }
80 void Connector::setup()
81 {
82         if (m_priv->drm_connector->encoder_id != 0)
83                 m_current_encoder = card().get_encoder(m_priv->drm_connector->encoder_id);
84         else
85                 m_current_encoder = 0;
87         if (m_current_encoder)
88                 m_saved_crtc = m_current_encoder->get_crtc();
89         else
90                 m_saved_crtc = 0;
91 }
93 void Connector::restore_mode()
94 {
95         if (m_saved_crtc)
96                 m_saved_crtc->restore_mode(this);
97 }
99 void Connector::print_short() const
101         auto c = m_priv->drm_connector;
103         printf("Connector %d, %s, %dx%dmm, %s\n", id(), m_fullname.c_str(),
104                c->mmWidth, c->mmHeight, connection_str.at(c->connection).c_str());
107 Videomode Connector::get_default_mode() const
109         drmModeModeInfo drmmode = m_priv->drm_connector->modes[0];
111         return drm_mode_to_video_mode(drmmode);
114 Videomode Connector::get_mode(const string& mode) const
116         auto c = m_priv->drm_connector;
118         for (int i = 0; i < c->count_modes; i++)
119                 if (mode == c->modes[i].name)
120                         return drm_mode_to_video_mode(c->modes[i]);
122         throw invalid_argument(mode + ": mode not found");
125 bool Connector::connected() const
127         return m_priv->drm_connector->connection == DRM_MODE_CONNECTED;
130 vector<Crtc*> Connector::get_possible_crtcs() const
132         vector<Crtc*> crtcs;
134         for (int i = 0; i < m_priv->drm_connector->count_encoders; ++i) {
135                 auto enc = card().get_encoder(m_priv->drm_connector->encoders[i]);
137                 auto l = enc->get_possible_crtcs();
139                 crtcs.insert(crtcs.end(), l.begin(), l.end());
140         }
142         return crtcs;
145 Crtc* Connector::get_current_crtc() const
147         if (m_current_encoder)
148                 return m_current_encoder->get_crtc();
149         else
150                 return 0;
153 uint32_t Connector::connector_type() const
155         return m_priv->drm_connector->connector_type;
158 uint32_t Connector::connector_type_id() const
160         return m_priv->drm_connector->connector_type_id;
163 uint32_t Connector::mmWidth() const
165         return m_priv->drm_connector->mmWidth;
168 uint32_t Connector::mmHeight() const
170         return m_priv->drm_connector->mmHeight;
173 uint32_t Connector::subpixel() const
175         return m_priv->drm_connector->subpixel;
178 const string& Connector::subpixel_str() const
180         return subpix_str.at(subpixel());
183 std::vector<Videomode> Connector::get_modes() const
185         vector<Videomode> modes;
187         for (int i = 0; i < m_priv->drm_connector->count_modes; i++)
188                 modes.push_back(drm_mode_to_video_mode(
189                                         m_priv->drm_connector->modes[i]));
191         return modes;
194 std::vector<Encoder*> Connector::get_encoders() const
196         vector<Encoder*> encoders;
198         for (int i = 0; i < m_priv->drm_connector->count_encoders; i++) {
199                 auto enc = card().get_encoder(m_priv->drm_connector->encoders[i]);
200                 encoders.push_back(enc);
201         }
202         return encoders;