File indexing completed on 2024-11-10 04:56:17

0001 /*
0002     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
0003     SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 // Qt
0008 #include <QSignalSpy>
0009 #include <QTest>
0010 // KWin
0011 #include "wayland/compositor.h"
0012 #include "wayland/contrast.h"
0013 #include "wayland/display.h"
0014 
0015 #include "KWayland/Client/compositor.h"
0016 #include "KWayland/Client/connection_thread.h"
0017 #include "KWayland/Client/contrast.h"
0018 #include "KWayland/Client/event_queue.h"
0019 #include "KWayland/Client/region.h"
0020 #include "KWayland/Client/registry.h"
0021 #include "KWayland/Client/surface.h"
0022 
0023 #include <wayland-util.h>
0024 
0025 class TestContrast : public QObject
0026 {
0027     Q_OBJECT
0028 public:
0029     explicit TestContrast(QObject *parent = nullptr);
0030 private Q_SLOTS:
0031     void init();
0032     void cleanup();
0033 
0034     void testCreate();
0035     void testSurfaceDestroy();
0036 
0037 private:
0038     KWin::Display *m_display;
0039     KWin::CompositorInterface *m_compositorInterface;
0040     KWin::ContrastManagerInterface *m_contrastManagerInterface;
0041     KWayland::Client::ConnectionThread *m_connection;
0042     KWayland::Client::Compositor *m_compositor;
0043     KWayland::Client::ContrastManager *m_contrastManager;
0044     KWayland::Client::EventQueue *m_queue;
0045     QThread *m_thread;
0046 };
0047 
0048 static const QString s_socketName = QStringLiteral("kwayland-test-wayland-contrast-0");
0049 
0050 TestContrast::TestContrast(QObject *parent)
0051     : QObject(parent)
0052     , m_display(nullptr)
0053     , m_compositorInterface(nullptr)
0054     , m_connection(nullptr)
0055     , m_compositor(nullptr)
0056     , m_queue(nullptr)
0057     , m_thread(nullptr)
0058 {
0059 }
0060 
0061 void TestContrast::init()
0062 {
0063     using namespace KWin;
0064     delete m_display;
0065     m_display = new KWin::Display(this);
0066     m_display->addSocketName(s_socketName);
0067     m_display->start();
0068     QVERIFY(m_display->isRunning());
0069 
0070     // setup connection
0071     m_connection = new KWayland::Client::ConnectionThread;
0072     QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
0073     m_connection->setSocketName(s_socketName);
0074 
0075     m_thread = new QThread(this);
0076     m_connection->moveToThread(m_thread);
0077     m_thread->start();
0078 
0079     m_connection->initConnection();
0080     QVERIFY(connectedSpy.wait());
0081 
0082     m_queue = new KWayland::Client::EventQueue(this);
0083     QVERIFY(!m_queue->isValid());
0084     m_queue->setup(m_connection);
0085     QVERIFY(m_queue->isValid());
0086 
0087     KWayland::Client::Registry registry;
0088     QSignalSpy compositorSpy(&registry, &KWayland::Client::Registry::compositorAnnounced);
0089 
0090     QSignalSpy contrastSpy(&registry, &KWayland::Client::Registry::contrastAnnounced);
0091 
0092     QVERIFY(!registry.eventQueue());
0093     registry.setEventQueue(m_queue);
0094     QCOMPARE(registry.eventQueue(), m_queue);
0095     registry.create(m_connection->display());
0096     QVERIFY(registry.isValid());
0097     registry.setup();
0098 
0099     m_compositorInterface = new CompositorInterface(m_display, m_display);
0100     QVERIFY(compositorSpy.wait());
0101     m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this);
0102 
0103     m_contrastManagerInterface = new ContrastManagerInterface(m_display, m_display);
0104 
0105     QVERIFY(contrastSpy.wait());
0106     m_contrastManager = registry.createContrastManager(contrastSpy.first().first().value<quint32>(), contrastSpy.first().last().value<quint32>(), this);
0107 }
0108 
0109 void TestContrast::cleanup()
0110 {
0111 #define CLEANUP(variable)   \
0112     if (variable) {         \
0113         delete variable;    \
0114         variable = nullptr; \
0115     }
0116     CLEANUP(m_compositor)
0117     CLEANUP(m_contrastManager)
0118     CLEANUP(m_queue)
0119     if (m_connection) {
0120         m_connection->deleteLater();
0121         m_connection = nullptr;
0122     }
0123     if (m_thread) {
0124         m_thread->quit();
0125         m_thread->wait();
0126         delete m_thread;
0127         m_thread = nullptr;
0128     }
0129     CLEANUP(m_display)
0130 #undef CLEANUP
0131 
0132     // these are the children of the display
0133     m_compositorInterface = nullptr;
0134     m_contrastManagerInterface = nullptr;
0135 }
0136 
0137 void TestContrast::testCreate()
0138 {
0139     QSignalSpy serverSurfaceCreated(m_compositorInterface, &KWin::CompositorInterface::surfaceCreated);
0140 
0141     std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
0142     QVERIFY(serverSurfaceCreated.wait());
0143 
0144     auto serverSurface = serverSurfaceCreated.first().first().value<KWin::SurfaceInterface *>();
0145     QSignalSpy contrastChanged(serverSurface, &KWin::SurfaceInterface::contrastChanged);
0146 
0147     auto contrast = m_contrastManager->createContrast(surface.get(), surface.get());
0148     contrast->setRegion(m_compositor->createRegion(QRegion(0, 0, 10, 20), nullptr));
0149 
0150     contrast->setContrast(0.2);
0151     contrast->setIntensity(2.0);
0152     contrast->setSaturation(1.7);
0153 
0154     contrast->commit();
0155     surface->commit(KWayland::Client::Surface::CommitFlag::None);
0156 
0157     QVERIFY(contrastChanged.wait());
0158     QCOMPARE(serverSurface->contrast()->region(), QRegion(0, 0, 10, 20));
0159     QCOMPARE(wl_fixed_from_double(serverSurface->contrast()->contrast()), wl_fixed_from_double(0.2));
0160     QCOMPARE(wl_fixed_from_double(serverSurface->contrast()->intensity()), wl_fixed_from_double(2.0));
0161     QCOMPARE(wl_fixed_from_double(serverSurface->contrast()->saturation()), wl_fixed_from_double(1.7));
0162 
0163     // and destroy
0164     QSignalSpy destroyedSpy(serverSurface->contrast(), &QObject::destroyed);
0165     delete contrast;
0166     QVERIFY(destroyedSpy.wait());
0167 }
0168 
0169 void TestContrast::testSurfaceDestroy()
0170 {
0171     QSignalSpy serverSurfaceCreated(m_compositorInterface, &KWin::CompositorInterface::surfaceCreated);
0172 
0173     std::unique_ptr<KWayland::Client::Surface> surface(m_compositor->createSurface());
0174     QVERIFY(serverSurfaceCreated.wait());
0175 
0176     auto serverSurface = serverSurfaceCreated.first().first().value<KWin::SurfaceInterface *>();
0177     QSignalSpy contrastChanged(serverSurface, &KWin::SurfaceInterface::contrastChanged);
0178 
0179     std::unique_ptr<KWayland::Client::Contrast> contrast(m_contrastManager->createContrast(surface.get()));
0180     contrast->setRegion(m_compositor->createRegion(QRegion(0, 0, 10, 20), nullptr));
0181     contrast->commit();
0182     surface->commit(KWayland::Client::Surface::CommitFlag::None);
0183 
0184     QVERIFY(contrastChanged.wait());
0185     QCOMPARE(serverSurface->contrast()->region(), QRegion(0, 0, 10, 20));
0186 
0187     // destroy the parent surface
0188     QSignalSpy surfaceDestroyedSpy(serverSurface, &QObject::destroyed);
0189     QSignalSpy contrastDestroyedSpy(serverSurface->contrast(), &QObject::destroyed);
0190     surface.reset();
0191     QVERIFY(surfaceDestroyedSpy.wait());
0192     QVERIFY(contrastDestroyedSpy.isEmpty());
0193     // destroy the blur
0194     contrast.reset();
0195     QVERIFY(contrastDestroyedSpy.wait());
0196 }
0197 
0198 QTEST_GUILESS_MAIN(TestContrast)
0199 #include "test_wayland_contrast.moc"