1 /*
2     SPDX-FileCopyrightText: 2016 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/compositor.h"
7 #include "../src/client/connection_thread.h"
8 #include "../src/client/event_queue.h"
9 #include "../src/client/plasmashell.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 <QCommandLineParser>
16 #include <QGuiApplication>
17 #include <QImage>
18 #include <QThread>
19 
20 using namespace KWayland::Client;
21 
22 class PlasmaSurfaceTest : public QObject
23 {
24     Q_OBJECT
25 public:
26     explicit PlasmaSurfaceTest(QObject *parent = nullptr);
27     ~PlasmaSurfaceTest() override;
28 
29     void init();
30 
setRole(PlasmaShellSurface::Role role)31     void setRole(PlasmaShellSurface::Role role)
32     {
33         m_role = role;
34     }
setSkipTaskbar(bool set)35     void setSkipTaskbar(bool set)
36     {
37         m_skipTaskbar = set;
38     }
39 
setSkipSwitcher(bool set)40     void setSkipSwitcher(bool set)
41     {
42         m_skipSwitcher = set;
43     }
44 
45 private:
46     void setupRegistry(Registry *registry);
47     void render();
48     QThread *m_connectionThread;
49     ConnectionThread *m_connectionThreadObject;
50     EventQueue *m_eventQueue = nullptr;
51     Compositor *m_compositor = nullptr;
52     Shell *m_shell = nullptr;
53     ShellSurface *m_shellSurface = nullptr;
54     ShmPool *m_shm = nullptr;
55     Surface *m_surface = nullptr;
56     PlasmaShell *m_plasmaShell = nullptr;
57     PlasmaShellSurface *m_plasmaShellSurface = nullptr;
58     PlasmaShellSurface::Role m_role = PlasmaShellSurface::Role::Normal;
59     bool m_skipTaskbar = false;
60     bool m_skipSwitcher = false;
61 };
62 
PlasmaSurfaceTest(QObject * parent)63 PlasmaSurfaceTest::PlasmaSurfaceTest(QObject *parent)
64     : QObject(parent)
65     , m_connectionThread(new QThread(this))
66     , m_connectionThreadObject(new ConnectionThread())
67 {
68 }
69 
~PlasmaSurfaceTest()70 PlasmaSurfaceTest::~PlasmaSurfaceTest()
71 {
72     m_connectionThread->quit();
73     m_connectionThread->wait();
74     m_connectionThreadObject->deleteLater();
75 }
76 
init()77 void PlasmaSurfaceTest::init()
78 {
79     connect(
80         m_connectionThreadObject,
81         &ConnectionThread::connected,
82         this,
83         [this] {
84             m_eventQueue = new EventQueue(this);
85             m_eventQueue->setup(m_connectionThreadObject);
86 
87             Registry *registry = new Registry(this);
88             setupRegistry(registry);
89         },
90         Qt::QueuedConnection);
91     m_connectionThreadObject->moveToThread(m_connectionThread);
92     m_connectionThread->start();
93 
94     m_connectionThreadObject->initConnection();
95 }
96 
setupRegistry(Registry * registry)97 void PlasmaSurfaceTest::setupRegistry(Registry *registry)
98 {
99     connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name, quint32 version) {
100         m_compositor = registry->createCompositor(name, version, this);
101     });
102     connect(registry, &Registry::shellAnnounced, this, [this, registry](quint32 name, quint32 version) {
103         m_shell = registry->createShell(name, version, this);
104     });
105     connect(registry, &Registry::shmAnnounced, this, [this, registry](quint32 name, quint32 version) {
106         m_shm = registry->createShmPool(name, version, this);
107     });
108     connect(registry, &Registry::plasmaShellAnnounced, this, [this, registry](quint32 name, quint32 version) {
109         m_plasmaShell = registry->createPlasmaShell(name, version, this);
110         m_plasmaShell->setEventQueue(m_eventQueue);
111     });
112     connect(registry, &Registry::interfacesAnnounced, this, [this] {
113         Q_ASSERT(m_compositor);
114         Q_ASSERT(m_shell);
115         Q_ASSERT(m_shm);
116         Q_ASSERT(m_plasmaShell);
117         m_surface = m_compositor->createSurface(this);
118         Q_ASSERT(m_surface);
119         m_shellSurface = m_shell->createSurface(m_surface, this);
120         Q_ASSERT(m_shellSurface);
121         m_shellSurface->setToplevel();
122         connect(m_shellSurface, &ShellSurface::sizeChanged, this, &PlasmaSurfaceTest::render);
123         m_plasmaShellSurface = m_plasmaShell->createSurface(m_surface, this);
124         Q_ASSERT(m_plasmaShellSurface);
125         m_plasmaShellSurface->setSkipTaskbar(m_skipTaskbar);
126         m_plasmaShellSurface->setSkipSwitcher(m_skipSwitcher);
127         m_plasmaShellSurface->setRole(m_role);
128         render();
129     });
130     registry->setEventQueue(m_eventQueue);
131     registry->create(m_connectionThreadObject);
132     registry->setup();
133 }
134 
render()135 void PlasmaSurfaceTest::render()
136 {
137     const QSize &size = m_shellSurface->size().isValid() ? m_shellSurface->size() : QSize(300, 200);
138     auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef();
139     buffer->setUsed(true);
140     QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied);
141     image.fill(QColor(255, 255, 255, 128));
142 
143     m_surface->attachBuffer(*buffer);
144     m_surface->damage(QRect(QPoint(0, 0), size));
145     m_surface->commit(Surface::CommitFlag::None);
146     buffer->setUsed(false);
147 }
148 
main(int argc,char ** argv)149 int main(int argc, char **argv)
150 {
151     QCoreApplication app(argc, argv);
152     QCommandLineParser parser;
153     parser.addHelpOption();
154     QCommandLineOption notificationOption(QStringLiteral("notification"));
155     parser.addOption(notificationOption);
156     QCommandLineOption criticalNotificationOption(QStringLiteral("criticalNotification"));
157     parser.addOption(criticalNotificationOption);
158     QCommandLineOption panelOption(QStringLiteral("panel"));
159     parser.addOption(panelOption);
160     QCommandLineOption desktopOption(QStringLiteral("desktop"));
161     parser.addOption(desktopOption);
162     QCommandLineOption osdOption(QStringLiteral("osd"));
163     parser.addOption(osdOption);
164     QCommandLineOption tooltipOption(QStringLiteral("tooltip"));
165     parser.addOption(tooltipOption);
166     QCommandLineOption skipTaskbarOption(QStringLiteral("skipTaskbar"));
167     parser.addOption(skipTaskbarOption);
168     parser.process(app);
169     QCommandLineOption skipSwitcherOption(QStringLiteral("skipSwitcher"));
170     parser.addOption(skipSwitcherOption);
171     parser.process(app);
172 
173     PlasmaSurfaceTest client;
174 
175     if (parser.isSet(notificationOption)) {
176         client.setRole(PlasmaShellSurface::Role::Notification);
177     } else if (parser.isSet(criticalNotificationOption)) {
178         client.setRole(PlasmaShellSurface::Role::CriticalNotification);
179     } else if (parser.isSet(panelOption)) {
180         client.setRole(PlasmaShellSurface::Role::Panel);
181     } else if (parser.isSet(desktopOption)) {
182         client.setRole(PlasmaShellSurface::Role::Desktop);
183     } else if (parser.isSet(osdOption)) {
184         client.setRole(PlasmaShellSurface::Role::OnScreenDisplay);
185     } else if (parser.isSet(tooltipOption)) {
186         client.setRole(PlasmaShellSurface::Role::ToolTip);
187     }
188     client.setSkipTaskbar(parser.isSet(skipTaskbarOption));
189     client.setSkipSwitcher(parser.isSet(skipSwitcherOption));
190 
191     client.init();
192 
193     return app.exec();
194 }
195 
196 #include "plasmasurfacetest.moc"
197