From 9916712a62169606d845510028a3ea6f84bd442f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Sat, 11 Jun 2016 21:46:24 +0300 Subject: kms++: organize into subdirs --- kms++/src/connector.cpp | 224 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 kms++/src/connector.cpp (limited to 'kms++/src/connector.cpp') 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 +#include +#include +#include +#include + +#include +#include "helpers.h" + +using namespace std; + +namespace kms +{ + + +static const map 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 connection_str = { + { 0, "" }, + { DRM_MODE_CONNECTED, "Connected" }, + { DRM_MODE_DISCONNECTED, "Disconnected" }, + { DRM_MODE_UNKNOWNCONNECTION, "Unknown" }, +}; + +static const map 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 Connector::get_possible_crtcs() const +{ + vector 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 Connector::get_modes() const +{ + vector 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 Connector::get_encoders() const +{ + vector 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; +} + +} -- cgit v1.2.3