File indexing completed on 2024-12-01 05:02:04
0001 /* 0002 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "KWayland/Client/shadow.h" 0007 #include "KWayland/Client/compositor.h" 0008 #include "KWayland/Client/connection_thread.h" 0009 #include "KWayland/Client/event_queue.h" 0010 #include "KWayland/Client/registry.h" 0011 #include "KWayland/Client/shell.h" 0012 #include "KWayland/Client/shm_pool.h" 0013 #include "KWayland/Client/surface.h" 0014 // Qt 0015 #include <QGuiApplication> 0016 #include <QImage> 0017 #include <QThread> 0018 0019 using namespace KWayland::Client; 0020 0021 class ShadowTest : public QObject 0022 { 0023 Q_OBJECT 0024 public: 0025 explicit ShadowTest(QObject *parent = nullptr); 0026 virtual ~ShadowTest(); 0027 0028 void init(); 0029 0030 private: 0031 void setupRegistry(Registry *registry); 0032 void setupShadow(); 0033 void render(); 0034 QThread *m_connectionThread; 0035 ConnectionThread *m_connectionThreadObject; 0036 EventQueue *m_eventQueue = nullptr; 0037 Compositor *m_compositor = nullptr; 0038 Shell *m_shell = nullptr; 0039 ShellSurface *m_shellSurface = nullptr; 0040 ShmPool *m_shm = nullptr; 0041 Surface *m_surface = nullptr; 0042 ShadowManager *m_shadowManager = nullptr; 0043 }; 0044 0045 ShadowTest::ShadowTest(QObject *parent) 0046 : QObject(parent) 0047 , m_connectionThread(new QThread(this)) 0048 , m_connectionThreadObject(new ConnectionThread()) 0049 { 0050 } 0051 0052 ShadowTest::~ShadowTest() 0053 { 0054 m_connectionThread->quit(); 0055 m_connectionThread->wait(); 0056 m_connectionThreadObject->deleteLater(); 0057 } 0058 0059 void ShadowTest::init() 0060 { 0061 connect( 0062 m_connectionThreadObject, 0063 &ConnectionThread::connected, 0064 this, 0065 [this] { 0066 m_eventQueue = new EventQueue(this); 0067 m_eventQueue->setup(m_connectionThreadObject); 0068 0069 Registry *registry = new Registry(this); 0070 setupRegistry(registry); 0071 }, 0072 Qt::QueuedConnection); 0073 m_connectionThreadObject->moveToThread(m_connectionThread); 0074 m_connectionThread->start(); 0075 0076 m_connectionThreadObject->initConnection(); 0077 } 0078 0079 void ShadowTest::setupRegistry(Registry *registry) 0080 { 0081 connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name, quint32 version) { 0082 m_compositor = registry->createCompositor(name, version, this); 0083 }); 0084 connect(registry, &Registry::shellAnnounced, this, [this, registry](quint32 name, quint32 version) { 0085 m_shell = registry->createShell(name, version, this); 0086 }); 0087 connect(registry, &Registry::shmAnnounced, this, [this, registry](quint32 name, quint32 version) { 0088 m_shm = registry->createShmPool(name, version, this); 0089 }); 0090 connect(registry, &Registry::shadowAnnounced, this, [this, registry](quint32 name, quint32 version) { 0091 m_shadowManager = registry->createShadowManager(name, version, this); 0092 m_shadowManager->setEventQueue(m_eventQueue); 0093 }); 0094 connect(registry, &Registry::interfacesAnnounced, this, [this] { 0095 Q_ASSERT(m_compositor); 0096 Q_ASSERT(m_shell); 0097 Q_ASSERT(m_shm); 0098 m_surface = m_compositor->createSurface(this); 0099 Q_ASSERT(m_surface); 0100 setupShadow(); 0101 m_shellSurface = m_shell->createSurface(m_surface, this); 0102 Q_ASSERT(m_shellSurface); 0103 m_shellSurface->setToplevel(); 0104 connect(m_shellSurface, &ShellSurface::sizeChanged, this, &ShadowTest::render); 0105 render(); 0106 }); 0107 registry->setEventQueue(m_eventQueue); 0108 registry->create(m_connectionThreadObject); 0109 registry->setup(); 0110 } 0111 0112 void ShadowTest::setupShadow() 0113 { 0114 Q_ASSERT(m_shadowManager); 0115 Shadow *shadow = m_shadowManager->createShadow(m_surface, this); 0116 Q_ASSERT(shadow); 0117 0118 auto addElement = [this](const QColor color) { 0119 const QSize size = QSize(10, 10); 0120 auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef(); 0121 buffer->setUsed(true); 0122 QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); 0123 image.fill(color); 0124 return buffer; 0125 }; 0126 shadow->attachTopLeft(addElement(Qt::red)); 0127 shadow->attachTop(addElement(Qt::darkRed)); 0128 shadow->attachTopRight(addElement(Qt::green)); 0129 shadow->attachRight(addElement(Qt::darkGreen)); 0130 shadow->attachBottomRight(addElement(Qt::darkBlue)); 0131 shadow->attachBottom(addElement(Qt::cyan)); 0132 shadow->attachBottomLeft(addElement(Qt::darkCyan)); 0133 shadow->attachLeft(addElement(Qt::magenta)); 0134 shadow->setOffsets(QMarginsF(5, 5, 5, 5)); 0135 shadow->commit(); 0136 } 0137 0138 void ShadowTest::render() 0139 { 0140 const QSize &size = m_shellSurface->size().isValid() ? m_shellSurface->size() : QSize(300, 200); 0141 auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef(); 0142 buffer->setUsed(true); 0143 QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); 0144 image.fill(QColor(255, 255, 255, 128)); 0145 0146 m_surface->attachBuffer(*buffer); 0147 m_surface->damage(QRect(QPoint(0, 0), size)); 0148 m_surface->commit(Surface::CommitFlag::None); 0149 buffer->setUsed(false); 0150 } 0151 0152 int main(int argc, char **argv) 0153 { 0154 QCoreApplication app(argc, argv); 0155 ShadowTest client; 0156 client.init(); 0157 0158 return app.exec(); 0159 } 0160 0161 #include "shadowtest.moc"