diff --git a/autotests/testkwaylandconfig.cpp b/autotests/testkwaylandconfig.cpp index 17c3827..4a7a685 100644 --- a/autotests/testkwaylandconfig.cpp +++ b/autotests/testkwaylandconfig.cpp @@ -1,270 +1,271 @@ /************************************************************************************* * Copyright 2015 by Sebastian Kügler * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************************/ #include #include #include #include #include "backendmanager_p.h" #include "getconfigoperation.h" #include "setconfigoperation.h" #include "config.h" #include "configmonitor.h" #include "output.h" #include "mode.h" #include "edid.h" #include "waylandtestserver.h" Q_LOGGING_CATEGORY(KSCREEN_WAYLAND, "kscreen.kwayland") using namespace KScreen; class TestKWaylandConfig : public QObject { Q_OBJECT public: explicit TestKWaylandConfig(QObject *parent = nullptr); private Q_SLOTS: void initTestCase(); void cleanupTestCase(); void changeConfig(); void testPositionChange(); void testRotationChange(); void testRotationChange_data(); void testScaleChange(); void testModeChange(); private: WaylandTestServer *m_server; }; TestKWaylandConfig::TestKWaylandConfig(QObject *parent) : QObject(parent) , m_server(nullptr) { qputenv("KSCREEN_LOGGING", "false"); } void TestKWaylandConfig::initTestCase() { setenv("KSCREEN_BACKEND", "kwayland", 1); KScreen::BackendManager::instance()->shutdownBackend(); // This is how KWayland will pick up the right socket, // and thus connect to our internal test server. setenv("WAYLAND_DISPLAY", s_socketName.toLocal8Bit(), 1); m_server = new WaylandTestServer(this); m_server->start(); } void TestKWaylandConfig::cleanupTestCase() { qDebug() << "Shutting down"; KScreen::BackendManager::instance()->shutdownBackend(); delete m_server; } void TestKWaylandConfig::changeConfig() { auto op = new GetConfigOperation(); QVERIFY(op->exec()); auto config = op->config(); QVERIFY(config); // Prepare monitor & spy KScreen::ConfigMonitor *monitor = KScreen::ConfigMonitor::instance(); monitor->addConfig(config); QSignalSpy configSpy(monitor, &KScreen::ConfigMonitor::configurationChanged); // The first output is currently disabled, let's try to enable it auto output = config->outputs().first(); QVERIFY(output->isEnabled() == false); output->setEnabled(true); output->setCurrentModeId("76"); auto output2 = config->outputs()[2]; // is this id stable enough? output2->setPos(QPoint(4000, 1080)); output2->setRotation(KScreen::Output::Left); QSignalSpy serverSpy(m_server, &WaylandTestServer::configChanged); auto sop = new SetConfigOperation(config, this); sop->exec(); // fire and forget... QVERIFY(configSpy.wait()); // check if the server changed QCOMPARE(serverSpy.count(), 1); QCOMPARE(configSpy.count(), 1); monitor->removeConfig(config); m_server->showOutputs(); } void TestKWaylandConfig::testPositionChange() { auto op = new GetConfigOperation(); QVERIFY(op->exec()); auto config = op->config(); QVERIFY(config); // Prepare monitor & spy KScreen::ConfigMonitor *monitor = KScreen::ConfigMonitor::instance(); monitor->addConfig(config); QSignalSpy configSpy(monitor, &KScreen::ConfigMonitor::configurationChanged); auto output = config->outputs()[2]; // is this id stable enough? auto new_pos = QPoint(3840, 1080); output->setPos(new_pos); QSignalSpy serverSpy(m_server, &WaylandTestServer::configChanged); auto sop = new SetConfigOperation(config, this); sop->exec(); // fire and forget... QVERIFY(configSpy.wait()); // check if the server changed QCOMPARE(serverSpy.count(), 1); QCOMPARE(configSpy.count(), 1); } void TestKWaylandConfig::testRotationChange_data() { QTest::addColumn("rotation"); QTest::newRow("left") << KScreen::Output::Left; QTest::newRow("inverted") << KScreen::Output::Inverted; QTest::newRow("right") << KScreen::Output::Right; QTest::newRow("none") << KScreen::Output::None; } void TestKWaylandConfig::testRotationChange() { QFETCH(KScreen::Output::Rotation, rotation); auto op = new GetConfigOperation(); QVERIFY(op->exec()); auto config = op->config(); QVERIFY(config); // Prepare monitor & spy KScreen::ConfigMonitor *monitor = KScreen::ConfigMonitor::instance(); monitor->addConfig(config); QSignalSpy configSpy(monitor, &KScreen::ConfigMonitor::configurationChanged); auto output = config->outputs().first(); // is this id stable enough? output->setRotation(rotation); QSignalSpy serverSpy(m_server, &WaylandTestServer::configChanged); auto sop = new SetConfigOperation(config, this); sop->exec(); // fire and forget... QVERIFY(configSpy.wait()); // check if the server changed QCOMPARE(serverSpy.count(), 1); QCOMPARE(configSpy.count(), 1); // Get a new config, then compare the output with the expected new value auto newop = new GetConfigOperation(); QVERIFY(newop->exec()); auto newconfig = newop->config(); QVERIFY(newconfig); auto newoutput = newconfig->outputs().first(); QCOMPARE(newoutput->rotation(), rotation); } void TestKWaylandConfig::testScaleChange() { auto op = new GetConfigOperation(); QVERIFY(op->exec()); auto config = op->config(); QVERIFY(config); auto op2 = new GetConfigOperation(); QVERIFY(op2->exec()); auto config2 = op2->config(); QVERIFY(config2); // Prepare monitor & spy KScreen::ConfigMonitor *monitor = KScreen::ConfigMonitor::instance(); monitor->addConfig(config); + monitor->addConfig(config2); QSignalSpy configSpy(monitor, &KScreen::ConfigMonitor::configurationChanged); QSignalSpy configSpy2(monitor, &KScreen::ConfigMonitor::configurationChanged); auto output2 = config2->outputs()[2]; // is this id stable enough? QSignalSpy outputSpy(output2.data(), &KScreen::Output::scaleChanged); QCOMPARE(output2->scale(), 1.0); auto output = config->outputs()[2]; // is this id stable enough? output->setScale(2); QSignalSpy serverSpy(m_server, &WaylandTestServer::configChanged); auto sop = new SetConfigOperation(config, this); sop->exec(); // fire and forget... QVERIFY(configSpy.wait()); // check if the server changed QCOMPARE(serverSpy.count(), 1); QCOMPARE(configSpy.count(), 1); QCOMPARE(outputSpy.count(), 1); QCOMPARE(configSpy2.count(), 1); QCOMPARE(output2->scale(), 2.0); } void TestKWaylandConfig::testModeChange() { auto op = new GetConfigOperation(); QVERIFY(op->exec()); auto config = op->config(); QVERIFY(config); KScreen::ConfigMonitor *monitor = KScreen::ConfigMonitor::instance(); monitor->addConfig(config); QSignalSpy configSpy(monitor, &KScreen::ConfigMonitor::configurationChanged); auto output = config->outputs()[1]; // is this id stable enough? QString new_mode = QStringLiteral("74"); output->setCurrentModeId(new_mode); QSignalSpy serverSpy(m_server, &WaylandTestServer::configChanged); auto sop = new SetConfigOperation(config, this); sop->exec(); QVERIFY(configSpy.wait()); // check if the server changed QCOMPARE(serverSpy.count(), 1); QCOMPARE(configSpy.count(), 1); } QTEST_GUILESS_MAIN(TestKWaylandConfig) #include "testkwaylandconfig.moc" diff --git a/backends/fake/fake.cpp b/backends/fake/fake.cpp index 94586bc..0d19d1b 100644 --- a/backends/fake/fake.cpp +++ b/backends/fake/fake.cpp @@ -1,203 +1,203 @@ /************************************************************************************* * Copyright (C) 2012 by Alejandro Fiestas Olivares * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************************/ #include "fake.h" #include "parser.h" #include "config.h" #include "edid.h" #include #include #include #include #include #include #include #include #include "fakebackendadaptor.h" using namespace KScreen; Q_LOGGING_CATEGORY(KSCREEN_FAKE, "kscreen.fake") Fake::Fake() : KScreen::AbstractBackend() { QLoggingCategory::setFilterRules(QStringLiteral("kscreen.fake.debug = true")); if (qgetenv("KSCREEN_BACKEND_INPROCESS") != QByteArray("1")) { QTimer::singleShot(0, this, SLOT(delayedInit())); } } void Fake::init(const QVariantMap &arguments) { if (!mConfig.isNull()) { mConfig.clear(); } mConfigFile = arguments[QStringLiteral("TEST_DATA")].toString(); qCDebug(KSCREEN_FAKE) << "Fake profile file:" << mConfigFile; } void Fake::delayedInit() { new FakeBackendAdaptor(this); QDBusConnection::sessionBus().registerObject(QLatin1String("/fake"), this); } Fake::~Fake() { } QString Fake::name() const { return QString("Fake"); } QString Fake::serviceName() const { return QLatin1Literal("org.kde.KScreen.Backend.Fake"); } ConfigPtr Fake::config() const { if (mConfig.isNull()) { mConfig = Parser::fromJson(mConfigFile); } return mConfig; } void Fake::setConfig(const ConfigPtr &config) { qCDebug(KSCREEN_FAKE) << "set config" << config->outputs(); - mConfig = config; + mConfig = config->clone(); emit configChanged(mConfig); } bool Fake::isValid() const { return true; } QByteArray Fake::edid(int outputId) const { Q_UNUSED(outputId); QFile file(mConfigFile); file.open(QIODevice::ReadOnly); const QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll()); const QJsonObject json = jsonDoc.object(); const QJsonArray outputs = json["outputs"].toArray(); Q_FOREACH(const QJsonValue &value, outputs) { const QVariantMap output = value.toObject().toVariantMap(); if (output["id"].toInt() != outputId) { continue; } return QByteArray::fromBase64(output["edid"].toByteArray()); } return QByteArray(); } void Fake::setConnected(int outputId, bool connected) { KScreen::OutputPtr output = config()->output(outputId); if (output->isConnected() == connected) { return; } output->setConnected(connected); qCDebug(KSCREEN_FAKE) << "emitting configChanged in Fake"; Q_EMIT configChanged(mConfig); } void Fake::setEnabled(int outputId, bool enabled) { KScreen::OutputPtr output = config()->output(outputId); if (output->isEnabled() == enabled) { return; } output->setEnabled(enabled); Q_EMIT configChanged(mConfig); } void Fake::setPrimary(int outputId, bool primary) { KScreen::OutputPtr output = config()->output(outputId); if (output->isPrimary() == primary) { return; } Q_FOREACH (KScreen::OutputPtr output, config()->outputs()) { if (output->id() == outputId) { output->setPrimary(primary); } else { output->setPrimary(false); } } Q_EMIT configChanged(mConfig); } void Fake::setCurrentModeId(int outputId, const QString &modeId) { KScreen::OutputPtr output = config()->output(outputId); if (output->currentModeId() == modeId) { return; } output->setCurrentModeId(modeId); Q_EMIT configChanged(mConfig); } void Fake::setRotation(int outputId, int rotation) { KScreen::OutputPtr output = config()->output(outputId); const KScreen::Output::Rotation rot = static_cast(rotation); if (output->rotation() == rot) { return; } output->setRotation(rot); Q_EMIT configChanged(mConfig); } void Fake::addOutput(int outputId, const QString &name) { KScreen::OutputPtr output(new KScreen::Output); output->setId(outputId); output->setName(name); mConfig->addOutput(output); Q_EMIT configChanged(mConfig); } void Fake::removeOutput(int outputId) { mConfig->removeOutput(outputId); Q_EMIT configChanged(mConfig); }