File indexing completed on 2024-05-12 05:30:05

0001 /*
0002     SPDX-FileCopyrightText: 2012 Alejandro Fiestas Olivares <afiestas@kde.org>
0003     SPDX-FileCopyrightText: 2021 David Redondo <kde@david-redondo.de>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "../../kded/generator.h"
0009 #include "../../kded/output.h"
0010 
0011 #include <QObject>
0012 #include <QtTest>
0013 
0014 #include <kscreen/backendmanager_p.h>
0015 #include <kscreen/config.h>
0016 #include <kscreen/getconfigoperation.h>
0017 
0018 using namespace KScreen;
0019 
0020 class testScreenConfig : public QObject
0021 {
0022     Q_OBJECT
0023 
0024 private:
0025     KScreen::ConfigPtr loadConfig(const QByteArray &fileName);
0026 
0027     void switchDisplayTwoScreensNoCommonMode();
0028 
0029 private Q_SLOTS:
0030     void initTestCase();
0031     void cleanupTestCase();
0032     void singleOutput();
0033     void laptopLidOpenAndExternal();
0034     void laptopLidOpenAndTwoExternal();
0035     void laptopLidClosedAndExternal();
0036     void laptopLidClosedAndThreeExternal();
0037     void laptopDockedLidOpenAndExternal();
0038     void laptopDockedLidClosedAndExternal();
0039     void workstationWithoutScreens();
0040     void workstationWithNoConnectedScreens();
0041     void workstationTwoExternalSameSize();
0042     void workstationFallbackMode();
0043     void workstationTwoExternalDiferentSize();
0044     void switchDisplayTwoScreens();
0045     void switchDisplayTwoScreensOneRotated();
0046     void globalOutputData();
0047     void outputPreset();
0048     void autogeneratedScreenScales();
0049 };
0050 
0051 KScreen::ConfigPtr testScreenConfig::loadConfig(const QByteArray &fileName)
0052 {
0053     KScreen::BackendManager::instance()->shutdownBackend();
0054 
0055     QByteArray path(TEST_DATA "configs/" + fileName);
0056     qDebug() << path;
0057     KScreen::BackendManager::instance()->setBackendArgs({{QStringLiteral("TEST_DATA"), path}});
0058 
0059     KScreen::GetConfigOperation *op = new KScreen::GetConfigOperation;
0060     if (!op->exec()) {
0061         qWarning() << op->errorString();
0062         return ConfigPtr();
0063     }
0064     return op->config();
0065 }
0066 
0067 void testScreenConfig::initTestCase()
0068 {
0069     QStandardPaths::setTestModeEnabled(true);
0070     qputenv("KSCREEN_LOGGING", "false");
0071     setenv("KSCREEN_BACKEND", "Fake", 1);
0072 }
0073 
0074 void testScreenConfig::cleanupTestCase()
0075 {
0076     KScreen::BackendManager::instance()->shutdownBackend();
0077 }
0078 
0079 void testScreenConfig::singleOutput()
0080 {
0081     const ConfigPtr currentConfig = loadConfig("singleOutput.json");
0082     QVERIFY(currentConfig);
0083 
0084     Generator *generator = Generator::self();
0085     generator->setCurrentConfig(currentConfig);
0086 
0087     ConfigPtr config = generator->idealConfig(currentConfig);
0088     OutputPtr output = config->outputs().value(1);
0089 
0090     QCOMPARE(output->currentModeId(), QLatin1String("3"));
0091     QCOMPARE(output->isEnabled(), true);
0092     QCOMPARE(output->isPrimary(), true);
0093     QCOMPARE(output->pos(), QPoint(0, 0));
0094 }
0095 
0096 void testScreenConfig::laptopLidOpenAndExternal()
0097 {
0098     const ConfigPtr currentConfig = loadConfig("laptopAndExternal.json");
0099     QVERIFY(currentConfig);
0100 
0101     Generator *generator = Generator::self();
0102     generator->setCurrentConfig(currentConfig);
0103     generator->setForceLaptop(true);
0104 
0105     ConfigPtr config = generator->idealConfig(currentConfig);
0106     OutputPtr laptop = config->outputs().value(1);
0107     OutputPtr external = config->outputs().value(2);
0108 
0109     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0110     QCOMPARE(laptop->isPrimary(), true);
0111     QCOMPARE(laptop->isEnabled(), true);
0112     QCOMPARE(laptop->pos(), QPoint(0, 0));
0113 
0114     QCOMPARE(external->currentModeId(), QLatin1String("4"));
0115     QCOMPARE(external->isPrimary(), false);
0116     QCOMPARE(external->isEnabled(), true);
0117     QCOMPARE(external->pos(), QPoint(1280, 0));
0118 }
0119 
0120 void testScreenConfig::laptopLidOpenAndTwoExternal()
0121 {
0122     const ConfigPtr currentConfig = loadConfig("laptopLidOpenAndTwoExternal.json");
0123     QVERIFY(currentConfig);
0124 
0125     Generator *generator = Generator::self();
0126     generator->setCurrentConfig(currentConfig);
0127     generator->setForceLaptop(true);
0128 
0129     ConfigPtr config = generator->idealConfig(currentConfig);
0130     OutputPtr laptop = config->outputs().value(1);
0131     OutputPtr hdmi1 = config->outputs().value(2);
0132     OutputPtr hdmi2 = config->outputs().value(3);
0133 
0134     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0135     QCOMPARE(laptop->isPrimary(), true);
0136     QCOMPARE(laptop->isEnabled(), true);
0137     QCOMPARE(laptop->pos(), QPoint(0, 0));
0138 
0139     QCOMPARE(hdmi1->currentModeId(), QLatin1String("4"));
0140     QCOMPARE(hdmi1->isPrimary(), false);
0141     QCOMPARE(hdmi1->isEnabled(), true);
0142     QCOMPARE(hdmi1->pos(), QPoint(hdmi2->pos().x() + hdmi2->currentMode()->size().width(), 0));
0143 
0144     QCOMPARE(hdmi2->currentModeId(), QLatin1String("4"));
0145     QCOMPARE(hdmi2->isPrimary(), false);
0146     QCOMPARE(hdmi2->isEnabled(), true);
0147     QCOMPARE(hdmi2->pos(), QPoint(1280, 0));
0148 }
0149 
0150 void testScreenConfig::laptopLidClosedAndExternal()
0151 {
0152     const ConfigPtr currentConfig = loadConfig("laptopAndExternal.json");
0153     QVERIFY(currentConfig);
0154 
0155     Generator *generator = Generator::self();
0156     generator->setCurrentConfig(currentConfig);
0157     generator->setForceLaptop(true);
0158     generator->setForceLidClosed(true);
0159 
0160     ConfigPtr config = generator->idealConfig(currentConfig);
0161     OutputPtr laptop = config->outputs().value(1);
0162     OutputPtr external = config->outputs().value(2);
0163 
0164     QCOMPARE(laptop->isEnabled(), false);
0165     QCOMPARE(laptop->isPrimary(), false);
0166 
0167     QCOMPARE(external->currentModeId(), QLatin1String("4"));
0168     QCOMPARE(external->isPrimary(), true);
0169     QCOMPARE(external->isEnabled(), true);
0170     QCOMPARE(external->pos(), QPoint(0, 0));
0171 }
0172 
0173 void testScreenConfig::laptopLidClosedAndThreeExternal()
0174 {
0175     const ConfigPtr currentConfig = loadConfig("laptopLidClosedAndThreeExternal.json");
0176     QVERIFY(currentConfig);
0177 
0178     Generator *generator = Generator::self();
0179     generator->setCurrentConfig(currentConfig);
0180     generator->setForceLaptop(true);
0181     generator->setForceLidClosed(true);
0182 
0183     ConfigPtr config = generator->idealConfig(currentConfig);
0184     OutputPtr laptop = config->outputs().value(1);
0185     OutputPtr hdmi1 = config->outputs().value(2);
0186     OutputPtr hdmi2 = config->outputs().value(3);
0187     OutputPtr primary = config->outputs().value(4);
0188 
0189     QCOMPARE(laptop->isEnabled(), false);
0190     QCOMPARE(laptop->isPrimary(), false);
0191 
0192     QCOMPARE(hdmi1->isEnabled(), true);
0193     QCOMPARE(hdmi1->isPrimary(), false);
0194     QCOMPARE(hdmi1->currentModeId(), QLatin1String("4"));
0195     QCOMPARE(hdmi1->pos(), QPoint(primary->currentMode()->size().width(), 0));
0196 
0197     QCOMPARE(hdmi2->isEnabled(), true);
0198     QCOMPARE(hdmi2->isPrimary(), false);
0199     QCOMPARE(hdmi2->currentModeId(), QLatin1String("3"));
0200     QCOMPARE(hdmi2->pos(), QPoint(hdmi1->pos().x() + hdmi1->currentMode()->size().width(), 0));
0201 
0202     QCOMPARE(primary->isEnabled(), true);
0203     QCOMPARE(primary->isPrimary(), true);
0204     QCOMPARE(primary->currentModeId(), QLatin1String("4"));
0205     QCOMPARE(primary->pos(), QPoint(0, 0));
0206 }
0207 
0208 void testScreenConfig::laptopDockedLidOpenAndExternal()
0209 {
0210     const ConfigPtr currentConfig = loadConfig("laptopAndExternal.json");
0211     QVERIFY(currentConfig);
0212 
0213     Generator *generator = Generator::self();
0214     generator->setCurrentConfig(currentConfig);
0215     generator->setForceLaptop(true);
0216     generator->setForceLidClosed(false);
0217     generator->setForceDocked(true);
0218 
0219     ConfigPtr config = generator->idealConfig(currentConfig);
0220     OutputPtr laptop = config->outputs().value(1);
0221     OutputPtr external = config->outputs().value(2);
0222 
0223     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0224     QCOMPARE(laptop->isPrimary(), false);
0225     QCOMPARE(laptop->isEnabled(), true);
0226     QCOMPARE(laptop->pos(), QPoint(0, 0));
0227 
0228     QCOMPARE(external->currentModeId(), QLatin1String("4"));
0229     QCOMPARE(external->isPrimary(), true);
0230     QCOMPARE(external->isEnabled(), true);
0231     QCOMPARE(external->pos(), QPoint(1280, 0));
0232 }
0233 
0234 void testScreenConfig::laptopDockedLidClosedAndExternal()
0235 {
0236     const ConfigPtr currentConfig = loadConfig("laptopAndExternal.json");
0237     QVERIFY(currentConfig);
0238 
0239     Generator *generator = Generator::self();
0240     generator->setCurrentConfig(currentConfig);
0241     generator->setForceLaptop(true);
0242     generator->setForceLidClosed(true);
0243     generator->setForceDocked(true);
0244 
0245     ConfigPtr config = generator->idealConfig(currentConfig);
0246     OutputPtr laptop = config->outputs().value(1);
0247     OutputPtr external = config->outputs().value(2);
0248 
0249     QCOMPARE(laptop->isEnabled(), false);
0250     QCOMPARE(laptop->isPrimary(), false);
0251 
0252     QCOMPARE(external->currentModeId(), QLatin1String("4"));
0253     QCOMPARE(external->isPrimary(), true);
0254     QCOMPARE(external->isEnabled(), true);
0255     QCOMPARE(external->pos(), QPoint(0, 0));
0256 }
0257 
0258 void testScreenConfig::workstationWithoutScreens()
0259 {
0260     const ConfigPtr currentConfig = loadConfig("workstationWithoutScreens.json");
0261     QVERIFY(currentConfig);
0262 
0263     Generator *generator = Generator::self();
0264     generator->setCurrentConfig(currentConfig);
0265     generator->setForceLaptop(false);
0266     generator->setForceNotLaptop(true);
0267 
0268     ConfigPtr config = generator->idealConfig(currentConfig);
0269 
0270     QVERIFY(config->outputs().isEmpty());
0271 }
0272 
0273 void testScreenConfig::workstationWithNoConnectedScreens()
0274 {
0275     const ConfigPtr currentConfig = loadConfig("workstationWithNoConnectedScreens.json");
0276     QVERIFY(currentConfig);
0277 
0278     Generator *generator = Generator::self();
0279     generator->setCurrentConfig(currentConfig);
0280     generator->setForceLaptop(false);
0281     generator->setForceNotLaptop(true);
0282 
0283     ConfigPtr config = generator->idealConfig(currentConfig);
0284 
0285     OutputPtr external1 = config->output(1);
0286     OutputPtr external2 = config->output(2);
0287 
0288     QCOMPARE(external1->isEnabled(), false);
0289     QCOMPARE(external2->isEnabled(), false);
0290 }
0291 
0292 void testScreenConfig::workstationTwoExternalSameSize()
0293 {
0294     const ConfigPtr currentConfig = loadConfig("workstaionTwoExternalSameSize.json");
0295     QVERIFY(currentConfig);
0296 
0297     Generator *generator = Generator::self();
0298     generator->setCurrentConfig(currentConfig);
0299     generator->setForceLaptop(false);
0300     generator->setForceNotLaptop(true);
0301 
0302     ConfigPtr config = generator->idealConfig(currentConfig);
0303     OutputPtr external1 = config->output(1);
0304     OutputPtr external2 = config->output(2);
0305 
0306     QCOMPARE(external1->isPrimary(), true);
0307     QCOMPARE(external1->isEnabled(), true);
0308     QCOMPARE(external1->currentModeId(), QLatin1String("3"));
0309     QCOMPARE(external1->pos(), QPoint(0, 0));
0310 
0311     QCOMPARE(external2->isPrimary(), false);
0312     QCOMPARE(external2->isEnabled(), true);
0313     QCOMPARE(external2->currentModeId(), QLatin1String("3"));
0314     QCOMPARE(external2->pos(), QPoint(external1->currentMode()->size().width(), 0));
0315 }
0316 
0317 void testScreenConfig::workstationFallbackMode()
0318 {
0319     const ConfigPtr currentConfig = loadConfig("workstationFallbackMode.json");
0320     QVERIFY(currentConfig);
0321 
0322     Generator *generator = Generator::self();
0323     generator->setCurrentConfig(currentConfig);
0324     generator->setForceLaptop(false);
0325     generator->setForceNotLaptop(true);
0326 
0327     ConfigPtr config = generator->idealConfig(currentConfig);
0328     OutputPtr external1 = config->output(1);
0329     OutputPtr external2 = config->output(2);
0330 
0331     QCOMPARE(external1->isPrimary(), true);
0332     QCOMPARE(external1->isEnabled(), true);
0333     QCOMPARE(external1->currentModeId(), QLatin1String("1"));
0334     QCOMPARE(external1->pos(), QPoint(0, 0));
0335 
0336     QCOMPARE(external2->isPrimary(), false);
0337     QCOMPARE(external2->isEnabled(), true);
0338     QCOMPARE(external2->currentModeId(), QLatin1String("1"));
0339     QCOMPARE(external2->pos(), QPoint(0, 0));
0340 }
0341 
0342 void testScreenConfig::workstationTwoExternalDiferentSize()
0343 {
0344     const ConfigPtr currentConfig = loadConfig("workstationTwoExternalDiferentSize.json");
0345     QVERIFY(currentConfig);
0346 
0347     Generator *generator = Generator::self();
0348     generator->setCurrentConfig(currentConfig);
0349     generator->setForceLaptop(false);
0350     generator->setForceNotLaptop(true);
0351 
0352     ConfigPtr config = generator->idealConfig(currentConfig);
0353     OutputPtr external1 = config->output(1);
0354     OutputPtr external2 = config->output(2);
0355 
0356     QCOMPARE(external1->isPrimary(), false);
0357     QCOMPARE(external1->isEnabled(), true);
0358     QCOMPARE(external1->currentModeId(), QLatin1String("3"));
0359     QCOMPARE(external1->pos(), QPoint(external2->currentMode()->size().width(), 0));
0360 
0361     QCOMPARE(external2->isPrimary(), true);
0362     QCOMPARE(external2->isEnabled(), true);
0363     QCOMPARE(external2->currentModeId(), QLatin1String("4"));
0364 }
0365 
0366 void testScreenConfig::switchDisplayTwoScreens()
0367 {
0368     const ConfigPtr currentConfig = loadConfig("switchDisplayTwoScreens.json");
0369     QVERIFY(currentConfig);
0370 
0371     Generator *generator = Generator::self();
0372     generator->setCurrentConfig(currentConfig);
0373     generator->setForceLaptop(true);
0374     generator->setForceNotLaptop(false);
0375     generator->setForceDocked(false);
0376     generator->setForceLidClosed(false);
0377 
0378     // Clone all
0379     ConfigPtr config = generator->displaySwitch(Generator::Clone);
0380     OutputPtr laptop = config->outputs().value(1);
0381     OutputPtr external = config->outputs().value(2);
0382     QCOMPARE(laptop->currentModeId(), QLatin1String("2"));
0383     QCOMPARE(laptop->isPrimary(), true);
0384     QCOMPARE(laptop->isEnabled(), true);
0385     QCOMPARE(laptop->pos(), QPoint(0, 0));
0386     QCOMPARE(external->currentModeId(), QLatin1String("3"));
0387     QCOMPARE(external->isPrimary(), false);
0388     QCOMPARE(external->isEnabled(), true);
0389     QCOMPARE(external->pos(), QPoint(0, 0));
0390 
0391     // Extend to left
0392     config = generator->displaySwitch(Generator::ExtendToLeft);
0393     laptop = config->outputs().value(1);
0394     external = config->outputs().value(2);
0395     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0396     QCOMPARE(laptop->isPrimary(), true);
0397     QCOMPARE(laptop->isEnabled(), true);
0398     QCOMPARE(laptop->pos(), QPoint(1920, 0));
0399     QCOMPARE(external->currentModeId(), QLatin1String("5"));
0400     QCOMPARE(external->isPrimary(), false);
0401     QCOMPARE(external->isEnabled(), true);
0402     QCOMPARE(external->pos(), QPoint(0, 0));
0403 
0404     // Disable embedded,. enable external
0405     config = generator->displaySwitch(Generator::TurnOffEmbedded);
0406     laptop = config->outputs().value(1);
0407     external = config->outputs().value(2);
0408     ;
0409     QCOMPARE(laptop->isEnabled(), false);
0410     QCOMPARE(external->currentModeId(), QLatin1String("5"));
0411     QCOMPARE(external->isPrimary(), true);
0412     QCOMPARE(external->isEnabled(), true);
0413     QCOMPARE(external->pos(), QPoint(0, 0));
0414 
0415     // Enable embedded, disable external
0416     config = generator->displaySwitch(Generator::TurnOffExternal);
0417     laptop = config->outputs().value(1);
0418     external = config->outputs().value(2);
0419     ;
0420     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0421     QCOMPARE(laptop->isPrimary(), true);
0422     QCOMPARE(laptop->isEnabled(), true);
0423     QCOMPARE(laptop->pos(), QPoint(0, 0));
0424     ;
0425     QCOMPARE(external->isEnabled(), false);
0426 
0427     // Extend to right
0428     config = generator->displaySwitch(Generator::ExtendToRight);
0429     laptop = config->outputs().value(1);
0430     external = config->outputs().value(2);
0431     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0432     QCOMPARE(laptop->isPrimary(), true);
0433     QCOMPARE(laptop->isEnabled(), true);
0434     QCOMPARE(laptop->pos(), QPoint(0, 0));
0435     QCOMPARE(external->currentModeId(), QLatin1String("5"));
0436     QCOMPARE(external->isPrimary(), false);
0437     QCOMPARE(external->isEnabled(), true);
0438     QCOMPARE(external->pos(), QPoint(1280, 0));
0439 }
0440 
0441 void testScreenConfig::switchDisplayTwoScreensOneRotated()
0442 {
0443     const ConfigPtr currentConfig = loadConfig("switchDisplayTwoScreensOneRotated.json");
0444     QVERIFY(currentConfig);
0445 
0446     Generator *generator = Generator::self();
0447     generator->setCurrentConfig(currentConfig);
0448     generator->setForceLaptop(true);
0449     generator->setForceNotLaptop(false);
0450     generator->setForceDocked(false);
0451     generator->setForceLidClosed(false);
0452 
0453     QCOMPARE(currentConfig->outputs().value(1)->rotation(), KScreen::Output::Right);
0454     {
0455         auto config = Generator::self()->idealConfig(currentConfig);
0456         OutputPtr laptop = config->outputs().value(1);
0457         OutputPtr external = config->outputs().value(2);
0458 
0459         QCOMPARE(laptop->pos(), QPoint(0, 0));
0460         QCOMPARE(external->pos(), QPoint(800, 0));
0461     }
0462 
0463     // Skipping cloning for now, I am not sure what's the best way forward here.
0464     // We probably should not offer the option to clone if both displays have a different ratio?
0465 
0466     // Extend to left
0467     ConfigPtr config = generator->displaySwitch(Generator::ExtendToLeft);
0468     OutputPtr laptop = config->outputs().value(1);
0469     OutputPtr external = config->outputs().value(2);
0470     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0471     QCOMPARE(laptop->isPrimary(), true);
0472     QCOMPARE(laptop->isEnabled(), true);
0473     QCOMPARE(laptop->pos(), QPoint(1920, 0));
0474     QCOMPARE(laptop->rotation(), KScreen::Output::Right);
0475     QCOMPARE(external->currentModeId(), QLatin1String("5"));
0476     QCOMPARE(external->isPrimary(), false);
0477     QCOMPARE(external->isEnabled(), true);
0478     QCOMPARE(external->pos(), QPoint(0, 0));
0479 
0480     // Disable embedded,. enable external
0481     config = generator->displaySwitch(Generator::TurnOffEmbedded);
0482     laptop = config->outputs().value(1);
0483     external = config->outputs().value(2);
0484     ;
0485     QCOMPARE(laptop->isEnabled(), false);
0486     QCOMPARE(external->currentModeId(), QLatin1String("5"));
0487     QCOMPARE(external->isPrimary(), true);
0488     QCOMPARE(external->isEnabled(), true);
0489     QCOMPARE(external->pos(), QPoint(0, 0));
0490 
0491     // Enable embedded, disable external
0492     config = generator->displaySwitch(Generator::TurnOffExternal);
0493     laptop = config->outputs().value(1);
0494     external = config->outputs().value(2);
0495     ;
0496     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0497     QCOMPARE(laptop->isPrimary(), true);
0498     QCOMPARE(laptop->isEnabled(), true);
0499     QCOMPARE(laptop->pos(), QPoint(0, 0));
0500     QCOMPARE(laptop->rotation(), KScreen::Output::Right);
0501     ;
0502     QCOMPARE(external->isEnabled(), false);
0503 
0504     // Extend to right
0505     config = generator->displaySwitch(Generator::ExtendToRight);
0506     laptop = config->outputs().value(1);
0507     external = config->outputs().value(2);
0508     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0509     QCOMPARE(laptop->isPrimary(), true);
0510     QCOMPARE(laptop->isEnabled(), true);
0511     QCOMPARE(laptop->pos(), QPoint(0, 0));
0512     QCOMPARE(laptop->rotation(), KScreen::Output::Right);
0513     QCOMPARE(external->currentModeId(), QLatin1String("5"));
0514     QCOMPARE(external->isPrimary(), false);
0515     QCOMPARE(external->isEnabled(), true);
0516     QCOMPARE(external->pos(), QPoint(800, 0));
0517 }
0518 
0519 void testScreenConfig::switchDisplayTwoScreensNoCommonMode()
0520 {
0521     const ConfigPtr currentConfig = loadConfig("switchDisplayTwoScreensNoCommonMode.json");
0522     QVERIFY(currentConfig);
0523 
0524     Generator *generator = Generator::self();
0525     generator->setCurrentConfig(currentConfig);
0526     ConfigPtr config = generator->displaySwitch(Generator::Clone);
0527     OutputPtr laptop = config->outputs().value(1);
0528     OutputPtr external = config->outputs().value(2);
0529 
0530     QCOMPARE(laptop->currentModeId(), QLatin1String("3"));
0531     QCOMPARE(laptop->isPrimary(), true);
0532     QCOMPARE(laptop->isEnabled(), true);
0533     QCOMPARE(laptop->pos(), QPoint(0, 0));
0534     QCOMPARE(external->currentModeId(), QLatin1String("5"));
0535     QCOMPARE(external->isPrimary(), false);
0536     QCOMPARE(external->isEnabled(), true);
0537     QCOMPARE(external->pos(), QPoint(0, 0));
0538 }
0539 
0540 void testScreenConfig::globalOutputData()
0541 {
0542     const ConfigPtr currentConfig = loadConfig("singleOutput.json");
0543 
0544     auto config = Generator::self()->idealConfig(currentConfig);
0545     auto output = config->connectedOutputs().first();
0546     QCOMPARE(output->currentModeId(), QLatin1String("3"));
0547     QCOMPARE(output->rotation(), KScreen::Output::None);
0548     QCOMPARE(output->scale(), 1.0);
0549 
0550     output->setCurrentModeId(QStringLiteral("2"));
0551     output->setRotation(KScreen::Output::Left);
0552     output->setScale(2.0);
0553     ::Output::writeGlobal(output, false);
0554 
0555     config = Generator::self()->idealConfig(currentConfig);
0556     output = config->connectedOutputs().first();
0557     QCOMPARE(output->currentModeId(), QLatin1String("2"));
0558     QCOMPARE(output->rotation(), KScreen::Output::Left);
0559     // Fake backend does not support perOutputScale
0560     QCOMPARE(output->scale(), 1.0);
0561 
0562     // But simulate it now
0563     currentConfig->setSupportedFeatures(currentConfig->supportedFeatures() | KScreen::Config::Feature::PerOutputScaling);
0564     config = Generator::self()->idealConfig(currentConfig);
0565     output = config->connectedOutputs().first();
0566     QCOMPARE(output->currentModeId(), QLatin1String("2"));
0567     QCOMPARE(output->rotation(), KScreen::Output::Left);
0568     QCOMPARE(output->scale(), 2.0);
0569 
0570     // cleanup
0571     QFile::remove(::Output::dirPath() + output->hashMd5());
0572 }
0573 
0574 void testScreenConfig::outputPreset()
0575 {
0576     const ConfigPtr currentConfig = loadConfig("singleOutput.json");
0577     currentConfig->setSupportedFeatures(currentConfig->supportedFeatures() | KScreen::Config::Feature::PerOutputScaling);
0578     auto defaultOutput = Generator::self()->idealConfig(currentConfig)->connectedOutputs().first();
0579     QCOMPARE(defaultOutput->currentModeId(), QLatin1String("3"));
0580     QCOMPARE(defaultOutput->rotation(), KScreen::Output::None);
0581     QCOMPARE(defaultOutput->scale(), 1.0);
0582 
0583     // Create the preset
0584     QTemporaryDir dataDir;
0585     qputenv("XDG_DATA_DIRS", dataDir.path().toUtf8());
0586     QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation);
0587     auto presetOutput = defaultOutput->clone();
0588     presetOutput->setCurrentModeId(QStringLiteral("2"));
0589     presetOutput->setRotation(KScreen::Output::Left);
0590     presetOutput->setScale(2.0);
0591     ::Output::writeGlobal(presetOutput, false);
0592     QDir(dataDir.path()).mkpath(QStringLiteral("kscreen/outputs"));
0593     QFile::copy(::Output::dirPath() + presetOutput->hashMd5(), dataDir.filePath(QStringLiteral("kscreen/outputs/") % presetOutput->hashMd5()));
0594     QFile::remove(::Output::dirPath() + presetOutput->hashMd5());
0595 
0596     auto config = Generator::self()->idealConfig(currentConfig);
0597     auto output = config->connectedOutputs().first();
0598     QCOMPARE(output->currentModeId(), QLatin1String("2"));
0599     QCOMPARE(output->rotation(), KScreen::Output::Left);
0600     QCOMPARE(output->scale(), 2.0);
0601 
0602     // But local global settings should still overwrite
0603     ::Output::writeGlobal(defaultOutput, false);
0604     config = Generator::self()->idealConfig(currentConfig);
0605     output = config->connectedOutputs().first();
0606     QCOMPARE(output->currentModeId(), QLatin1String("3"));
0607     QCOMPARE(output->rotation(), KScreen::Output::None);
0608     QCOMPARE(output->scale(), 1.0);
0609 
0610     QFile::remove(::Output::dirPath() + defaultOutput->hashMd5());
0611 }
0612 
0613 void testScreenConfig::autogeneratedScreenScales()
0614 {
0615     // Test desktop screen configs
0616     ConfigPtr desktopConfig = loadConfig("AutogeneratedDesktopScreenScales.json");
0617     QVERIFY(desktopConfig);
0618 
0619     Generator *desktopGenerator = Generator::self();
0620     desktopGenerator->setCurrentConfig(desktopConfig);
0621     desktopGenerator->setForceLaptop(false);
0622     desktopGenerator->setForceNotLaptop(true);
0623     ConfigPtr currentDesktopConfig = desktopGenerator->idealConfig(desktopConfig);
0624     OutputPtr currentDesktopOutput;
0625     QCOMPARE(currentDesktopConfig->outputs().size() > 0, true);
0626 
0627     for (int i = 1; i <= currentDesktopConfig->outputs().size(); i++) {
0628         currentDesktopOutput = currentDesktopConfig->outputs().value(i);
0629         currentDesktopOutput->setCurrentModeId(QStringLiteral("1"));
0630         QCOMPARE(desktopGenerator->bestScaleForOutput(currentDesktopOutput), currentDesktopOutput->scale());
0631     }
0632 
0633     // Test laptop screen configs
0634     ConfigPtr laptopConfig = loadConfig("AutogeneratedLaptopScreenScales.json");
0635     QVERIFY(laptopConfig);
0636 
0637     Generator *laptopGenerator = Generator::self();
0638     laptopGenerator->setCurrentConfig(laptopConfig);
0639     laptopGenerator->setForceLaptop(true);
0640     laptopGenerator->setForceNotLaptop(false);
0641     ConfigPtr currentlaptopConfig = laptopGenerator->idealConfig(laptopConfig);
0642     OutputPtr currentLaptopOutput;
0643     QCOMPARE(currentlaptopConfig->outputs().size() > 0, true);
0644 
0645     for (int i = 1; i <= currentlaptopConfig->outputs().size(); i++) {
0646         currentLaptopOutput = currentlaptopConfig->outputs().value(i);
0647         currentLaptopOutput->setCurrentModeId(QStringLiteral("1"));
0648         QCOMPARE(laptopGenerator->bestScaleForOutput(currentLaptopOutput), currentLaptopOutput->scale());
0649     }
0650 
0651     // Test mobile device screen configs
0652     ConfigPtr mobileConfig = loadConfig("AutogeneratedMobileScreenScales.json");
0653     QVERIFY(mobileConfig);
0654 
0655     Generator *mobileGenerator = Generator::self();
0656     mobileGenerator->setCurrentConfig(mobileConfig);
0657     mobileGenerator->setForceLaptop(false);
0658     mobileGenerator->setForceNotLaptop(true);
0659     ConfigPtr currentMobileConfig = mobileGenerator->idealConfig(mobileConfig);
0660     OutputPtr currentMobileOutput;
0661 
0662     QCOMPARE(currentMobileConfig->outputs().size() > 0, true);
0663 
0664     for (int i = 1; i <= currentMobileConfig->outputs().size(); i++) {
0665         currentMobileOutput = currentMobileConfig->outputs().value(i);
0666         currentMobileOutput->setCurrentModeId(QStringLiteral("1"));
0667         // When it's a panel but not a laptop, it's a mobile device
0668         currentMobileOutput->setType(KScreen::Output::Panel);
0669         QCOMPARE(desktopGenerator->bestScaleForOutput(currentMobileOutput), currentMobileOutput->scale());
0670     }
0671 }
0672 
0673 QTEST_MAIN(testScreenConfig)
0674 
0675 #include "testgenerator.moc"