KWin
Loading...
Searching...
No Matches
copyclient.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2014 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 "KWayland/Client/compositor.h"
7#include "KWayland/Client/connection_thread.h"
8#include "KWayland/Client/datadevice.h"
9#include "KWayland/Client/datadevicemanager.h"
10#include "KWayland/Client/datasource.h"
11#include "KWayland/Client/event_queue.h"
12#include "KWayland/Client/keyboard.h"
13#include "KWayland/Client/pointer.h"
14#include "KWayland/Client/registry.h"
15#include "KWayland/Client/seat.h"
16#include "KWayland/Client/shell.h"
17#include "KWayland/Client/shm_pool.h"
18#include "KWayland/Client/surface.h"
19// Qt
20#include <QCoreApplication>
21#include <QDebug>
22#include <QFile>
23#include <QImage>
24#include <QThread>
25
26using namespace KWayland::Client;
27
28class CopyClient : public QObject
29{
30 Q_OBJECT
31public:
32 explicit CopyClient(QObject *parent = nullptr);
33 virtual ~CopyClient();
34
35 void init();
36
37private:
38 void setupRegistry(Registry *registry);
39 void render();
40 void copy(const QString &mimeType, qint32 fd);
41 QThread *m_connectionThread;
42 ConnectionThread *m_connectionThreadObject;
43 EventQueue *m_eventQueue = nullptr;
44 Compositor *m_compositor = nullptr;
45 DataDeviceManager *m_dataDeviceManager = nullptr;
46 DataDevice *m_dataDevice = nullptr;
47 DataSource *m_copySource = nullptr;
48 Seat *m_seat = nullptr;
49 Shell *m_shell = nullptr;
50 ShellSurface *m_shellSurface = nullptr;
51 ShmPool *m_shm = nullptr;
52 Surface *m_surface = nullptr;
53};
54
55CopyClient::CopyClient(QObject *parent)
56 : QObject(parent)
57 , m_connectionThread(new QThread(this))
58 , m_connectionThreadObject(new ConnectionThread())
59{
60}
61
63{
64 m_connectionThread->quit();
65 m_connectionThread->wait();
66 m_connectionThreadObject->deleteLater();
67}
68
70{
71 connect(
72 m_connectionThreadObject,
73 &ConnectionThread::connected,
74 this,
75 [this] {
76 m_eventQueue = new EventQueue(this);
77 m_eventQueue->setup(m_connectionThreadObject);
78
79 Registry *registry = new Registry(this);
80 setupRegistry(registry);
81 },
82 Qt::QueuedConnection);
83 m_connectionThreadObject->moveToThread(m_connectionThread);
84 m_connectionThread->start();
85
86 m_connectionThreadObject->initConnection();
87}
88
89void CopyClient::setupRegistry(Registry *registry)
90{
91 connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name, quint32 version) {
92 m_compositor = registry->createCompositor(name, version, this);
93 });
94 connect(registry, &Registry::shellAnnounced, this, [this, registry](quint32 name, quint32 version) {
95 m_shell = registry->createShell(name, version, this);
96 });
97 connect(registry, &Registry::shmAnnounced, this, [this, registry](quint32 name, quint32 version) {
98 m_shm = registry->createShmPool(name, version, this);
99 });
100 connect(registry, &Registry::seatAnnounced, this, [this, registry](quint32 name, quint32 version) {
101 m_seat = registry->createSeat(name, version, this);
102 connect(m_seat, &Seat::hasPointerChanged, this, [this] {
103 auto p = m_seat->createPointer(this);
104 connect(p, &Pointer::entered, this, [this](quint32 serial) {
105 if (m_copySource) {
106 m_dataDevice->setSelection(serial, m_copySource);
107 }
108 });
109 });
110 });
111 connect(registry, &Registry::dataDeviceManagerAnnounced, this, [this, registry](quint32 name, quint32 version) {
112 m_dataDeviceManager = registry->createDataDeviceManager(name, version, this);
113 });
114 connect(registry, &Registry::interfacesAnnounced, this, [this] {
115 Q_ASSERT(m_compositor);
116 Q_ASSERT(m_dataDeviceManager);
117 Q_ASSERT(m_seat);
118 Q_ASSERT(m_shell);
119 Q_ASSERT(m_shm);
120 m_surface = m_compositor->createSurface(this);
121 Q_ASSERT(m_surface);
122 m_shellSurface = m_shell->createSurface(m_surface, this);
123 Q_ASSERT(m_shellSurface);
124 m_shellSurface->setFullscreen();
125 connect(m_shellSurface, &ShellSurface::sizeChanged, this, &CopyClient::render);
126
127 m_dataDevice = m_dataDeviceManager->getDataDevice(m_seat, this);
128 m_copySource = m_dataDeviceManager->createDataSource(this);
129 m_copySource->offer(QStringLiteral("text/plain"));
130 connect(m_copySource, &DataSource::sendDataRequested, this, &CopyClient::copy);
131 });
132 registry->setEventQueue(m_eventQueue);
133 registry->create(m_connectionThreadObject);
134 registry->setup();
135}
136
137void CopyClient::render()
138{
139 const QSize &size = m_shellSurface->size();
140 auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef();
141 buffer->setUsed(true);
142 QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied);
143 image.fill(Qt::green);
144
145 m_surface->attachBuffer(*buffer);
146 m_surface->damage(QRect(QPoint(0, 0), size));
147 m_surface->commit(Surface::CommitFlag::None);
148 buffer->setUsed(false);
149}
150
151void CopyClient::copy(const QString &mimeType, qint32 fd)
152{
153 qDebug() << "Requested to copy for mimeType" << mimeType;
154 QFile c;
155 if (c.open(fd, QFile::WriteOnly, QFile::AutoCloseHandle)) {
156 c.write(QByteArrayLiteral("foo"));
157 c.close();
158 qDebug() << "Copied foo";
159 }
160}
161
162int main(int argc, char **argv)
163{
164 QCoreApplication app(argc, argv);
165 CopyClient client;
166 client.init();
167
168 return app.exec();
169}
170
171#include "copyclient.moc"
virtual ~CopyClient()
CopyClient(QObject *parent=nullptr)
void init()
KWayland::Client::Registry * registry
constexpr int version