6 #include "remote_access_interface.h"
10 #include "output_interface.h"
11 #include "remote_access_interface_p.h"
12 #include "resource_p.h"
14 #include <wayland-remote-access-server-protocol.h>
17 #include <QMutableHashIterator>
25 class BufferHandle::Private
38 BufferHandle::BufferHandle()
43 BufferHandle::~BufferHandle()
47 void BufferHandle::setFd(qint32 fd)
52 qint32 BufferHandle::fd()
const
57 void BufferHandle::setSize(quint32 width, quint32 height)
63 quint32 BufferHandle::width()
const
68 quint32 BufferHandle::height()
const
73 void BufferHandle::setStride(quint32 stride)
78 quint32 BufferHandle::stride()
const
83 void BufferHandle::setFormat(quint32 format)
88 quint32 BufferHandle::format()
const
98 const BufferHandle *buf;
102 class RemoteAccessManagerInterface::Private :
public Global::Private
105 Private(RemoteAccessManagerInterface *q, Display *d);
113 void sendBufferReady(
const OutputInterface *output,
const BufferHandle *buf);
118 void release(wl_resource *resource);
129 static void unbind(wl_resource *resource);
130 static Private *cast(wl_resource *r)
132 return reinterpret_cast<Private *
>(wl_resource_get_user_data(r));
134 static void getBufferCallback(wl_client *client, wl_resource *resource, uint32_t buffer, int32_t internalBufId);
135 static void releaseCallback(wl_client *client, wl_resource *resource);
136 void bind(wl_client *client, uint32_t version, uint32_t
id)
override;
143 bool unref(BufferHolder &buf);
146 static const struct org_kde_kwin_remote_access_manager_interface s_interface;
147 static const quint32 s_version;
149 RemoteAccessManagerInterface *q;
158 const quint32 RemoteAccessManagerInterface::Private::s_version = 1;
160 RemoteAccessManagerInterface::Private::Private(RemoteAccessManagerInterface *q, Display *d)
161 : Global::Private(d, &org_kde_kwin_remote_access_manager_interface, s_version)
166 void RemoteAccessManagerInterface::Private::bind(wl_client *client, uint32_t version, uint32_t
id)
169 auto c = display->getConnection(client);
170 wl_resource *resource = c->createResource(&org_kde_kwin_remote_access_manager_interface, qMin(version, s_version),
id);
172 wl_client_post_no_memory(client);
175 wl_resource_set_implementation(resource, &s_interface,
this, unbind);
178 clientResources << resource;
181 void RemoteAccessManagerInterface::Private::sendBufferReady(
const OutputInterface *output,
const BufferHandle *buf)
183 BufferHolder holder{buf, 0};
185 qCDebug(KWAYLAND_SERVER) <<
"Server buffer sent: fd" << buf->fd();
186 for (
auto res : clientResources) {
187 auto client = wl_resource_get_client(res);
188 auto boundScreens = output->clientResources(display->getConnection(client));
191 if (boundScreens.isEmpty()) {
196 org_kde_kwin_remote_access_manager_send_buffer_ready(res, buf->fd(), boundScreens[0]);
199 if (holder.counter == 0) {
201 Q_EMIT q->bufferReleased(buf);
205 sentBuffers[buf->fd()] = holder;
209 const struct org_kde_kwin_remote_access_manager_interface RemoteAccessManagerInterface::Private::s_interface = {getBufferCallback, releaseCallback};
212 void RemoteAccessManagerInterface::Private::getBufferCallback(wl_client *client, wl_resource *resource, uint32_t buffer, int32_t internalBufId)
214 Private *p = cast(resource);
217 if (Q_UNLIKELY(!p->sentBuffers.contains(internalBufId))) {
218 wl_resource_post_no_memory(resource);
222 BufferHolder &bh = p->sentBuffers[internalBufId];
223 auto rbuf =
new RemoteBufferInterface(p->q, resource, bh.buf);
224 rbuf->create(p->display->getConnection(client), wl_resource_get_version(resource), buffer);
225 if (!rbuf->resource()) {
226 wl_resource_post_no_memory(resource);
231 QObject::connect(rbuf, &Resource::aboutToBeUnbound, p->q, [p, rbuf, resource, &bh] {
232 if (!p->clientResources.contains(resource)) {
237 qCDebug(KWAYLAND_SERVER) <<
"Remote buffer returned, client" << wl_resource_get_id(resource) <<
", id" << rbuf->id() <<
", fd" << bh.buf->fd();
239 p->sentBuffers.remove(bh.buf->fd());
247 void RemoteAccessManagerInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
253 bool RemoteAccessManagerInterface::Private::unref(BufferHolder &bh)
258 qCDebug(KWAYLAND_SERVER) <<
"Buffer released, fd" << bh.buf->fd();
259 Q_EMIT q->bufferReleased(bh.buf);
266 void RemoteAccessManagerInterface::Private::unbind(wl_resource *resource)
269 Private *p = cast(resource);
270 p->release(resource);
277 while (itr.hasNext()) {
278 BufferHolder &bh = itr.next().value();
284 clientResources.removeAll(resource);
287 RemoteAccessManagerInterface::Private::~Private()
290 auto c = clientResources;
296 RemoteAccessManagerInterface::RemoteAccessManagerInterface(Display *display,
QObject *parent)
297 : Global(new Private(this, display), parent)
301 void RemoteAccessManagerInterface::sendBufferReady(
const OutputInterface *output,
const BufferHandle *buf)
303 Private *priv =
reinterpret_cast<Private *
>(d.data());
304 priv->sendBufferReady(output, buf);
307 bool RemoteAccessManagerInterface::isBound()
const
309 Private *priv =
reinterpret_cast<Private *
>(d.data());
310 return !priv->clientResources.isEmpty();
313 class RemoteBufferInterface::Private :
public Resource::Private
316 Private(RemoteAccessManagerInterface *ram, RemoteBufferInterface *q, wl_resource *pResource,
const BufferHandle *buf);
322 static const struct org_kde_kwin_remote_buffer_interface s_interface;
324 const BufferHandle *wrapped;
328 const struct org_kde_kwin_remote_buffer_interface RemoteBufferInterface::Private::s_interface = {resourceDestroyedCallback};
331 RemoteBufferInterface::Private::Private(RemoteAccessManagerInterface *ram, RemoteBufferInterface *q, wl_resource *pResource,
const BufferHandle *buf)
332 :
Resource::Private(q, ram, pResource, &org_kde_kwin_remote_buffer_interface, &s_interface)
337 RemoteBufferInterface::Private::~Private()
341 void RemoteBufferInterface::Private::passFd()
343 org_kde_kwin_remote_buffer_send_gbm_handle(resource, wrapped->fd(), wrapped->width(), wrapped->height(), wrapped->stride(), wrapped->format());
346 RemoteBufferInterface::RemoteBufferInterface(RemoteAccessManagerInterface *ram, wl_resource *pResource,
const BufferHandle *buf)
347 :
Resource(new Private(ram, this, pResource, buf), ram)
351 RemoteBufferInterface::Private *RemoteBufferInterface::d_func()
const
353 return reinterpret_cast<Private *
>(d.data());
356 void RemoteBufferInterface::passFd()