File indexing completed on 2024-05-19 16:33:11
0001 /* 0002 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org> 0003 SPDX-FileCopyrightText: 2017 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 #include "../src/client/xdgforeign.h" 0008 #include "../src/client/compositor.h" 0009 #include "../src/client/connection_thread.h" 0010 #include "../src/client/event_queue.h" 0011 #include "../src/client/registry.h" 0012 #include "../src/client/server_decoration.h" 0013 #include "../src/client/shell.h" 0014 #include "../src/client/shm_pool.h" 0015 #include "../src/client/xdgshell.h" 0016 // Qt 0017 #include <QCommandLineParser> 0018 #include <QDebug> 0019 #include <QGuiApplication> 0020 #include <QImage> 0021 #include <QThread> 0022 using namespace KWayland::Client; 0023 0024 class XdgForeignTest : public QObject 0025 { 0026 Q_OBJECT 0027 public: 0028 explicit XdgForeignTest(QObject *parent = nullptr); 0029 ~XdgForeignTest() override; 0030 0031 void init(); 0032 0033 private: 0034 void setupRegistry(Registry *registry); 0035 void render(); 0036 QThread *m_connectionThread; 0037 ConnectionThread *m_connectionThreadObject; 0038 EventQueue *m_eventQueue = nullptr; 0039 Compositor *m_compositor = nullptr; 0040 XdgShell *m_shell = nullptr; 0041 XdgShellSurface *m_shellSurface = nullptr; 0042 ShmPool *m_shm = nullptr; 0043 Surface *m_surface = nullptr; 0044 0045 XdgShellSurface *m_childShellSurface = nullptr; 0046 Surface *m_childSurface = nullptr; 0047 0048 KWayland::Client::XdgExporter *m_exporter = nullptr; 0049 KWayland::Client::XdgImporter *m_importer = nullptr; 0050 KWayland::Client::XdgExported *m_exported = nullptr; 0051 KWayland::Client::XdgImported *m_imported = nullptr; 0052 KWayland::Client::ServerSideDecorationManager *m_decoration = nullptr; 0053 }; 0054 0055 XdgForeignTest::XdgForeignTest(QObject *parent) 0056 : QObject(parent) 0057 , m_connectionThread(new QThread(this)) 0058 , m_connectionThreadObject(new ConnectionThread()) 0059 { 0060 } 0061 0062 XdgForeignTest::~XdgForeignTest() 0063 { 0064 m_connectionThread->quit(); 0065 m_connectionThread->wait(); 0066 m_connectionThreadObject->deleteLater(); 0067 } 0068 0069 void XdgForeignTest::init() 0070 { 0071 connect( 0072 m_connectionThreadObject, 0073 &ConnectionThread::connected, 0074 this, 0075 [this] { 0076 m_eventQueue = new EventQueue(this); 0077 m_eventQueue->setup(m_connectionThreadObject); 0078 0079 Registry *registry = new Registry(this); 0080 setupRegistry(registry); 0081 }, 0082 Qt::QueuedConnection); 0083 m_connectionThreadObject->moveToThread(m_connectionThread); 0084 m_connectionThread->start(); 0085 0086 m_connectionThreadObject->initConnection(); 0087 } 0088 0089 void XdgForeignTest::setupRegistry(Registry *registry) 0090 { 0091 connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name, quint32 version) { 0092 m_compositor = registry->createCompositor(name, version, this); 0093 }); 0094 connect(registry, &Registry::xdgShellUnstableV5Announced, this, [this, registry](quint32 name, quint32 version) { 0095 m_shell = registry->createXdgShell(name, version, this); 0096 }); 0097 connect(registry, &Registry::shmAnnounced, this, [this, registry](quint32 name, quint32 version) { 0098 m_shm = registry->createShmPool(name, version, this); 0099 }); 0100 connect(registry, &Registry::exporterUnstableV2Announced, this, [this, registry](quint32 name, quint32 version) { 0101 m_exporter = registry->createXdgExporter(name, version, this); 0102 m_exporter->setEventQueue(m_eventQueue); 0103 }); 0104 connect(registry, &Registry::importerUnstableV2Announced, this, [this, registry](quint32 name, quint32 version) { 0105 m_importer = registry->createXdgImporter(name, version, this); 0106 m_importer->setEventQueue(m_eventQueue); 0107 }); 0108 connect(registry, &Registry::serverSideDecorationManagerAnnounced, this, [this, registry](quint32 name, quint32 version) { 0109 m_decoration = registry->createServerSideDecorationManager(name, version, this); 0110 m_decoration->setEventQueue(m_eventQueue); 0111 }); 0112 connect(registry, &Registry::interfacesAnnounced, this, [this] { 0113 Q_ASSERT(m_compositor); 0114 Q_ASSERT(m_shell); 0115 Q_ASSERT(m_shm); 0116 Q_ASSERT(m_exporter); 0117 Q_ASSERT(m_importer); 0118 m_surface = m_compositor->createSurface(this); 0119 Q_ASSERT(m_surface); 0120 auto parentDeco = m_decoration->create(m_surface, this); 0121 Q_UNUSED(parentDeco) 0122 m_shellSurface = m_shell->createSurface(m_surface, this); 0123 Q_ASSERT(m_shellSurface); 0124 connect(m_shellSurface, &XdgShellSurface::sizeChanged, this, &XdgForeignTest::render); 0125 0126 m_childSurface = m_compositor->createSurface(this); 0127 Q_ASSERT(m_childSurface); 0128 auto childDeco = m_decoration->create(m_childSurface, this); 0129 Q_UNUSED(childDeco) 0130 m_childShellSurface = m_shell->createSurface(m_childSurface, this); 0131 Q_ASSERT(m_childShellSurface); 0132 connect(m_childShellSurface, &XdgShellSurface::sizeChanged, this, &XdgForeignTest::render); 0133 0134 m_exported = m_exporter->exportTopLevel(m_surface, this); 0135 Q_ASSERT(m_decoration); 0136 connect(m_exported, &XdgExported::done, this, [this]() { 0137 m_imported = m_importer->importTopLevel(m_exported->handle(), this); 0138 m_imported->setParentOf(m_childSurface); 0139 }); 0140 render(); 0141 }); 0142 registry->setEventQueue(m_eventQueue); 0143 registry->create(m_connectionThreadObject); 0144 registry->setup(); 0145 } 0146 0147 void XdgForeignTest::render() 0148 { 0149 QSize size = m_shellSurface->size().isValid() ? m_shellSurface->size() : QSize(500, 500); 0150 auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef(); 0151 buffer->setUsed(true); 0152 QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); 0153 image.fill(QColor(255, 255, 255, 255)); 0154 0155 m_surface->attachBuffer(*buffer); 0156 m_surface->damage(QRect(QPoint(0, 0), size)); 0157 m_surface->commit(Surface::CommitFlag::None); 0158 buffer->setUsed(false); 0159 0160 size = m_childShellSurface->size().isValid() ? m_childShellSurface->size() : QSize(200, 200); 0161 buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef(); 0162 buffer->setUsed(true); 0163 image = QImage(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); 0164 image.fill(QColor(255, 0, 0, 255)); 0165 0166 m_childSurface->attachBuffer(*buffer); 0167 m_childSurface->damage(QRect(QPoint(0, 0), size)); 0168 m_childSurface->commit(Surface::CommitFlag::None); 0169 buffer->setUsed(false); 0170 } 0171 0172 int main(int argc, char **argv) 0173 { 0174 QCoreApplication app(argc, argv); 0175 0176 XdgForeignTest client; 0177 0178 client.init(); 0179 0180 return app.exec(); 0181 } 0182 0183 #include "xdgforeigntest.moc"