diff --git a/CMakeLists.txt b/CMakeLists.txt index da7328e980..936d923c69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,6 +342,7 @@ set_package_properties(QAccessibilityClient6 PROPERTIES set(HAVE_ACCESSIBILITY ${QAccessibilityClient6_FOUND}) find_package(KGlobalAccelD REQUIRED) +pkg_search_module(libdisplayinfo REQUIRED IMPORTED_TARGET libdisplay-info) ecm_find_qmlmodule(QtQuick 2.3) ecm_find_qmlmodule(QtQuick.Controls 2.15) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eb779370d6..0e0044799a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -230,6 +230,7 @@ target_link_libraries(kwin Threads::Threads Wayland::Server lcms2::lcms2 + PkgConfig::libdisplayinfo ) if (KWIN_BUILD_NOTIFICATIONS) diff --git a/src/utils/edid.cpp b/src/utils/edid.cpp index 0f47cd05f3..4d53951d28 100644 --- a/src/utils/edid.cpp +++ b/src/utils/edid.cpp @@ -9,6 +9,7 @@ */ #include "edid.h" +#include "c_ptr.h" #include "config-kwin.h" #include @@ -17,26 +18,13 @@ #include #include -namespace KWin -{ - -static bool verifyHeader(const uint8_t *data) -{ - if (data[0] != 0x0 || data[7] != 0x0) { - return false; - } - - return std::all_of(data + 1, data + 7, - [](uint8_t byte) { - return byte == 0xff; - }); +extern "C" { +#include +#include } -static QSize parsePhysicalSize(const uint8_t *data) +namespace KWin { - // Convert physical size from centimeters to millimeters. - return QSize(data[0x15], data[0x16]) * 10; -} static QByteArray parsePnpId(const uint8_t *data) { @@ -83,57 +71,6 @@ static QByteArray parseEisaId(const uint8_t *data) return parsePnpId(data); } -static QByteArray parseMonitorName(const uint8_t *data) -{ - for (int i = 72; i <= 108; i += 18) { - // Skip the block if it isn't used as monitor descriptor. - if (data[i]) { - continue; - } - if (data[i + 1]) { - continue; - } - - // We have found the monitor name, it's stored as ASCII. - if (data[i + 3] == 0xfc) { - return QByteArray(reinterpret_cast(&data[i + 5]), 13).trimmed(); - } - } - - return QByteArray(); -} - -static QByteArray parseSerialNumber(const uint8_t *data) -{ - for (int i = 72; i <= 108; i += 18) { - // Skip the block if it isn't used as monitor descriptor. - if (data[i]) { - continue; - } - if (data[i + 1]) { - continue; - } - - // We have found the serial number, it's stored as ASCII. - if (data[i + 3] == 0xff) { - return QByteArray(reinterpret_cast(&data[i + 5]), 13).trimmed(); - } - } - - // Maybe there isn't an ASCII serial number descriptor, so use this instead. - const uint32_t offset = 0xc; - - uint32_t serialNumber = data[offset + 0]; - serialNumber |= uint32_t(data[offset + 1]) << 8; - serialNumber |= uint32_t(data[offset + 2]) << 16; - serialNumber |= uint32_t(data[offset + 3]) << 24; - if (serialNumber) { - return QByteArray::number(serialNumber); - } - - return QByteArray(); -} - static QByteArray parseVendor(const uint8_t *data) { const auto pnpId = parsePnpId(data); @@ -163,24 +100,26 @@ Edid::Edid(const void *data, uint32_t size) const uint8_t *bytes = static_cast(data); - if (size < 128) { - return; - } - - if (!verifyHeader(bytes)) { + auto info = di_info_parse_edid(data, size); + if (!info) { return; } + const di_edid *edid = di_info_get_edid(info); + const di_edid_vendor_product *productInfo = di_edid_get_vendor_product(edid); + const di_edid_screen_size *screenSize = di_edid_get_screen_size(edid); - m_physicalSize = parsePhysicalSize(bytes); + m_physicalSize = QSize(screenSize->width_cm, screenSize->height_cm) * 10; m_eisaId = parseEisaId(bytes); - m_monitorName = parseMonitorName(bytes); - m_serialNumber = parseSerialNumber(bytes); + UniqueCPtr monitorName{di_info_get_model(info)}; + m_monitorName = QByteArray(monitorName.get()); + m_serialNumber = QByteArray::number(productInfo->serial); m_vendor = parseVendor(bytes); QCryptographicHash hash(QCryptographicHash::Md5); hash.addData(m_raw); m_hash = QString::fromLatin1(hash.result().toHex()); m_isValid = true; + di_info_destroy(info); } bool Edid::isValid() const