File indexing completed on 2024-04-28 16:49:40

0001 /*
0002  *  SPDX-FileCopyrightText: 2012 Alejandro Fiestas Olivares <afiestas@kde.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.1-or-later
0005  */
0006 
0007 #include "fake.h"
0008 #include "parser.h"
0009 
0010 #include "edid.h"
0011 #include <output.h>
0012 
0013 #include <stdlib.h>
0014 
0015 #include <QFile>
0016 #include <QTimer>
0017 
0018 #include <QJsonArray>
0019 #include <QJsonDocument>
0020 #include <QJsonObject>
0021 
0022 #include <QDBusConnection>
0023 
0024 #include "fakebackendadaptor.h"
0025 
0026 using namespace KScreen;
0027 
0028 Q_LOGGING_CATEGORY(KSCREEN_FAKE, "kscreen.fake")
0029 
0030 Fake::Fake()
0031     : KScreen::AbstractBackend()
0032 {
0033     QLoggingCategory::setFilterRules(QStringLiteral("kscreen.fake.debug = true"));
0034 
0035     if (qgetenv("KSCREEN_BACKEND_INPROCESS") != QByteArray("1")) {
0036         QTimer::singleShot(0, this, &Fake::delayedInit);
0037     }
0038 }
0039 
0040 void Fake::init(const QVariantMap &arguments)
0041 {
0042     if (!mConfig.isNull()) {
0043         mConfig.clear();
0044     }
0045 
0046     mConfigFile = arguments[QStringLiteral("TEST_DATA")].toString();
0047 
0048     if (arguments.contains(QStringLiteral("SUPPORTED_FEATURES"))) {
0049         bool ok = false;
0050         const int features = arguments[QStringLiteral("SUPPORTED_FEATURES")].toInt(&ok);
0051         if (ok) {
0052             mSupportedFeatures = static_cast<KScreen::Config::Features>(features);
0053         }
0054     }
0055 
0056     qCDebug(KSCREEN_FAKE) << "Fake profile file:" << mConfigFile << "features" << mSupportedFeatures;
0057 }
0058 
0059 void Fake::delayedInit()
0060 {
0061     new FakeBackendAdaptor(this);
0062     QDBusConnection::sessionBus().registerObject(QStringLiteral("/fake"), this);
0063 }
0064 
0065 Fake::~Fake()
0066 {
0067 }
0068 
0069 QString Fake::name() const
0070 {
0071     return QStringLiteral("Fake");
0072 }
0073 
0074 QString Fake::serviceName() const
0075 {
0076     return QStringLiteral("org.kde.KScreen.Backend.Fake");
0077 }
0078 
0079 ConfigPtr Fake::config() const
0080 {
0081     if (mConfig.isNull()) {
0082         mConfig = Parser::fromJson(mConfigFile);
0083         if (mConfig) {
0084             mConfig->setSupportedFeatures(mSupportedFeatures);
0085         }
0086     }
0087 
0088     return mConfig;
0089 }
0090 
0091 void Fake::setConfig(const ConfigPtr &config)
0092 {
0093     qCDebug(KSCREEN_FAKE) << "set config" << config->outputs();
0094     mConfig = config->clone();
0095     Q_EMIT configChanged(mConfig);
0096 }
0097 
0098 bool Fake::isValid() const
0099 {
0100     return true;
0101 }
0102 
0103 QByteArray Fake::edid(int outputId) const
0104 {
0105     Q_UNUSED(outputId);
0106     QFile file(mConfigFile);
0107     file.open(QIODevice::ReadOnly);
0108 
0109     const QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll());
0110     const QJsonObject json = jsonDoc.object();
0111 
0112     const QJsonArray outputs = json[QStringLiteral("outputs")].toArray();
0113     for (const QJsonValue &value : outputs) {
0114         const QVariantMap output = value.toObject().toVariantMap();
0115         if (output[QStringLiteral("id")].toInt() != outputId) {
0116             continue;
0117         }
0118 
0119         return QByteArray::fromBase64(output[QStringLiteral("edid")].toByteArray());
0120     }
0121     return QByteArray();
0122 }
0123 
0124 void Fake::setConnected(int outputId, bool connected)
0125 {
0126     KScreen::OutputPtr output = config()->output(outputId);
0127     if (output->isConnected() == connected) {
0128         return;
0129     }
0130 
0131     output->setConnected(connected);
0132     qCDebug(KSCREEN_FAKE) << "emitting configChanged in Fake";
0133     Q_EMIT configChanged(mConfig);
0134 }
0135 
0136 void Fake::setEnabled(int outputId, bool enabled)
0137 {
0138     KScreen::OutputPtr output = config()->output(outputId);
0139     if (output->isEnabled() == enabled) {
0140         return;
0141     }
0142 
0143     output->setEnabled(enabled);
0144     Q_EMIT configChanged(mConfig);
0145 }
0146 
0147 void Fake::setPrimary(int outputId, bool primary)
0148 {
0149     KScreen::OutputPtr output = config()->output(outputId);
0150     if (!output || output->isPrimary() == primary) {
0151         return;
0152     }
0153 
0154     mConfig->setPrimaryOutput(output);
0155     Q_EMIT configChanged(mConfig);
0156 }
0157 
0158 void Fake::setCurrentModeId(int outputId, const QString &modeId)
0159 {
0160     KScreen::OutputPtr output = config()->output(outputId);
0161     if (output->currentModeId() == modeId) {
0162         return;
0163     }
0164 
0165     output->setCurrentModeId(modeId);
0166     Q_EMIT configChanged(mConfig);
0167 }
0168 
0169 void Fake::setRotation(int outputId, int rotation)
0170 {
0171     KScreen::OutputPtr output = config()->output(outputId);
0172     const KScreen::Output::Rotation rot = static_cast<KScreen::Output::Rotation>(rotation);
0173     if (output->rotation() == rot) {
0174         return;
0175     }
0176 
0177     output->setRotation(rot);
0178     Q_EMIT configChanged(mConfig);
0179 }
0180 
0181 void Fake::addOutput(int outputId, const QString &name)
0182 {
0183     KScreen::OutputPtr output(new KScreen::Output);
0184     output->setId(outputId);
0185     output->setName(name);
0186     mConfig->addOutput(output);
0187     Q_EMIT configChanged(mConfig);
0188 }
0189 
0190 void Fake::removeOutput(int outputId)
0191 {
0192     mConfig->removeOutput(outputId);
0193     Q_EMIT configChanged(mConfig);
0194 }