1 | /* |
2 | SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
5 | */ |
6 | #include "../src/client/shadow.h" |
7 | #include "../src/client/compositor.h" |
8 | #include "../src/client/connection_thread.h" |
9 | #include "../src/client/event_queue.h" |
10 | #include "../src/client/registry.h" |
11 | #include "../src/client/shell.h" |
12 | #include "../src/client/shm_pool.h" |
13 | #include "../src/client/surface.h" |
14 | // Qt |
15 | #include <QGuiApplication> |
16 | #include <QImage> |
17 | #include <QThread> |
18 | |
19 | using namespace KWayland::Client; |
20 | |
21 | class ShadowTest : public QObject |
22 | { |
23 | Q_OBJECT |
24 | public: |
25 | explicit ShadowTest(QObject *parent = nullptr); |
26 | ~ShadowTest() override; |
27 | |
28 | void init(); |
29 | |
30 | private: |
31 | void setupRegistry(Registry *registry); |
32 | void setupShadow(); |
33 | void render(); |
34 | QThread *m_connectionThread; |
35 | ConnectionThread *m_connectionThreadObject; |
36 | EventQueue *m_eventQueue = nullptr; |
37 | Compositor *m_compositor = nullptr; |
38 | Shell *m_shell = nullptr; |
39 | ShellSurface *m_shellSurface = nullptr; |
40 | ShmPool *m_shm = nullptr; |
41 | Surface *m_surface = nullptr; |
42 | ShadowManager *m_shadowManager = nullptr; |
43 | }; |
44 | |
45 | ShadowTest::ShadowTest(QObject *parent) |
46 | : QObject(parent) |
47 | , m_connectionThread(new QThread(this)) |
48 | , m_connectionThreadObject(new ConnectionThread()) |
49 | { |
50 | } |
51 | |
52 | ShadowTest::~ShadowTest() |
53 | { |
54 | m_connectionThread->quit(); |
55 | m_connectionThread->wait(); |
56 | m_connectionThreadObject->deleteLater(); |
57 | } |
58 | |
59 | void ShadowTest::init() |
60 | { |
61 | connect( |
62 | sender: m_connectionThreadObject, |
63 | signal: &ConnectionThread::connected, |
64 | context: this, |
65 | slot: [this] { |
66 | m_eventQueue = new EventQueue(this); |
67 | m_eventQueue->setup(m_connectionThreadObject); |
68 | |
69 | Registry *registry = new Registry(this); |
70 | setupRegistry(registry); |
71 | }, |
72 | type: Qt::QueuedConnection); |
73 | m_connectionThreadObject->moveToThread(thread: m_connectionThread); |
74 | m_connectionThread->start(); |
75 | |
76 | m_connectionThreadObject->initConnection(); |
77 | } |
78 | |
79 | void ShadowTest::setupRegistry(Registry *registry) |
80 | { |
81 | connect(sender: registry, signal: &Registry::compositorAnnounced, context: this, slot: [this, registry](quint32 name, quint32 version) { |
82 | m_compositor = registry->createCompositor(name, version, parent: this); |
83 | }); |
84 | connect(sender: registry, signal: &Registry::shellAnnounced, context: this, slot: [this, registry](quint32 name, quint32 version) { |
85 | m_shell = registry->createShell(name, version, parent: this); |
86 | }); |
87 | connect(sender: registry, signal: &Registry::shmAnnounced, context: this, slot: [this, registry](quint32 name, quint32 version) { |
88 | m_shm = registry->createShmPool(name, version, parent: this); |
89 | }); |
90 | connect(sender: registry, signal: &Registry::shadowAnnounced, context: this, slot: [this, registry](quint32 name, quint32 version) { |
91 | m_shadowManager = registry->createShadowManager(name, version, parent: this); |
92 | m_shadowManager->setEventQueue(m_eventQueue); |
93 | }); |
94 | connect(sender: registry, signal: &Registry::interfacesAnnounced, context: this, slot: [this] { |
95 | Q_ASSERT(m_compositor); |
96 | Q_ASSERT(m_shell); |
97 | Q_ASSERT(m_shm); |
98 | m_surface = m_compositor->createSurface(parent: this); |
99 | Q_ASSERT(m_surface); |
100 | setupShadow(); |
101 | m_shellSurface = m_shell->createSurface(surface: m_surface, parent: this); |
102 | Q_ASSERT(m_shellSurface); |
103 | m_shellSurface->setToplevel(); |
104 | connect(sender: m_shellSurface, signal: &ShellSurface::sizeChanged, context: this, slot: &ShadowTest::render); |
105 | render(); |
106 | }); |
107 | registry->setEventQueue(m_eventQueue); |
108 | registry->create(connection: m_connectionThreadObject); |
109 | registry->setup(); |
110 | } |
111 | |
112 | void ShadowTest::setupShadow() |
113 | { |
114 | Q_ASSERT(m_shadowManager); |
115 | Shadow *shadow = m_shadowManager->createShadow(surface: m_surface, parent: this); |
116 | Q_ASSERT(shadow); |
117 | |
118 | auto addElement = [this](const QColor color) { |
119 | const QSize size = QSize(10, 10); |
120 | auto buffer = m_shm->getBuffer(size, stride: size.width() * 4).toStrongRef(); |
121 | buffer->setUsed(true); |
122 | QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); |
123 | image.fill(color); |
124 | return buffer; |
125 | }; |
126 | shadow->attachTopLeft(buffer: addElement(Qt::red)); |
127 | shadow->attachTop(buffer: addElement(Qt::darkRed)); |
128 | shadow->attachTopRight(buffer: addElement(Qt::green)); |
129 | shadow->attachRight(buffer: addElement(Qt::darkGreen)); |
130 | shadow->attachBottomRight(buffer: addElement(Qt::darkBlue)); |
131 | shadow->attachBottom(buffer: addElement(Qt::cyan)); |
132 | shadow->attachBottomLeft(buffer: addElement(Qt::darkCyan)); |
133 | shadow->attachLeft(buffer: addElement(Qt::magenta)); |
134 | shadow->setOffsets(QMarginsF(5, 5, 5, 5)); |
135 | shadow->commit(); |
136 | } |
137 | |
138 | void ShadowTest::render() |
139 | { |
140 | const QSize &size = m_shellSurface->size().isValid() ? m_shellSurface->size() : QSize(300, 200); |
141 | auto buffer = m_shm->getBuffer(size, stride: size.width() * 4).toStrongRef(); |
142 | buffer->setUsed(true); |
143 | QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied); |
144 | image.fill(color: QColor(255, 255, 255, 128)); |
145 | |
146 | m_surface->attachBuffer(buffer: *buffer); |
147 | m_surface->damage(rect: QRect(QPoint(0, 0), size)); |
148 | m_surface->commit(flag: Surface::CommitFlag::None); |
149 | buffer->setUsed(false); |
150 | } |
151 | |
152 | int main(int argc, char **argv) |
153 | { |
154 | QCoreApplication app(argc, argv); |
155 | ShadowTest client; |
156 | client.init(); |
157 | |
158 | return app.exec(); |
159 | } |
160 | |
161 | #include "shadowtest.moc" |
162 | |