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