Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwaylandclient.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6#include <QtCore/private/qobject_p.h>
7
8#include <QtWaylandCompositor/QWaylandCompositor>
9#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
10
11
12#include <wayland-server-core.h>
13#include <wayland-util.h>
14
15QT_BEGIN_NAMESPACE
16
17class QWaylandClientPrivate : public QObjectPrivate
18{
19public:
20 QWaylandClientPrivate(QWaylandCompositor *compositor, wl_client *_client)
21 : compositor(compositor)
22 , client(_client)
23 {
24 // Save client credentials
25 wl_client_get_credentials(client, &pid, &uid, &gid);
26 }
27
28 ~QWaylandClientPrivate() override
29 {
30 }
31
32 static void client_destroy_callback(wl_listener *listener, void *data)
33 {
34 Q_UNUSED(data);
35
36 QWaylandClient *client = reinterpret_cast<Listener *>(listener)->parent;
37 Q_ASSERT(client != nullptr);
38 delete client;
39 }
40
41 QWaylandCompositor *compositor = nullptr;
42 wl_client *client = nullptr;
43
44 uid_t uid;
45 gid_t gid;
46 pid_t pid;
47
48 struct Listener {
49 wl_listener listener;
50 QWaylandClient *parent = nullptr;
51 };
52 Listener listener;
53
54 QWaylandClient::TextInputProtocols mTextInputProtocols = QWaylandClient::NoProtocol;
55};
56
57/*!
58 * \qmltype WaylandClient
59 * \nativetype QWaylandClient
60 * \inqmlmodule QtWayland.Compositor
61 * \since 5.8
62 * \brief Represents a client connected to the WaylandCompositor.
63 *
64 * This type represents a client connected to the compositor using the Wayland protocol.
65 * It corresponds to the Wayland interface wl_client.
66 */
67
68/*!
69 * \class QWaylandClient
70 * \inmodule QtWaylandCompositor
71 * \since 5.8
72 * \brief The QWaylandClient class represents a client connected to the QWaylandCompositor.
73 *
74 * This class corresponds to a client connected to the compositor using the Wayland protocol.
75 * It corresponds to the Wayland interface wl_client.
76 */
77
78/*!
79 * Constructs a QWaylandClient for the \a compositor and the Wayland \a client.
80 */
81QWaylandClient::QWaylandClient(QWaylandCompositor *compositor, wl_client *client)
82 : QObject(*new QWaylandClientPrivate(compositor, client))
83{
84 Q_D(QWaylandClient);
85
86 // Destroy wrapper when the client goes away
87 d->listener.parent = this;
88 d->listener.listener.notify = QWaylandClientPrivate::client_destroy_callback;
89 wl_client_add_destroy_listener(client, &d->listener.listener);
90
91 QWaylandCompositorPrivate::get(compositor)->addClient(this);
92}
93
94/*!
95 * Destroys the QWaylandClient.
96 */
97QWaylandClient::~QWaylandClient()
98{
99 Q_D(QWaylandClient);
100
101 // Remove listener from signal
102 wl_list_remove(&d->listener.listener.link);
103
104 QWaylandCompositorPrivate::get(d->compositor)->removeClient(this);
105}
106
107/*!
108 * Returns the QWaylandClient corresponding to the Wayland client \a wlClient and \a compositor.
109 * If a QWaylandClient has not already been created for a client, it is
110 * created and returned.
111 */
112QWaylandClient *QWaylandClient::fromWlClient(QWaylandCompositor *compositor, wl_client *wlClient)
113{
114 if (!wlClient)
115 return nullptr;
116
117 QWaylandClient *client = nullptr;
118
119 wl_listener *l = wl_client_get_destroy_listener(wlClient,
120 QWaylandClientPrivate::client_destroy_callback);
121 if (l)
122 client = reinterpret_cast<QWaylandClientPrivate::Listener *>(
123 wl_container_of(l, (QWaylandClientPrivate::Listener *)nullptr, listener))->parent;
124
125 if (!client) {
126 // The original idea was to create QWaylandClient instances when
127 // a client bound wl_compositor, but it's legal for a client to
128 // bind several times resulting in multiple QWaylandClient
129 // instances for the same wl_client therefore we create it from
130 // here on demand
131 client = new QWaylandClient(compositor, wlClient);
132 }
133
134 return client;
135}
136
137/*!
138 * \qmlproperty WaylandCompositor QtWayland.Compositor::WaylandClient::compositor
139 *
140 * This property holds the compositor of this WaylandClient.
141 */
142
143/*!
144 * \property QWaylandClient::compositor
145 *
146 * This property holds the compositor of this QWaylandClient.
147 */
148QWaylandCompositor *QWaylandClient::compositor() const
149{
150 Q_D(const QWaylandClient);
151
152 return d->compositor;
153}
154
155/*!
156 * Returns the Wayland client of this QWaylandClient.
157 */
158wl_client *QWaylandClient::client() const
159{
160 Q_D(const QWaylandClient);
161
162 return d->client;
163}
164
165/*!
166 * \qmlproperty int QtWayland.Compositor::WaylandClient::userId
167 *
168 * This property holds the user id of this WaylandClient.
169 */
170
171/*!
172 * \property QWaylandClient::userId
173 * \readonly
174 *
175 * This property holds the user id of this QWaylandClient.
176 */
177qint64 QWaylandClient::userId() const
178{
179 Q_D(const QWaylandClient);
180
181 return d->uid;
182}
183
184/*!
185 * \qmlproperty int QtWayland.Compositor::WaylandClient::groupId
186 * \readonly
187 *
188 * This property holds the group id of this WaylandClient.
189 */
190
191/*!
192 * \property QWaylandClient::groupId
193 *
194 * This property holds the group id of this QWaylandClient.
195 */
196qint64 QWaylandClient::groupId() const
197{
198 Q_D(const QWaylandClient);
199
200 return d->gid;
201}
202
203/*!
204 * \qmlproperty int QtWayland.Compositor::WaylandClient::processId
205 * \readonly
206 *
207 * This property holds the process id of this WaylandClient.
208 */
209
210/*!
211 * \property QWaylandClient::processId
212 *
213 * This property holds the process id of this QWaylandClient.
214 */
215qint64 QWaylandClient::processId() const
216{
217 Q_D(const QWaylandClient);
218
219 return d->pid;
220}
221
222/*!
223 * \qmlmethod void QtWayland.Compositor::WaylandClient::kill(signal)
224 *
225 * Kills the client with the specified \a signal.
226 */
227
228/*!
229 * Kills the client with the specified \a signal.
230 */
231void QWaylandClient::kill(int signal)
232{
233 Q_D(QWaylandClient);
234
235 ::kill(d->pid, signal);
236}
237
238/*!
239 * \qmlmethod void QtWayland.Compositor::WaylandClient::close()
240 *
241 * Closes the client
242 */
243
244/*!
245 * Closes the client.
246 */
247void QWaylandClient::close()
248{
249 Q_D(QWaylandClient);
250 d->compositor->destroyClient(this);
251}
252
253QWaylandClient::TextInputProtocols QWaylandClient::textInputProtocols() const
254{
255 Q_D(const QWaylandClient);
256 return d->mTextInputProtocols;
257}
258
259void QWaylandClient::setTextInputProtocols(TextInputProtocols p)
260{
261 Q_D(QWaylandClient);
262 if (d->mTextInputProtocols != p)
263 d->mTextInputProtocols = p;
264}
265
266QT_END_NAMESPACE
267
268#include "moc_qwaylandclient.cpp"