From 24d865ea386654e3856a69277179b082ac2218f4 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Tue, 6 Apr 2021 23:08:02 +0300 Subject: [PATCH] wayland: Generate valid output uuids Currently, kwin generates invalid output uuids. --- src/abstract_output.cpp | 4 ++-- src/abstract_output.h | 3 ++- src/abstract_wayland_output.cpp | 16 +++++++++++++--- src/abstract_wayland_output.h | 6 +++--- src/platform.cpp | 2 +- src/platform.h | 2 +- src/plugins/platforms/drm/drm_backend.cpp | 8 ++++---- src/plugins/platforms/drm/drm_output.cpp | 15 ++------------- src/plugins/platforms/drm/drm_output.h | 2 -- src/plugins/platforms/fbdev/fb_backend.cpp | 2 +- src/plugins/platforms/virtual/virtual_output.cpp | 1 - src/plugins/platforms/wayland/wayland_output.cpp | 2 +- .../x11/windowed/x11windowed_output.cpp | 2 +- 13 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/abstract_output.cpp b/src/abstract_output.cpp index 3756e27424..b4ce9c2813 100644 --- a/src/abstract_output.cpp +++ b/src/abstract_output.cpp @@ -83,9 +83,9 @@ AbstractOutput::~AbstractOutput() { } -QString AbstractOutput::uuid() const +QUuid AbstractOutput::uuid() const { - return QString(); + return QUuid(); } bool AbstractOutput::isEnabled() const diff --git a/src/abstract_output.h b/src/abstract_output.h index cf751017b9..8e3b8a0bc3 100644 --- a/src/abstract_output.h +++ b/src/abstract_output.h @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace KWaylandServer @@ -102,7 +103,7 @@ public: * * Default implementation returns an empty byte array. */ - virtual QString uuid() const; + virtual QUuid uuid() const; /** * Returns @c true if the output is enabled; otherwise returns @c false. diff --git a/src/abstract_wayland_output.cpp b/src/abstract_wayland_output.cpp index f6ba7f680d..1dd219d219 100644 --- a/src/abstract_wayland_output.cpp +++ b/src/abstract_wayland_output.cpp @@ -45,7 +45,7 @@ QString AbstractWaylandOutput::name() const return m_name; } -QString AbstractWaylandOutput::uuid() const +QUuid AbstractWaylandOutput::uuid() const { return m_uuid; } @@ -211,9 +211,19 @@ void AbstractWaylandOutput::setCurrentModeInternal(const QSize &size, int refres } } +static QUuid generateOutputId(const QString &eisaId, const QString &model, + const QString &serialNumber, const QString &name) +{ + static const QUuid urlNs = QUuid("6ba7b811-9dad-11d1-80b4-00c04fd430c8"); // NameSpace_URL + static const QUuid kwinNs = QUuid::createUuidV5(urlNs, QStringLiteral("https://kwin.kde.org/o/")); + + const QString payload = QStringList{name, eisaId, model, serialNumber}.join(':'); + return QUuid::createUuidV5(kwinNs, payload); +} + void AbstractWaylandOutput::initialize(const QString &model, const QString &manufacturer, const QString &eisaId, const QString &serialNumber, - const QString &uuid, const QSize &physicalSize, + const QSize &physicalSize, const QVector &modes, const QByteArray &edid) { m_serialNumber = serialNumber; @@ -221,9 +231,9 @@ void AbstractWaylandOutput::initialize(const QString &model, const QString &manu m_manufacturer = manufacturer.isEmpty() ? i18n("unknown") : manufacturer; m_model = model; m_physicalSize = physicalSize; - m_uuid = uuid; m_edid = edid; m_modes = modes; + m_uuid = generateOutputId(m_eisaId, m_model, m_serialNumber, m_name); for (const Mode &mode : modes) { if (mode.flags & ModeFlag::Current) { diff --git a/src/abstract_wayland_output.h b/src/abstract_wayland_output.h index 34cc4b386f..b8e69807c7 100644 --- a/src/abstract_wayland_output.h +++ b/src/abstract_wayland_output.h @@ -80,7 +80,7 @@ public: explicit AbstractWaylandOutput(QObject *parent = nullptr); QString name() const override; - QString uuid() const override; + QUuid uuid() const override; QSize modeSize() const; @@ -148,7 +148,7 @@ Q_SIGNALS: protected: void initialize(const QString &model, const QString &manufacturer, const QString &eisaId, const QString &serialNumber, - const QString &uuid, const QSize &physicalSize, + const QSize &physicalSize, const QVector &modes, const QByteArray &edid); QPoint globalPos() const; @@ -187,7 +187,7 @@ private: QString m_manufacturer; QString m_model; QString m_serialNumber; - QString m_uuid; + QUuid m_uuid; QSize m_modeSize; QSize m_physicalSize; QPoint m_position; diff --git a/src/platform.cpp b/src/platform.cpp index 9c2de4ec1c..70f208c83c 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -169,7 +169,7 @@ AbstractOutput *Platform::findOutput(int screenId) return enabledOutputs().value(screenId); } -AbstractOutput *Platform::findOutput(const QString &uuid) +AbstractOutput *Platform::findOutput(const QUuid &uuid) { const auto outs = outputs(); auto it = std::find_if(outs.constBegin(), outs.constEnd(), diff --git a/src/platform.h b/src/platform.h index 712d443503..1d78556476 100644 --- a/src/platform.h +++ b/src/platform.h @@ -429,7 +429,7 @@ public: return Outputs(); } AbstractOutput *findOutput(int screenId); - AbstractOutput *findOutput(const QString &uuid); + AbstractOutput *findOutput(const QUuid &uuid); /** * A string of information to include in kwin debug output diff --git a/src/plugins/platforms/drm/drm_backend.cpp b/src/plugins/platforms/drm/drm_backend.cpp index d57ce0ee6a..beacb098a7 100644 --- a/src/plugins/platforms/drm/drm_backend.cpp +++ b/src/plugins/platforms/drm/drm_backend.cpp @@ -372,7 +372,7 @@ void DrmBackend::readOutputsConfiguration() QPoint pos(0, 0); for (auto it = m_outputs.begin(); it != m_outputs.end(); ++it) { qCDebug(KWIN_DRM) << "Reading output configuration for [" << uuid << "] ["<< (*it)->uuid() << "]"; - const auto outputConfig = configGroup.group((*it)->uuid()); + const auto outputConfig = configGroup.group((*it)->uuid().toString(QUuid::WithoutBraces)); (*it)->setGlobalPos(outputConfig.readEntry("Position", pos)); if (outputConfig.hasKey("Scale")) (*it)->setScale(outputConfig.readEntry("Scale", 1.0)); @@ -404,7 +404,7 @@ void DrmBackend::writeOutputsConfiguration() // default position goes from left to right for (auto it = m_outputs.cbegin(); it != m_outputs.cend(); ++it) { qCDebug(KWIN_DRM) << "Writing output configuration for [" << uuid << "] ["<< (*it)->uuid() << "]"; - auto outputConfig = configGroup.group((*it)->uuid()); + auto outputConfig = configGroup.group((*it)->uuid().toString(QUuid::WithoutBraces)); outputConfig.writeEntry("Scale", (*it)->scale()); outputConfig.writeEntry("Transform", transformToString((*it)->transform())); QString mode; @@ -422,11 +422,11 @@ QString DrmBackend::generateOutputConfigurationUuid() const auto it = m_outputs.constBegin(); if (m_outputs.size() == 1) { // special case: one output - return (*it)->uuid(); + return (*it)->uuid().toString(QUuid::WithoutBraces); } QCryptographicHash hash(QCryptographicHash::Md5); for (const DrmOutput *output: qAsConst(m_outputs)) { - hash.addData(output->uuid().toLocal8Bit()); + hash.addData(output->uuid().toByteArray()); } return QString::fromLocal8Bit(hash.result().toHex().left(10)); } diff --git a/src/plugins/platforms/drm/drm_output.cpp b/src/plugins/platforms/drm/drm_output.cpp index 7c756fa1d2..c01816b201 100644 --- a/src/plugins/platforms/drm/drm_output.cpp +++ b/src/plugins/platforms/drm/drm_output.cpp @@ -207,7 +207,6 @@ static AbstractWaylandOutput::SubPixel drmSubPixelToKWinSubPixel(drmModeSubPixel bool DrmOutput::init(drmModeConnector *connector) { - initUuid(); if (m_gpu->atomicModeSetting() && !m_primaryPlane) { return false; } @@ -226,16 +225,6 @@ bool DrmOutput::init(drmModeConnector *connector) return true; } -void DrmOutput::initUuid() -{ - QCryptographicHash hash(QCryptographicHash::Md5); - hash.addData(QByteArray::number(m_conn->id())); - hash.addData(m_conn->edid()->eisaId()); - hash.addData(m_conn->edid()->monitorName()); - hash.addData(m_conn->edid()->serialNumber()); - m_uuid = hash.result().toHex().left(10); -} - void DrmOutput::initOutputDevice(drmModeConnector *connector) { // read in mode information @@ -263,7 +252,7 @@ void DrmOutput::initOutputDevice(drmModeConnector *connector) setName(m_conn->connectorName()); initialize(m_conn->modelName(), m_conn->edid()->manufacturerString(), m_conn->edid()->eisaId(), m_conn->edid()->serialNumber(), - m_uuid, m_conn->physicalSize(), modes, m_conn->edid()->raw()); + m_conn->physicalSize(), modes, m_conn->edid()->raw()); } bool DrmOutput::isCurrentMode(const drmModeModeInfo *mode) const @@ -517,7 +506,7 @@ void DrmOutput::updateMode(uint32_t width, uint32_t height, uint32_t refreshRate } } qCWarning(KWIN_DRM, "Could not find a fitting mode with size=%dx%d and refresh rate %d for output %s", - width, height, refreshRate, uuid().constData()); + width, height, refreshRate, qPrintable(name())); } void DrmOutput::updateMode(int modeIndex) diff --git a/src/plugins/platforms/drm/drm_output.h b/src/plugins/platforms/drm/drm_output.h index f42f5af4a2..3e8b4c0f87 100644 --- a/src/plugins/platforms/drm/drm_output.h +++ b/src/plugins/platforms/drm/drm_output.h @@ -107,7 +107,6 @@ private: void initOutputDevice(drmModeConnector *connector); bool isCurrentMode(const drmModeModeInfo *mode) const; - void initUuid(); void atomicEnable(); void atomicDisable(); @@ -137,7 +136,6 @@ private: bool m_lastGbm = false; drmModeModeInfo m_mode; DpmsMode m_dpmsModePending = DpmsMode::On; - QByteArray m_uuid; RenderLoop *m_renderLoop; uint32_t m_blobId = 0; diff --git a/src/plugins/platforms/fbdev/fb_backend.cpp b/src/plugins/platforms/fbdev/fb_backend.cpp index 92a9adbde9..214bbdfe2b 100644 --- a/src/plugins/platforms/fbdev/fb_backend.cpp +++ b/src/plugins/platforms/fbdev/fb_backend.cpp @@ -70,7 +70,7 @@ void FramebufferOutput::init(const QSize &pixelSize, const QSize &physicalSize) mode.size = pixelSize; mode.flags = ModeFlag::Current; mode.refreshRate = refreshRate; - initialize("model_TODO", "manufacturer_TODO", "eisa_TODO", "serial_TODO", "UUID_TODO", physicalSize, { mode }, {}); + initialize("model_TODO", "manufacturer_TODO", "eisa_TODO", "serial_TODO", physicalSize, { mode }, {}); } void FramebufferOutput::vblank(std::chrono::nanoseconds timestamp) diff --git a/src/plugins/platforms/virtual/virtual_output.cpp b/src/plugins/platforms/virtual/virtual_output.cpp index 3f1dd69149..909b182648 100644 --- a/src/plugins/platforms/virtual/virtual_output.cpp +++ b/src/plugins/platforms/virtual/virtual_output.cpp @@ -57,7 +57,6 @@ void VirtualOutput::init(const QPoint &logicalPosition, const QSize &pixelSize) QByteArray("manufacturer_").append(QByteArray::number(m_identifier)), QByteArray("eisa_").append(QByteArray::number(m_identifier)), QByteArray("serial_").append(QByteArray::number(m_identifier)), - QByteArray("UUID_").append(QByteArray::number(m_identifier)), pixelSize, { mode }, QByteArray("EDID_").append(QByteArray::number(m_identifier))); setGeometry(QRect(logicalPosition, pixelSize)); } diff --git a/src/plugins/platforms/wayland/wayland_output.cpp b/src/plugins/platforms/wayland/wayland_output.cpp index 3c487e2979..8f4aafde70 100644 --- a/src/plugins/platforms/wayland/wayland_output.cpp +++ b/src/plugins/platforms/wayland/wayland_output.cpp @@ -62,7 +62,7 @@ void WaylandOutput::init(const QPoint &logicalPosition, const QSize &pixelSize) mode.size = pixelSize; mode.flags = ModeFlag::Current; mode.refreshRate = refreshRate; - initialize("model_TODO", "manufacturer_TODO", "eisa_TODO", "serial_TODO", "UUID_TODO", pixelSize, { mode }, {}); + initialize("model_TODO", "manufacturer_TODO", "eisa_TODO", "serial_TODO", pixelSize, { mode }, {}); setGeometry(logicalPosition, pixelSize); setScale(backend()->initialOutputScale()); } diff --git a/src/plugins/platforms/x11/windowed/x11windowed_output.cpp b/src/plugins/platforms/x11/windowed/x11windowed_output.cpp index c6310149de..be243ec94f 100644 --- a/src/plugins/platforms/x11/windowed/x11windowed_output.cpp +++ b/src/plugins/platforms/x11/windowed/x11windowed_output.cpp @@ -70,7 +70,7 @@ void X11WindowedOutput::init(const QPoint &logicalPosition, const QSize &pixelSi // Physicial size must be adjusted, such that QPA calculates correct sizes of // internal elements. const QSize physicalSize = pixelSize / 96.0 * 25.4 / m_backend->initialOutputScale(); - initialize("model_TODO", "manufacturer_TODO", "eisa_TODO", "serial_TODO", "UUID_TODO", physicalSize, { mode }, {}); + initialize("model_TODO", "manufacturer_TODO", "eisa_TODO", "serial_TODO", physicalSize, { mode }, {}); setGeometry(logicalPosition, pixelSize); setScale(m_backend->initialOutputScale());