summaryrefslogtreecommitdiff
path: root/kms++/src/connector.cpp
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2016-06-11 21:46:24 +0300
committerTomi Valkeinen <tomi.valkeinen@ti.com>2016-06-11 21:46:24 +0300
commit9916712a62169606d845510028a3ea6f84bd442f (patch)
treeaca4e1bec39500812111c43a8ecee862edae0002 /kms++/src/connector.cpp
parent736b295100ce441e800457bcbd08cb36db543ff2 (diff)
kms++: organize into subdirs
Diffstat (limited to 'kms++/src/connector.cpp')
-rw-r--r--kms++/src/connector.cpp224
1 files changed, 224 insertions, 0 deletions
diff --git a/kms++/src/connector.cpp b/kms++/src/connector.cpp
new file mode 100644
index 0000000..ec37d5d
--- /dev/null
+++ b/kms++/src/connector.cpp
@@ -0,0 +1,224 @@
+#include <stdio.h>
+#include <iostream>
+#include <unistd.h>
+#include <fcntl.h>
+#include <cassert>
+
+#include <kms++/kms++.h>
+#include "helpers.h"
+
+using namespace std;
+
+namespace kms
+{
+
+
+static const map<int, string> connector_names = {
+ { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
+ { DRM_MODE_CONNECTOR_VGA, "VGA" },
+ { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
+ { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
+ { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
+ { DRM_MODE_CONNECTOR_Composite, "Composite" },
+ { DRM_MODE_CONNECTOR_SVIDEO, "S-Video" },
+ { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
+ { DRM_MODE_CONNECTOR_Component, "Component" },
+ { DRM_MODE_CONNECTOR_9PinDIN, "9-Pin-DIN" },
+ { DRM_MODE_CONNECTOR_DisplayPort, "DP" },
+ { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
+ { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
+ { DRM_MODE_CONNECTOR_TV, "TV" },
+ { DRM_MODE_CONNECTOR_eDP, "eDP" },
+ { DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },
+ { DRM_MODE_CONNECTOR_DSI, "DSI" },
+};
+
+static const map<int, string> connection_str = {
+ { 0, "<unknown>" },
+ { DRM_MODE_CONNECTED, "Connected" },
+ { DRM_MODE_DISCONNECTED, "Disconnected" },
+ { DRM_MODE_UNKNOWNCONNECTION, "Unknown" },
+};
+
+static const map<int, string> subpix_str = {
+#define DEF_SUBPIX(c) { DRM_MODE_SUBPIXEL_##c, #c }
+ DEF_SUBPIX(UNKNOWN),
+ DEF_SUBPIX(HORIZONTAL_RGB),
+ DEF_SUBPIX(HORIZONTAL_BGR),
+ DEF_SUBPIX(VERTICAL_RGB),
+ DEF_SUBPIX(VERTICAL_BGR),
+ DEF_SUBPIX(NONE),
+#undef DEF_SUBPIX
+};
+
+struct ConnectorPriv
+{
+ drmModeConnectorPtr drm_connector;
+};
+
+Connector::Connector(Card &card, uint32_t id, uint32_t idx)
+ :DrmPropObject(card, id, DRM_MODE_OBJECT_CONNECTOR, idx)
+{
+ m_priv = new ConnectorPriv();
+
+ m_priv->drm_connector = drmModeGetConnector(this->card().fd(), this->id());
+ assert(m_priv->drm_connector);
+
+ // XXX drmModeGetConnector() does forced probe, which seems to change (at least) EDID blob id.
+ // XXX So refresh the props again here.
+ refresh_props();
+
+ const auto& name = connector_names.at(m_priv->drm_connector->connector_type);
+ m_fullname = name + "-" + to_string(m_priv->drm_connector->connector_type_id);
+}
+
+
+Connector::~Connector()
+{
+ drmModeFreeConnector(m_priv->drm_connector);
+ delete m_priv;
+}
+
+void Connector::setup()
+{
+ if (m_priv->drm_connector->encoder_id != 0)
+ m_current_encoder = card().get_encoder(m_priv->drm_connector->encoder_id);
+ else
+ m_current_encoder = 0;
+
+ if (m_current_encoder)
+ m_saved_crtc = m_current_encoder->get_crtc();
+ else
+ m_saved_crtc = 0;
+}
+
+void Connector::restore_mode()
+{
+ if (m_saved_crtc)
+ m_saved_crtc->restore_mode(this);
+}
+
+Videomode Connector::get_default_mode() const
+{
+ if (m_priv->drm_connector->count_modes == 0)
+ throw invalid_argument("no modes available\n");
+ drmModeModeInfo drmmode = m_priv->drm_connector->modes[0];
+
+ return drm_mode_to_video_mode(drmmode);
+}
+
+Videomode Connector::get_mode(const string& mode) const
+{
+ auto c = m_priv->drm_connector;
+
+ for (int i = 0; i < c->count_modes; i++)
+ if (mode == c->modes[i].name)
+ return drm_mode_to_video_mode(c->modes[i]);
+
+ throw invalid_argument(mode + ": mode not found");
+}
+
+Videomode Connector::get_mode(unsigned xres, unsigned yres, unsigned refresh, bool ilace) const
+{
+ auto c = m_priv->drm_connector;
+
+ for (int i = 0; i < c->count_modes; i++) {
+ drmModeModeInfo& m = c->modes[i];
+
+ if (m.hdisplay != xres || m.vdisplay != yres)
+ continue;
+
+ if (refresh && m.vrefresh != refresh)
+ continue;
+
+ if (ilace != !!(m.flags & DRM_MODE_FLAG_INTERLACE))
+ continue;
+
+ return drm_mode_to_video_mode(c->modes[i]);
+ }
+
+ throw invalid_argument("mode not found");
+}
+
+bool Connector::connected() const
+{
+ return m_priv->drm_connector->connection == DRM_MODE_CONNECTED ||
+ m_priv->drm_connector->connection == DRM_MODE_UNKNOWNCONNECTION;
+}
+
+vector<Crtc*> Connector::get_possible_crtcs() const
+{
+ vector<Crtc*> crtcs;
+
+ for (int i = 0; i < m_priv->drm_connector->count_encoders; ++i) {
+ auto enc = card().get_encoder(m_priv->drm_connector->encoders[i]);
+
+ auto l = enc->get_possible_crtcs();
+
+ crtcs.insert(crtcs.end(), l.begin(), l.end());
+ }
+
+ return crtcs;
+}
+
+Crtc* Connector::get_current_crtc() const
+{
+ if (m_current_encoder)
+ return m_current_encoder->get_crtc();
+ else
+ return 0;
+}
+
+uint32_t Connector::connector_type() const
+{
+ return m_priv->drm_connector->connector_type;
+}
+
+uint32_t Connector::connector_type_id() const
+{
+ return m_priv->drm_connector->connector_type_id;
+}
+
+uint32_t Connector::mmWidth() const
+{
+ return m_priv->drm_connector->mmWidth;
+}
+
+uint32_t Connector::mmHeight() const
+{
+ return m_priv->drm_connector->mmHeight;
+}
+
+uint32_t Connector::subpixel() const
+{
+ return m_priv->drm_connector->subpixel;
+}
+
+const string& Connector::subpixel_str() const
+{
+ return subpix_str.at(subpixel());
+}
+
+std::vector<Videomode> Connector::get_modes() const
+{
+ vector<Videomode> modes;
+
+ for (int i = 0; i < m_priv->drm_connector->count_modes; i++)
+ modes.push_back(drm_mode_to_video_mode(
+ m_priv->drm_connector->modes[i]));
+
+ return modes;
+}
+
+std::vector<Encoder*> Connector::get_encoders() const
+{
+ vector<Encoder*> encoders;
+
+ for (int i = 0; i < m_priv->drm_connector->count_encoders; i++) {
+ auto enc = card().get_encoder(m_priv->drm_connector->encoders[i]);
+ encoders.push_back(enc);
+ }
+ return encoders;
+}
+
+}