2 * Copyright (C) 2005-2020 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "DRMConnector.h"
11 #include "utils/XTimeUtils.h"
12 #include "utils/log.h"
17 using namespace KODI::WINDOWING::GBM
;
19 using namespace std::chrono_literals
;
24 std::map
<int, std::string
> connectorTypeNames
= {
25 {DRM_MODE_CONNECTOR_Unknown
, "unknown"},
26 {DRM_MODE_CONNECTOR_VGA
, "VGA"},
27 {DRM_MODE_CONNECTOR_DVII
, "DVI-I"},
28 {DRM_MODE_CONNECTOR_DVID
, "DVI-D"},
29 {DRM_MODE_CONNECTOR_DVIA
, "DVI-A"},
30 {DRM_MODE_CONNECTOR_Composite
, "composite"},
31 {DRM_MODE_CONNECTOR_SVIDEO
, "s-video"},
32 {DRM_MODE_CONNECTOR_LVDS
, "LVDS"},
33 {DRM_MODE_CONNECTOR_Component
, "component"},
34 {DRM_MODE_CONNECTOR_9PinDIN
, "9-pin DIN"},
35 {DRM_MODE_CONNECTOR_DisplayPort
, "DP"},
36 {DRM_MODE_CONNECTOR_HDMIA
, "HDMI-A"},
37 {DRM_MODE_CONNECTOR_HDMIB
, "HDMI-B"},
38 {DRM_MODE_CONNECTOR_TV
, "TV"},
39 {DRM_MODE_CONNECTOR_eDP
, "eDP"},
40 {DRM_MODE_CONNECTOR_VIRTUAL
, "Virtual"},
41 {DRM_MODE_CONNECTOR_DSI
, "DSI"},
42 {DRM_MODE_CONNECTOR_DPI
, "DPI"},
45 std::map
<drmModeConnection
, std::string
> connectorStatusNames
= {
46 {DRM_MODE_CONNECTED
, "connected"},
47 {DRM_MODE_DISCONNECTED
, "disconnected"},
48 {DRM_MODE_UNKNOWNCONNECTION
, "unknown"},
53 CDRMConnector::CDRMConnector(int fd
, uint32_t connector
)
54 : CDRMObject(fd
), m_connector(drmModeGetConnector(m_fd
, connector
))
57 throw std::runtime_error("drmModeGetConnector failed: " + std::string
{strerror(errno
)});
59 if (!GetProperties(m_connector
->connector_id
, DRM_MODE_OBJECT_CONNECTOR
))
60 throw std::runtime_error("failed to get properties for connector: " +
61 std::to_string(m_connector
->connector_id
));
64 bool CDRMConnector::CheckConnector()
66 unsigned retryCnt
= 7;
67 while (!IsConnected() && retryCnt
> 0)
69 CLog::Log(LOGDEBUG
, "CDRMConnector::{} - connector is disconnected", __FUNCTION__
);
71 KODI::TIME::Sleep(1s
);
73 m_connector
.reset(drmModeGetConnector(m_fd
, m_connector
->connector_id
));
76 return m_connector
->connection
== DRM_MODE_CONNECTED
;
79 std::string
CDRMConnector::GetType()
81 auto typeName
= connectorTypeNames
.find(m_connector
->connector_type
);
82 if (typeName
== connectorTypeNames
.end())
83 return connectorTypeNames
[DRM_MODE_CONNECTOR_Unknown
];
85 return typeName
->second
;
88 std::string
CDRMConnector::GetStatus()
90 auto statusName
= connectorStatusNames
.find(m_connector
->connection
);
91 if (statusName
== connectorStatusNames
.end())
92 return connectorStatusNames
[DRM_MODE_UNKNOWNCONNECTION
];
94 return statusName
->second
;
97 std::string
CDRMConnector::GetName()
99 return GetType() + "-" + std::to_string(m_connector
->connector_type_id
);
102 std::vector
<uint8_t> CDRMConnector::GetEDID() const
104 auto property
= std::find_if(m_propsInfo
.begin(), m_propsInfo
.end(),
105 [](auto& prop
) { return prop
->name
== std::string_view("EDID"); });
107 if (property
== m_propsInfo
.end())
109 CLog::LogF(LOGDEBUG
, "failed to find EDID property for connector: {}",
110 m_connector
->connector_id
);
114 uint64_t blob_id
= m_props
->prop_values
[std::distance(m_propsInfo
.begin(), property
)];
118 drmModePropertyBlobPtr blob
= drmModeGetPropertyBlob(m_fd
, blob_id
);
122 auto data
= static_cast<uint8_t*>(blob
->data
);
123 auto edid
= std::vector
<uint8_t>(data
, data
+ blob
->length
);
125 drmModeFreePropertyBlob(blob
);