From 1bb382d1b6d3bb6cd163653d66924e4e99aa2a84 Mon Sep 17 00:00:00 2001 From: gongheng Date: Tue, 29 Jul 2025 19:31:33 +0800 Subject: [PATCH] Feat: [Monitor] The monitor name show error. -- parse the edid ,and show the right monitor name. Log: add feature for Monitor. Task: https://pms.uniontech.com/task-view-379819.html --- .../src/DeviceManager/DeviceMonitor.cpp | 11 +++ .../src/DeviceManager/DeviceMonitor.h | 2 + .../src/GenerateDevice/CustomGenerator.cpp | 2 +- .../src/GenerateDevice/HWGenerator.cpp | 2 +- deepin-devicemanager/src/Tool/EDIDParser.cpp | 68 +++++++++++++++- deepin-devicemanager/src/Tool/EDIDParser.h | 12 +++ deepin-devicemanager/src/Tool/commontools.cpp | 80 ++++++++++++++----- deepin-devicemanager/src/Tool/commontools.h | 2 +- 8 files changed, 154 insertions(+), 25 deletions(-) diff --git a/deepin-devicemanager/src/DeviceManager/DeviceMonitor.cpp b/deepin-devicemanager/src/DeviceManager/DeviceMonitor.cpp index b590dad6..7d78cc47 100644 --- a/deepin-devicemanager/src/DeviceManager/DeviceMonitor.cpp +++ b/deepin-devicemanager/src/DeviceManager/DeviceMonitor.cpp @@ -164,6 +164,17 @@ void DeviceMonitor::setInfoFromEdid(const QMap &mapInfo) getOtherMapInfo(mapInfo); } +void DeviceMonitor::setInfoFromEdidForCustom(const QMap &mapInfo) +{ + setAttribute(mapInfo, "Size", m_ScreenSize); + setAttribute(mapInfo, "Vendor", m_Vendor); + setAttribute(mapInfo, "Date", m_ProductionWeek); + setAttribute(mapInfo, "Display Input", m_DisplayInput); + setAttribute(mapInfo, "Model", m_Model); + m_Name = m_Model; + getOtherMapInfo(mapInfo); +} + void DeviceMonitor::setInfoFromDbus(const QMap &mapInfo) { if (mapInfo["Name"].toLower().contains(m_DisplayInput.toLower(), Qt::CaseInsensitive)) { diff --git a/deepin-devicemanager/src/DeviceManager/DeviceMonitor.h b/deepin-devicemanager/src/DeviceManager/DeviceMonitor.h index bd32d2b4..22bdb222 100644 --- a/deepin-devicemanager/src/DeviceManager/DeviceMonitor.h +++ b/deepin-devicemanager/src/DeviceManager/DeviceMonitor.h @@ -67,6 +67,8 @@ class DeviceMonitor : public DeviceBaseInfo */ void setInfoFromEdid(const QMap &mapInfo); + void setInfoFromEdidForCustom(const QMap &mapInfo); + /**@brief:华为PanGuV项目里面的显示屏信息是从dbus里面获取的*/ /** * @brief setInfoFromDbus:设置华为PanGuV项目里面的显示屏信息 diff --git a/deepin-devicemanager/src/GenerateDevice/CustomGenerator.cpp b/deepin-devicemanager/src/GenerateDevice/CustomGenerator.cpp index 046250a8..f7f661ce 100644 --- a/deepin-devicemanager/src/GenerateDevice/CustomGenerator.cpp +++ b/deepin-devicemanager/src/GenerateDevice/CustomGenerator.cpp @@ -86,7 +86,7 @@ void CustomGenerator::generatorMonitorDevice() QStringList allEDIDS_all; allEDIDS_all.append(fileInfo.filePath() + "/" + "edid"); QString interface = fileInfo.fileName().remove("card0-").remove("card1-").remove("card2-"); - CommonTools::parseEDID(allEDIDS_all, interface); + CommonTools::parseEDID(allEDIDS_all, interface, false); } } } diff --git a/deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp b/deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp index 32c2d4ba..a279be32 100644 --- a/deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp +++ b/deepin-devicemanager/src/GenerateDevice/HWGenerator.cpp @@ -430,7 +430,7 @@ void HWGenerator::generatorMonitorDevice() QStringList allEDIDS_all; allEDIDS_all.append(fileInfo.filePath() + "/" + "edid"); QString interface = fileInfo.fileName().remove("card0-").remove("card1-").remove("card2-"); - CommonTools::parseEDID(allEDIDS_all,interface); + CommonTools::parseEDID(allEDIDS_all, interface, true); } } } diff --git a/deepin-devicemanager/src/Tool/EDIDParser.cpp b/deepin-devicemanager/src/Tool/EDIDParser.cpp index 082adbaa..634488ef 100644 --- a/deepin-devicemanager/src/Tool/EDIDParser.cpp +++ b/deepin-devicemanager/src/Tool/EDIDParser.cpp @@ -78,7 +78,8 @@ bool EDIDParser::setEdid(const QString &edid, QString &errorMsg, const QString & parseReleaseDate(); // 解析屏幕尺寸 parseScreenSize(); - + // 解析监视器名称 + parseMonitorName(); return true; } @@ -103,6 +104,11 @@ const QString &EDIDParser::screenSize()const return m_ScreenSize; } +const QString &EDIDParser::monitorName() const +{ + return m_MonitorName; +} + int EDIDParser::width() { return m_Width; @@ -213,6 +219,66 @@ void EDIDParser::parseScreenSize() m_ScreenSize = QString("%1 %2(%3mm×%4mm)").arg(QString::number(inch, '0', Common::specialComType == 7 ? 0 : 1)).arg(QObject::tr("inch")).arg(m_Width).arg(m_Height); } +void EDIDParser::parseMonitorName() +{ + // EDID中从字节54开始有4个18字节的Descriptor Block + // 每个Descriptor Block可能包含显示器名称信息 + // 显示器名称的标识符是0xFC(Display Product Name) 注意:部分机型有一些特殊,标识符为0xFE + + // 4个Descriptor Block的起始字节位置 + int descriptorStarts[4] = {54, 72, 90, 108}; + + for (int i = 0; i < 4; i++) { + int startByte = descriptorStarts[i]; + + // 计算行号和字节位置(每行16字节) + int line = startByte / 16; + int byteInLine = startByte % 16; + + // 获取Descriptor Block的关键字节 + QString byte0 = getBytes(line, byteInLine); // 第0字节 + QString byte1 = getBytes(line, byteInLine + 1); // 第1字节 + QString byte3 = getBytes(line, byteInLine + 3); // 第3字节(类型标识) + + // 检查是否为Display Descriptor (字节0-1为0x0000) 且类型为Display Product Name (字节3为0xFC) + if (byte0.toUpper() == "00" && byte1.toUpper() == "00" && (byte3.toUpper() == "FC" || byte3.toUpper() == "FE")) { + + // 找到显示器名称描述符,提取ASCII字符串(字节5-17) + QString monitorName; + + for (int j = 5; j <= 17; j++) { + int currentByte = startByte + j; + int currentLine = currentByte / 16; + int currentByteInLine = currentByte % 16; + + QString charByte = getBytes(currentLine, currentByteInLine); + + if (!charByte.isEmpty()) { + int asciiValue = hexToDec(charByte).toInt(); + + // ASCII可打印字符范围:32-126,0x0A为换行符,0x00为结束符 + if (asciiValue == 0x00 || asciiValue == 0x0A) { + break; // 遇到结束符或换行符,停止解析 + } else if (asciiValue >= 32 && asciiValue <= 126) { + monitorName.append(QChar(asciiValue)); + } + } + } + + // 去除首尾空白字符 + m_MonitorName = monitorName.trimmed(); + + // 如果找到有效的监视器名称,记录日志并返回 + if (!m_MonitorName.isEmpty()) + return; + } + } + + // 如果没有找到有效的监视器名称,设置默认值 + if (m_MonitorName.isEmpty()) + m_MonitorName = "Unknown Monitor"; +} + QString EDIDParser::binToDec(QString strBin) //二进制转十进制 { // 二进制转十进制 diff --git a/deepin-devicemanager/src/Tool/EDIDParser.h b/deepin-devicemanager/src/Tool/EDIDParser.h index 0f7118f5..abc538d1 100644 --- a/deepin-devicemanager/src/Tool/EDIDParser.h +++ b/deepin-devicemanager/src/Tool/EDIDParser.h @@ -52,6 +52,12 @@ class EDIDParser */ const QString &screenSize()const; + /** + * @brief screenSize:获取监视器名称 + * @return 监视器名称 + */ + const QString &monitorName()const; + /** * @brief width : get screen width * @return @@ -81,6 +87,11 @@ class EDIDParser */ void parseScreenSize(); + /** + * @brief parseScreenSize:从edid中获取监视器名称 + */ + void parseMonitorName(); + /** * @brief binToDec:将二进制转换成十进制 * @param strBin:二进制字符串 @@ -140,6 +151,7 @@ class EDIDParser QString m_Model; // 显示屏的型号信息 QString m_ReleaseDate; // 显示屏的生产日期 QString m_ScreenSize; // 屏幕大小 + QString m_MonitorName; // 监视器名称 bool m_LittleEndianMode; // 小端模式 int m_Width; // width int m_Height; // heigth diff --git a/deepin-devicemanager/src/Tool/commontools.cpp b/deepin-devicemanager/src/Tool/commontools.cpp index 2cf89c6e..dcebeec7 100644 --- a/deepin-devicemanager/src/Tool/commontools.cpp +++ b/deepin-devicemanager/src/Tool/commontools.cpp @@ -167,45 +167,83 @@ QString CommonTools::getBackupPath() return "/usr/share/deepin-devicemanager/"; } -void CommonTools::parseEDID(const QStringList &allEDIDS, const QString &input) +void CommonTools::parseEDID(const QStringList &allEDIDS, const QString &input, bool isHW) { for (auto edid:allEDIDS) { - QProcess process; - process.start(QString("hexdump %1").arg(edid)); - process.waitForFinished(-1); + QString edidStr; + if (isHW) { + QProcess process; + process.start(QString("hexdump %1").arg(edid)); + process.waitForFinished(-1); - QString deviceInfo = process.readAllStandardOutput(); - if (deviceInfo.isEmpty()) - continue; + QString deviceInfo = process.readAllStandardOutput(); + if (deviceInfo.isEmpty()) + continue; - QString edidStr; - QStringList lines = deviceInfo.split("\n"); - for (auto line:lines) { - QStringList words = line.trimmed().split(" "); - if (words.size() != 9) + QStringList lines = deviceInfo.split("\n"); + for (auto line:lines) { + QStringList words = line.trimmed().split(" "); + if (words.size() != 9) + continue; + + words.removeAt(0); + QString l = words.join(""); + l.append("\n"); + edidStr.append(l); + } + } else { + QProcess process; + process.start(QString("hexdump -C %1").arg(edid)); + process.waitForFinished(-1); + QString deviceInfo = process.readAllStandardOutput(); + if (deviceInfo.isEmpty()) continue; - words.removeAt(0); - QString l = words.join(""); - l.append("\n"); - edidStr.append(l); + QStringList lines = deviceInfo.split("\n"); + for (auto line: lines) { + if (line.trimmed().isEmpty()) + continue; + int firstSpace = line.indexOf(" "); + int lastPipe = line.indexOf("|"); + + if (firstSpace == -1 || lastPipe == -1 || firstSpace >= lastPipe) + continue; + + QString hexPart = line.mid(firstSpace + 2, lastPipe - firstSpace -3).trimmed(); + + QStringList hexBytes = hexPart.split(QRegExp("\\s+")); + + QString lineData; + for (const QString &hexByte : hexBytes) { + if (hexByte.length() == 2 && hexByte != "") + lineData.append(hexByte); + } + + if (lineData.length() == 32) + edidStr.append(lineData + "\n"); + } } - lines = edidStr.split("\n"); + QStringList lines = edidStr.split("\n"); if (lines.size() > 3){ EDIDParser edidParser; QString errorMsg; - edidParser.setEdid(edidStr,errorMsg,"\n", false); + edidParser.setEdid(edidStr,errorMsg,"\n", isHW ? false : true); QMap mapInfo; mapInfo.insert("Vendor",edidParser.vendor()); - mapInfo.insert("Model",edidParser.model()); - //mapInfo.insert("Date",edidParser.releaseDate()); + if (isHW) + mapInfo.insert("Model",edidParser.model()); + else + mapInfo.insert("Model",edidParser.monitorName()); mapInfo.insert("Size",edidParser.screenSize()); mapInfo.insert("Display Input",input); DeviceMonitor *device = new DeviceMonitor(); - device->setInfoFromEdid(mapInfo); + if (isHW) + device->setInfoFromEdid(mapInfo); + else + device->setInfoFromEdidForCustom(mapInfo); DeviceManager::instance()->addMonitor(device); } } diff --git a/deepin-devicemanager/src/Tool/commontools.h b/deepin-devicemanager/src/Tool/commontools.h index 71b2bc89..96ec149a 100644 --- a/deepin-devicemanager/src/Tool/commontools.h +++ b/deepin-devicemanager/src/Tool/commontools.h @@ -78,7 +78,7 @@ class CommonTools : public QObject */ static QString getBackupPath(); - static void parseEDID(const QStringList &allEDIDS, const QString &input); + static void parseEDID(const QStringList &allEDIDS, const QString &input, bool isHW = true); static QString getGpuInfoCommandFromDConfig(); signals: