1 /********************************************************************
2 Copyright 2016  Martin Gräßlin <mgraesslin@kde.org>
3 
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), which shall
10 act as a proxy defined in Section 6 of version 3 of the license.
11 
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library.  If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
20 #include "../src/client/compositor.h"
21 #include "../src/client/connection_thread.h"
22 #include "../src/client/event_queue.h"
23 #include "../src/client/plasmashell.h"
24 #include "../src/client/registry.h"
25 #include "../src/client/shell.h"
26 #include "../src/client/shm_pool.h"
27 #include "../src/client/surface.h"
28 // Qt
29 #include <QCommandLineParser>
30 #include <QGuiApplication>
31 #include <QImage>
32 #include <QThread>
33 
34 using namespace Wrapland::Client;
35 
36 class PlasmaSurfaceTest : public QObject
37 {
38     Q_OBJECT
39 public:
40     explicit PlasmaSurfaceTest(QObject* parent = nullptr);
41     virtual ~PlasmaSurfaceTest();
42 
43     void init();
44 
setRole(PlasmaShellSurface::Role role)45     void setRole(PlasmaShellSurface::Role role)
46     {
47         m_role = role;
48     }
setSkipTaskbar(bool set)49     void setSkipTaskbar(bool set)
50     {
51         m_skipTaskbar = set;
52     }
53 
setSkipSwitcher(bool set)54     void setSkipSwitcher(bool set)
55     {
56         m_skipSwitcher = set;
57     }
58 
59 private:
60     void setupRegistry(Registry* registry);
61     void render();
62     QThread* m_connectionThread;
63     ConnectionThread* m_connectionThreadObject;
64     EventQueue* m_eventQueue = nullptr;
65     Compositor* m_compositor = nullptr;
66     Shell* m_shell = nullptr;
67     ShellSurface* m_shellSurface = nullptr;
68     ShmPool* m_shm = nullptr;
69     Surface* m_surface = nullptr;
70     PlasmaShell* m_plasmaShell = nullptr;
71     PlasmaShellSurface* m_plasmaShellSurface = nullptr;
72     PlasmaShellSurface::Role m_role = PlasmaShellSurface::Role::Normal;
73     bool m_skipTaskbar = false;
74     bool m_skipSwitcher = false;
75 };
76 
PlasmaSurfaceTest(QObject * parent)77 PlasmaSurfaceTest::PlasmaSurfaceTest(QObject* parent)
78     : QObject(parent)
79     , m_connectionThread(new QThread(this))
80     , m_connectionThreadObject(new ConnectionThread())
81 {
82 }
83 
~PlasmaSurfaceTest()84 PlasmaSurfaceTest::~PlasmaSurfaceTest()
85 {
86     m_connectionThread->quit();
87     m_connectionThread->wait();
88     m_connectionThreadObject->deleteLater();
89 }
90 
init()91 void PlasmaSurfaceTest::init()
92 {
93     connect(
94         m_connectionThreadObject,
95         &ConnectionThread::establishedChanged,
96         this,
97         [this](bool established) {
98             if (!established) {
99                 return;
100             }
101             m_eventQueue = new EventQueue(this);
102             m_eventQueue->setup(m_connectionThreadObject);
103 
104             Registry* registry = new Registry(this);
105             setupRegistry(registry);
106         },
107         Qt::QueuedConnection);
108     m_connectionThreadObject->moveToThread(m_connectionThread);
109     m_connectionThread->start();
110 
111     m_connectionThreadObject->establishConnection();
112 }
113 
setupRegistry(Registry * registry)114 void PlasmaSurfaceTest::setupRegistry(Registry* registry)
115 {
116     connect(registry,
117             &Registry::compositorAnnounced,
118             this,
119             [this, registry](quint32 name, quint32 version) {
120                 m_compositor = registry->createCompositor(name, version, this);
121             });
122     connect(
123         registry, &Registry::shellAnnounced, this, [this, registry](quint32 name, quint32 version) {
124             m_shell = registry->createShell(name, version, this);
125         });
126     connect(
127         registry, &Registry::shmAnnounced, this, [this, registry](quint32 name, quint32 version) {
128             m_shm = registry->createShmPool(name, version, this);
129         });
130     connect(registry,
131             &Registry::plasmaShellAnnounced,
132             this,
133             [this, registry](quint32 name, quint32 version) {
134                 m_plasmaShell = registry->createPlasmaShell(name, version, this);
135                 m_plasmaShell->setEventQueue(m_eventQueue);
136             });
137     connect(registry, &Registry::interfacesAnnounced, this, [this] {
138         Q_ASSERT(m_compositor);
139         Q_ASSERT(m_shell);
140         Q_ASSERT(m_shm);
141         Q_ASSERT(m_plasmaShell);
142         m_surface = m_compositor->createSurface(this);
143         Q_ASSERT(m_surface);
144         m_shellSurface = m_shell->createSurface(m_surface, this);
145         Q_ASSERT(m_shellSurface);
146         m_shellSurface->setToplevel();
147         connect(m_shellSurface, &ShellSurface::sizeChanged, this, &PlasmaSurfaceTest::render);
148         m_plasmaShellSurface = m_plasmaShell->createSurface(m_surface, this);
149         Q_ASSERT(m_plasmaShellSurface);
150         m_plasmaShellSurface->setSkipTaskbar(m_skipTaskbar);
151         m_plasmaShellSurface->setSkipSwitcher(m_skipSwitcher);
152         m_plasmaShellSurface->setRole(m_role);
153         render();
154     });
155     registry->setEventQueue(m_eventQueue);
156     registry->create(m_connectionThreadObject);
157     registry->setup();
158 }
159 
render()160 void PlasmaSurfaceTest::render()
161 {
162     const QSize& size = m_shellSurface->size().isValid() ? m_shellSurface->size() : QSize(300, 200);
163     auto buffer = m_shm->getBuffer(size, size.width() * 4).lock();
164     buffer->setUsed(true);
165     QImage image(
166         buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied);
167     image.fill(QColor(255, 255, 255, 128));
168 
169     m_surface->attachBuffer(*buffer);
170     m_surface->damage(QRect(QPoint(0, 0), size));
171     m_surface->commit(Surface::CommitFlag::None);
172     buffer->setUsed(false);
173 }
174 
main(int argc,char ** argv)175 int main(int argc, char** argv)
176 {
177     QCoreApplication app(argc, argv);
178     QCommandLineParser parser;
179     parser.addHelpOption();
180     QCommandLineOption notificationOption(QStringLiteral("notification"));
181     parser.addOption(notificationOption);
182     QCommandLineOption criticalNotificationOption(QStringLiteral("criticalNotification"));
183     parser.addOption(criticalNotificationOption);
184     QCommandLineOption panelOption(QStringLiteral("panel"));
185     parser.addOption(panelOption);
186     QCommandLineOption desktopOption(QStringLiteral("desktop"));
187     parser.addOption(desktopOption);
188     QCommandLineOption osdOption(QStringLiteral("osd"));
189     parser.addOption(osdOption);
190     QCommandLineOption tooltipOption(QStringLiteral("tooltip"));
191     parser.addOption(tooltipOption);
192     QCommandLineOption skipTaskbarOption(QStringLiteral("skipTaskbar"));
193     parser.addOption(skipTaskbarOption);
194     parser.process(app);
195     QCommandLineOption skipSwitcherOption(QStringLiteral("skipSwitcher"));
196     parser.addOption(skipSwitcherOption);
197     parser.process(app);
198 
199     PlasmaSurfaceTest client;
200 
201     if (parser.isSet(notificationOption)) {
202         client.setRole(PlasmaShellSurface::Role::Notification);
203     } else if (parser.isSet(criticalNotificationOption)) {
204         client.setRole(PlasmaShellSurface::Role::CriticalNotification);
205     } else if (parser.isSet(panelOption)) {
206         client.setRole(PlasmaShellSurface::Role::Panel);
207     } else if (parser.isSet(desktopOption)) {
208         client.setRole(PlasmaShellSurface::Role::Desktop);
209     } else if (parser.isSet(osdOption)) {
210         client.setRole(PlasmaShellSurface::Role::OnScreenDisplay);
211     } else if (parser.isSet(tooltipOption)) {
212         client.setRole(PlasmaShellSurface::Role::ToolTip);
213     }
214     client.setSkipTaskbar(parser.isSet(skipTaskbarOption));
215     client.setSkipSwitcher(parser.isSet(skipSwitcherOption));
216 
217     client.init();
218 
219     return app.exec();
220 }
221 
222 #include "plasmasurfacetest.moc"
223