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>
22#include <QAbstractEventDispatcher>
23#include <QCoreApplication>
30#include <linux/input.h>
34static Qt::GlobalColor s_colors[] = {Qt::white, Qt::red, Qt::green, Qt::blue, Qt::black};
35static int s_colorIndex = 0;
39 , m_connectionThread(new QThread(this))
40 , m_connectionThreadObject(new ConnectionThread(nullptr))
41 , m_eventQueue(nullptr)
42 , m_compositor(nullptr)
46 , m_timer(new QTimer(this))
53 m_connectionThread->quit();
54 m_connectionThread->wait();
55 m_connectionThreadObject->deleteLater();
58void WaylandClientTest::init()
61 m_connectionThreadObject,
62 &ConnectionThread::connected,
66 m_eventQueue =
new EventQueue(
this);
67 m_eventQueue->setup(m_connectionThreadObject);
69 Registry *registry =
new Registry(
this);
70 setupRegistry(registry);
72 Qt::QueuedConnection);
74 m_connectionThreadObject->moveToThread(m_connectionThread);
75 m_connectionThread->start();
77 m_connectionThreadObject->initConnection();
79 connect(m_timer, &QTimer::timeout,
this, [
this]() {
80 s_colorIndex = (s_colorIndex + 1) % 5;
83 m_timer->setInterval(1000);
87void WaylandClientTest::setupRegistry(Registry *registry)
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);
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));
99 connect(registry, &Registry::outputAnnounced,
this, [
this, registry](quint32 name) {
103 m_output =
registry->createOutput(name, 2,
this);
105 connect(registry, &Registry::shmAnnounced,
this, [
this, registry](quint32 name) {
106 m_shm =
registry->createShmPool(name, 1,
this);
108 connect(registry, &Registry::seatAnnounced,
this, [
this, registry](quint32 name) {
110 connect(s, &Seat::hasKeyboardChanged,
this, [
this, s](
bool has) {
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();
121 connect(s, &Seat::hasPointerChanged,
this, [
this, s](
bool has) {
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()) {
135 if (button == BTN_RIGHT) {
136 QCoreApplication::instance()->quit();
141 connect(s, &Seat::hasTouchChanged,
this, [
this, s](
bool has) {
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();
149 connect(t, &Touch::sequenceCanceled,
this, []() {
150 qDebug() <<
"Touch sequence canceled";
152 connect(t, &Touch::sequenceEnded,
this, []() {
153 qDebug() <<
"Touch sequence finished";
155 connect(t, &Touch::frameEnded,
this, []() {
156 qDebug() <<
"End of touch contact point list";
158 connect(t, &Touch::pointAdded,
this, [](KWayland::Client::TouchPoint *point) {
159 qDebug() <<
"Touch point added at" << point->position() <<
"with id" << point->id();
161 connect(t, &Touch::pointRemoved,
this, [](KWayland::Client::TouchPoint *point) {
162 qDebug() <<
"Touch point " << point->id() <<
" removed at" << point->position();
164 connect(t, &Touch::pointMoved,
this, [](KWayland::Client::TouchPoint *point) {
165 qDebug() <<
"Touch point " << point->id() <<
" moved to" << point->position();
169 registry->create(m_connectionThreadObject->display());
170 registry->setEventQueue(m_eventQueue);
174void WaylandClientTest::render(
const QSize &size)
176 m_currentSize = size;
180void WaylandClientTest::render()
182 if (!m_shm || !m_surface || !m_surface->isValid() || !m_currentSize.isValid()) {
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]);
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);
198 QCoreApplication app(argc, argv);
205#include "moc_touchclienttest.cpp"
virtual ~WaylandClientTest()
WaylandClientTest(QObject *parent=nullptr)
KWayland::Client::Registry * registry