KWin
Loading...
Searching...
No Matches
touchclienttest.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2014, 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 "touchclienttest.h"
7// KWin::Wayland
8#include <KWayland/Client/buffer.h>
9#include <KWayland/Client/compositor.h>
10#include <KWayland/Client/connection_thread.h>
11#include <KWayland/Client/event_queue.h>
12#include <KWayland/Client/keyboard.h>
13#include <KWayland/Client/output.h>
14#include <KWayland/Client/pointer.h>
15#include <KWayland/Client/registry.h>
16#include <KWayland/Client/seat.h>
17#include <KWayland/Client/shell.h>
18#include <KWayland/Client/shm_pool.h>
19#include <KWayland/Client/surface.h>
20#include <KWayland/Client/touch.h>
21// Qt
22#include <QAbstractEventDispatcher>
23#include <QCoreApplication>
24#include <QDebug>
25#include <QImage>
26#include <QPainter>
27#include <QThread>
28#include <QTimer>
29
30#include <linux/input.h>
31
32using namespace KWayland::Client;
33
34static Qt::GlobalColor s_colors[] = {Qt::white, Qt::red, Qt::green, Qt::blue, Qt::black};
35static int s_colorIndex = 0;
36
38 : QObject(parent)
39 , m_connectionThread(new QThread(this))
40 , m_connectionThreadObject(new ConnectionThread(nullptr))
41 , m_eventQueue(nullptr)
42 , m_compositor(nullptr)
43 , m_output(nullptr)
44 , m_surface(nullptr)
45 , m_shm(nullptr)
46 , m_timer(new QTimer(this))
47{
48 init();
49}
50
52{
53 m_connectionThread->quit();
54 m_connectionThread->wait();
55 m_connectionThreadObject->deleteLater();
56}
57
58void WaylandClientTest::init()
59{
60 connect(
61 m_connectionThreadObject,
62 &ConnectionThread::connected,
63 this,
64 [this]() {
65 // create the event queue for the main gui thread
66 m_eventQueue = new EventQueue(this);
67 m_eventQueue->setup(m_connectionThreadObject);
68 // setup registry
69 Registry *registry = new Registry(this);
70 setupRegistry(registry);
71 },
72 Qt::QueuedConnection);
73
74 m_connectionThreadObject->moveToThread(m_connectionThread);
75 m_connectionThread->start();
76
77 m_connectionThreadObject->initConnection();
78
79 connect(m_timer, &QTimer::timeout, this, [this]() {
80 s_colorIndex = (s_colorIndex + 1) % 5;
81 render();
82 });
83 m_timer->setInterval(1000);
84 m_timer->start();
85}
86
87void WaylandClientTest::setupRegistry(Registry *registry)
88{
89 connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name) {
90 m_compositor = registry->createCompositor(name, 1, this);
91 m_surface = m_compositor->createSurface(this);
92 });
93 connect(registry, &Registry::shellAnnounced, this, [this, registry](quint32 name) {
94 Shell *shell = registry->createShell(name, 1, this);
95 ShellSurface *shellSurface = shell->createSurface(m_surface, m_surface);
96 shellSurface->setToplevel();
97 render(QSize(400, 200));
98 });
99 connect(registry, &Registry::outputAnnounced, this, [this, registry](quint32 name) {
100 if (m_output) {
101 return;
102 }
103 m_output = registry->createOutput(name, 2, this);
104 });
105 connect(registry, &Registry::shmAnnounced, this, [this, registry](quint32 name) {
106 m_shm = registry->createShmPool(name, 1, this);
107 });
108 connect(registry, &Registry::seatAnnounced, this, [this, registry](quint32 name) {
109 Seat *s = registry->createSeat(name, 2, this);
110 connect(s, &Seat::hasKeyboardChanged, this, [this, s](bool has) {
111 if (!has) {
112 return;
113 }
114 Keyboard *k = s->createKeyboard(this);
115 connect(k, &Keyboard::keyChanged, this, [](quint32 key, Keyboard::KeyState state) {
116 if (key == KEY_Q && state == Keyboard::KeyState::Released) {
117 QCoreApplication::instance()->quit();
118 }
119 });
120 });
121 connect(s, &Seat::hasPointerChanged, this, [this, s](bool has) {
122 if (!has) {
123 return;
124 }
125 Pointer *p = s->createPointer(this);
126 connect(p, &Pointer::buttonStateChanged, this, [this](quint32 serial, quint32 time, quint32 button, Pointer::ButtonState state) {
127 if (state == Pointer::ButtonState::Released) {
128 if (button == BTN_LEFT) {
129 if (m_timer->isActive()) {
130 m_timer->stop();
131 } else {
132 m_timer->start();
133 }
134 }
135 if (button == BTN_RIGHT) {
136 QCoreApplication::instance()->quit();
137 }
138 }
139 });
140 });
141 connect(s, &Seat::hasTouchChanged, this, [this, s](bool has) {
142 if (!has) {
143 return;
144 }
145 Touch *t = s->createTouch(this);
146 connect(t, &Touch::sequenceStarted, this, [](KWayland::Client::TouchPoint *startPoint) {
147 qDebug() << "Touch sequence started at" << startPoint->position() << "with id" << startPoint->id();
148 });
149 connect(t, &Touch::sequenceCanceled, this, []() {
150 qDebug() << "Touch sequence canceled";
151 });
152 connect(t, &Touch::sequenceEnded, this, []() {
153 qDebug() << "Touch sequence finished";
154 });
155 connect(t, &Touch::frameEnded, this, []() {
156 qDebug() << "End of touch contact point list";
157 });
158 connect(t, &Touch::pointAdded, this, [](KWayland::Client::TouchPoint *point) {
159 qDebug() << "Touch point added at" << point->position() << "with id" << point->id();
160 });
161 connect(t, &Touch::pointRemoved, this, [](KWayland::Client::TouchPoint *point) {
162 qDebug() << "Touch point " << point->id() << " removed at" << point->position();
163 });
164 connect(t, &Touch::pointMoved, this, [](KWayland::Client::TouchPoint *point) {
165 qDebug() << "Touch point " << point->id() << " moved to" << point->position();
166 });
167 });
168 });
169 registry->create(m_connectionThreadObject->display());
170 registry->setEventQueue(m_eventQueue);
171 registry->setup();
172}
173
174void WaylandClientTest::render(const QSize &size)
175{
176 m_currentSize = size;
177 render();
178}
179
180void WaylandClientTest::render()
181{
182 if (!m_shm || !m_surface || !m_surface->isValid() || !m_currentSize.isValid()) {
183 return;
184 }
185 auto buffer = m_shm->getBuffer(m_currentSize, m_currentSize.width() * 4).toStrongRef();
186 buffer->setUsed(true);
187 QImage image(buffer->address(), m_currentSize.width(), m_currentSize.height(), QImage::Format_ARGB32_Premultiplied);
188 image.fill(s_colors[s_colorIndex]);
189
190 m_surface->attachBuffer(*buffer);
191 m_surface->damage(QRect(QPoint(0, 0), m_currentSize));
192 m_surface->commit(Surface::CommitFlag::None);
193 buffer->setUsed(false);
194}
195
196int main(int argc, char **argv)
197{
198 QCoreApplication app(argc, argv);
199
200 new WaylandClientTest(&app);
201
202 return app.exec();
203}
204
205#include "moc_touchclienttest.cpp"
WaylandClientTest(QObject *parent=nullptr)
KWayland::Client::Registry * registry