/* SPDX-FileCopyrightText: 2020 Vlad Zahorodnii SPDX-License-Identifier: GPL-2.0-or-later */ #include "colordintegration.h" #include "abstract_output.h" #include "colorddevice.h" #include "colordlogging.h" #include "main.h" #include "platform.h" #include #include namespace KWin { ColordIntegration::ColordIntegration(QObject *parent) : Plugin(parent) { qDBusRegisterMetaType(); auto watcher = new QDBusServiceWatcher(QStringLiteral("org.freedesktop.ColorManager"), QDBusConnection::systemBus(), QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, this); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &ColordIntegration::initialize); connect(watcher, &QDBusServiceWatcher::serviceUnregistered, this, &ColordIntegration::teardown); QDBusConnectionInterface *interface = QDBusConnection::systemBus().interface(); if (interface->isServiceRegistered(QStringLiteral("org.freedesktop.ColorManager"))) { initialize(); } } void ColordIntegration::initialize() { const Platform *platform = kwinApp()->platform(); m_colordInterface = new CdInterface(QStringLiteral("org.freedesktop.ColorManager"), QStringLiteral("/org/freedesktop/ColorManager"), QDBusConnection::systemBus(), this); const QVector outputs = platform->outputs(); for (AbstractOutput *output : outputs) { handleOutputAdded(output); } connect(platform, &Platform::outputAdded, this, &ColordIntegration::handleOutputAdded); connect(platform, &Platform::outputRemoved, this, &ColordIntegration::handleOutputRemoved); } void ColordIntegration::teardown() { const Platform *platform = kwinApp()->platform(); const QVector outputs = platform->outputs(); for (AbstractOutput *output : outputs) { handleOutputRemoved(output); } delete m_colordInterface; m_colordInterface = nullptr; disconnect(platform, &Platform::outputAdded, this, &ColordIntegration::handleOutputAdded); disconnect(platform, &Platform::outputRemoved, this, &ColordIntegration::handleOutputRemoved); } void ColordIntegration::handleOutputAdded(AbstractOutput *output) { ColordDevice *device = new ColordDevice(output, this); CdStringMap properties; properties.insert(QStringLiteral("Kind"), QStringLiteral("display")); properties.insert(QStringLiteral("Colorspace"), QStringLiteral("RGB")); const QString vendor = output->manufacturer(); if (!vendor.isEmpty()) { properties.insert(QStringLiteral("Vendor"), vendor); } const QString model = output->model(); if (!model.isEmpty()) { properties.insert(QStringLiteral("Model"), model); } const QString serialNumber = output->serialNumber(); if (!serialNumber.isEmpty()) { properties.insert(QStringLiteral("Serial"), serialNumber); } if (output->isInternal()) { properties.insert(QStringLiteral("Embedded"), QString()); } QDBusPendingReply reply = m_colordInterface->CreateDevice(output->name(), QStringLiteral("temp"), properties); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, device, watcher]() { watcher->deleteLater(); const QDBusPendingReply reply = *watcher; if (reply.isError()) { qCDebug(KWIN_COLORD) << "Failed to add a colord device:" << reply.error(); delete device; return; } const QDBusObjectPath objectPath = reply.value(); if (!device->output()) { m_colordInterface->DeleteDevice(objectPath); delete device; return; } device->initialize(objectPath); m_outputToDevice.insert(device->output(), device); }); } void ColordIntegration::handleOutputRemoved(AbstractOutput *output) { ColordDevice *device = m_outputToDevice.take(output); if (device) { m_colordInterface->DeleteDevice(device->objectPath()); delete device; } } } // namespace KWin