KWin
Loading...
Searching...
No Matches
pasteclient.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/dataoffer.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 <QMimeType>
25#include <QThreadPool>
26// system
27#include <unistd.h>
28
29using namespace KWayland::Client;
30
31class PasteClient : public QObject
32{
33 Q_OBJECT
34public:
35 explicit PasteClient(QObject *parent = nullptr);
36 virtual ~PasteClient();
37
38 void init();
39
40private:
41 void setupRegistry(Registry *registry);
42 void render();
43 QThread *m_connectionThread;
44 ConnectionThread *m_connectionThreadObject;
45 EventQueue *m_eventQueue = nullptr;
46 Compositor *m_compositor = nullptr;
47 DataDeviceManager *m_dataDeviceManager = nullptr;
48 DataDevice *m_dataDevice = nullptr;
49 Seat *m_seat = nullptr;
50 Shell *m_shell = nullptr;
51 ShellSurface *m_shellSurface = nullptr;
52 ShmPool *m_shm = nullptr;
53 Surface *m_surface = nullptr;
54};
55
57 : QObject(parent)
58 , m_connectionThread(new QThread(this))
59 , m_connectionThreadObject(new ConnectionThread())
60{
61}
62
64{
65 m_connectionThread->quit();
66 m_connectionThread->wait();
67 m_connectionThreadObject->deleteLater();
68}
69
71{
72 connect(
73 m_connectionThreadObject,
74 &ConnectionThread::connected,
75 this,
76 [this] {
77 m_eventQueue = new EventQueue(this);
78 m_eventQueue->setup(m_connectionThreadObject);
79
80 Registry *registry = new Registry(this);
81 setupRegistry(registry);
82 },
83 Qt::QueuedConnection);
84 m_connectionThreadObject->moveToThread(m_connectionThread);
85 m_connectionThread->start();
86
87 m_connectionThreadObject->initConnection();
88}
89
90void PasteClient::setupRegistry(Registry *registry)
91{
92 connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name, quint32 version) {
93 m_compositor = registry->createCompositor(name, version, this);
94 });
95 connect(registry, &Registry::shellAnnounced, this, [this, registry](quint32 name, quint32 version) {
96 m_shell = registry->createShell(name, version, this);
97 });
98 connect(registry, &Registry::shmAnnounced, this, [this, registry](quint32 name, quint32 version) {
99 m_shm = registry->createShmPool(name, version, this);
100 });
101 connect(registry, &Registry::seatAnnounced, this, [this, registry](quint32 name, quint32 version) {
102 m_seat = registry->createSeat(name, version, this);
103 });
104 connect(registry, &Registry::dataDeviceManagerAnnounced, this, [this, registry](quint32 name, quint32 version) {
105 m_dataDeviceManager = registry->createDataDeviceManager(name, version, this);
106 });
107 connect(registry, &Registry::interfacesAnnounced, this, [this] {
108 Q_ASSERT(m_compositor);
109 Q_ASSERT(m_dataDeviceManager);
110 Q_ASSERT(m_seat);
111 Q_ASSERT(m_shell);
112 Q_ASSERT(m_shm);
113 m_surface = m_compositor->createSurface(this);
114 Q_ASSERT(m_surface);
115 m_shellSurface = m_shell->createSurface(m_surface, this);
116 Q_ASSERT(m_shellSurface);
117 m_shellSurface->setFullscreen();
118 connect(m_shellSurface, &ShellSurface::sizeChanged, this, &PasteClient::render);
119
120 m_dataDevice = m_dataDeviceManager->getDataDevice(m_seat, this);
121 connect(m_dataDevice, &DataDevice::selectionOffered, this, [this] {
122 auto dataOffer = m_dataDevice->offeredSelection();
123 if (!dataOffer) {
124 return;
125 }
126 const auto &mimeTypes = dataOffer->offeredMimeTypes();
127 auto it = std::find_if(mimeTypes.constBegin(), mimeTypes.constEnd(), [](const QMimeType &type) {
128 return type.inherits(QStringLiteral("text/plain"));
129 });
130 if (it == mimeTypes.constEnd()) {
131 return;
132 }
133 int pipeFds[2];
134 if (pipe(pipeFds) != 0) {
135 return;
136 }
137 dataOffer->receive((*it).name(), pipeFds[1]);
138 close(pipeFds[1]);
139 QThreadPool::globalInstance()->start([pipeFds] {
140 QFile readPipe;
141 if (readPipe.open(pipeFds[0], QIODevice::ReadOnly)) {
142 qDebug() << "Pasted: " << readPipe.readLine();
143 }
144 close(pipeFds[0]);
145 QCoreApplication::quit();
146 });
147 });
148 });
149 registry->setEventQueue(m_eventQueue);
150 registry->create(m_connectionThreadObject);
151 registry->setup();
152}
153
154void PasteClient::render()
155{
156 const QSize &size = m_shellSurface->size();
157 auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef();
158 buffer->setUsed(true);
159 QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied);
160 image.fill(Qt::blue);
161
162 m_surface->attachBuffer(*buffer);
163 m_surface->damage(QRect(QPoint(0, 0), size));
164 m_surface->commit(Surface::CommitFlag::None);
165 buffer->setUsed(false);
166}
167
168int main(int argc, char **argv)
169{
170 QCoreApplication app(argc, argv);
171 PasteClient client;
172 client.init();
173
174 return app.exec();
175}
176
177#include "pasteclient.moc"
virtual ~PasteClient()
PasteClient(QObject *parent=nullptr)
KWayland::Client::Registry * registry
constexpr int version