KWin
Loading...
Searching...
No Matches
wayland_backend.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
6 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9*/
10#include "wayland_backend.h"
11#include "input.h"
12#include "wayland_display.h"
13#include "wayland_egl_backend.h"
14#include "wayland_logging.h"
15#include "wayland_output.h"
17
18#include <KWayland/Client/keyboard.h>
19#include <KWayland/Client/pointer.h>
20#include <KWayland/Client/pointergestures.h>
21#include <KWayland/Client/relativepointer.h>
22#include <KWayland/Client/seat.h>
23#include <KWayland/Client/surface.h>
24#include <KWayland/Client/touch.h>
25
26#include <QAbstractEventDispatcher>
27
28#include <drm_fourcc.h>
29#include <fcntl.h>
30#include <gbm.h>
31#include <linux/input.h>
32#include <unistd.h>
33#include <wayland-client-core.h>
34
35#include "wayland-linux-dmabuf-unstable-v1-client-protocol.h"
36
37namespace KWin
38{
39namespace Wayland
40{
41
42using namespace KWayland::Client;
43
44inline static QPointF sizeToPoint(const QSizeF &size)
45{
46 return QPointF(size.width(), size.height());
47}
48
49WaylandInputDevice::WaylandInputDevice(KWayland::Client::Keyboard *keyboard, WaylandSeat *seat)
50 : m_seat(seat)
51 , m_keyboard(keyboard)
52{
53 connect(keyboard, &Keyboard::left, this, [this](quint32 time) {
54 for (quint32 key : std::as_const(m_pressedKeys)) {
55 Q_EMIT keyChanged(key, InputRedirection::KeyboardKeyReleased, std::chrono::milliseconds(time), this);
56 }
57 m_pressedKeys.clear();
58 });
59 connect(keyboard, &Keyboard::keyChanged, this, [this](quint32 key, Keyboard::KeyState nativeState, quint32 time) {
61 switch (nativeState) {
62 case Keyboard::KeyState::Pressed:
63 if (key == KEY_RIGHTCTRL) {
64 m_seat->backend()->togglePointerLock();
65 }
67 m_pressedKeys.insert(key);
68 break;
69 case Keyboard::KeyState::Released:
70 m_pressedKeys.remove(key);
72 break;
73 default:
74 Q_UNREACHABLE();
75 }
76 Q_EMIT keyChanged(key, state, std::chrono::milliseconds(time), this);
77 });
78}
79
80WaylandInputDevice::WaylandInputDevice(KWayland::Client::Pointer *pointer, WaylandSeat *seat)
81 : m_seat(seat)
82 , m_pointer(pointer)
83{
84 connect(pointer, &Pointer::entered, this, [this](quint32 serial, const QPointF &relativeToSurface) {
85 WaylandOutput *output = m_seat->backend()->findOutput(m_pointer->enteredSurface());
86 Q_ASSERT(output);
87 output->cursor()->setPointer(m_pointer.get());
88 });
89 connect(pointer, &Pointer::left, this, [this]() {
90 // wl_pointer.leave carries the wl_surface, but KWayland::Client::Pointer::left does not.
91 const auto outputs = m_seat->backend()->outputs();
92 for (Output *output : outputs) {
93 WaylandOutput *waylandOutput = static_cast<WaylandOutput *>(output);
94 if (waylandOutput->cursor()->pointer()) {
95 waylandOutput->cursor()->setPointer(nullptr);
96 }
97 }
98 });
99 connect(pointer, &Pointer::motion, this, [this](const QPointF &relativeToSurface, quint32 time) {
100 WaylandOutput *output = m_seat->backend()->findOutput(m_pointer->enteredSurface());
101 Q_ASSERT(output);
102 const QPointF absolutePos = output->geometry().topLeft() + relativeToSurface;
103 Q_EMIT pointerMotionAbsolute(absolutePos, std::chrono::milliseconds(time), this);
104 });
105 connect(pointer, &Pointer::buttonStateChanged, this, [this](quint32 serial, quint32 time, quint32 button, Pointer::ButtonState nativeState) {
107 switch (nativeState) {
108 case Pointer::ButtonState::Pressed:
110 break;
111 case Pointer::ButtonState::Released:
113 break;
114 default:
115 Q_UNREACHABLE();
116 }
117 Q_EMIT pointerButtonChanged(button, state, std::chrono::milliseconds(time), this);
118 });
119 // TODO: Send discreteDelta and source as well.
120 connect(pointer, &Pointer::axisChanged, this, [this](quint32 time, Pointer::Axis nativeAxis, qreal delta) {
122 switch (nativeAxis) {
123 case Pointer::Axis::Horizontal:
125 break;
126 case Pointer::Axis::Vertical:
128 break;
129 default:
130 Q_UNREACHABLE();
131 }
132 Q_EMIT pointerAxisChanged(axis, delta, 0, InputRedirection::PointerAxisSourceUnknown, std::chrono::milliseconds(time), this);
133 });
134
135 connect(pointer, &Pointer::frame, this, [this]() {
136 Q_EMIT pointerFrame(this);
137 });
138
139 KWayland::Client::PointerGestures *pointerGestures = m_seat->backend()->display()->pointerGestures();
140 if (pointerGestures) {
141 m_pinchGesture.reset(pointerGestures->createPinchGesture(m_pointer.get(), this));
142 connect(m_pinchGesture.get(), &PointerPinchGesture::started, this, [this](quint32 serial, quint32 time) {
143 Q_EMIT pinchGestureBegin(m_pinchGesture->fingerCount(), std::chrono::milliseconds(time), this);
144 });
145 connect(m_pinchGesture.get(), &PointerPinchGesture::updated, this, [this](const QSizeF &delta, qreal scale, qreal rotation, quint32 time) {
146 Q_EMIT pinchGestureUpdate(scale, rotation, sizeToPoint(delta), std::chrono::milliseconds(time), this);
147 });
148 connect(m_pinchGesture.get(), &PointerPinchGesture::ended, this, [this](quint32 serial, quint32 time) {
149 Q_EMIT pinchGestureEnd(std::chrono::milliseconds(time), this);
150 });
151 connect(m_pinchGesture.get(), &PointerPinchGesture::cancelled, this, [this](quint32 serial, quint32 time) {
152 Q_EMIT pinchGestureCancelled(std::chrono::milliseconds(time), this);
153 });
154
155 m_swipeGesture.reset(pointerGestures->createSwipeGesture(m_pointer.get(), this));
156 connect(m_swipeGesture.get(), &PointerSwipeGesture::started, this, [this](quint32 serial, quint32 time) {
157 Q_EMIT swipeGestureBegin(m_swipeGesture->fingerCount(), std::chrono::milliseconds(time), this);
158 });
159 connect(m_swipeGesture.get(), &PointerSwipeGesture::updated, this, [this](const QSizeF &delta, quint32 time) {
160 Q_EMIT swipeGestureUpdate(sizeToPoint(delta), std::chrono::milliseconds(time), this);
161 });
162 connect(m_swipeGesture.get(), &PointerSwipeGesture::ended, this, [this](quint32 serial, quint32 time) {
163 Q_EMIT swipeGestureEnd(std::chrono::milliseconds(time), this);
164 });
165 connect(m_swipeGesture.get(), &PointerSwipeGesture::cancelled, this, [this](quint32 serial, quint32 time) {
166 Q_EMIT swipeGestureCancelled(std::chrono::milliseconds(time), this);
167 });
168 }
169}
170
171WaylandInputDevice::WaylandInputDevice(KWayland::Client::RelativePointer *relativePointer, WaylandSeat *seat)
172 : m_seat(seat)
173 , m_relativePointer(relativePointer)
174{
175 connect(relativePointer, &RelativePointer::relativeMotion, this, [this](const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 timestamp) {
176 Q_EMIT pointerMotion(sizeToPoint(delta), sizeToPoint(deltaNonAccelerated), std::chrono::microseconds(timestamp), this);
177 });
178}
179
180WaylandInputDevice::WaylandInputDevice(KWayland::Client::Touch *touch, WaylandSeat *seat)
181 : m_seat(seat)
182 , m_touch(touch)
183{
184 connect(touch, &Touch::sequenceCanceled, this, [this]() {
185 Q_EMIT touchCanceled(this);
186 });
187 connect(touch, &Touch::frameEnded, this, [this]() {
188 Q_EMIT touchFrame(this);
189 });
190 connect(touch, &Touch::sequenceStarted, this, [this](TouchPoint *tp) {
191 Q_EMIT touchDown(tp->id(), tp->position(), std::chrono::milliseconds(tp->time()), this);
192 });
193 connect(touch, &Touch::pointAdded, this, [this](TouchPoint *tp) {
194 Q_EMIT touchDown(tp->id(), tp->position(), std::chrono::milliseconds(tp->time()), this);
195 });
196 connect(touch, &Touch::pointRemoved, this, [this](TouchPoint *tp) {
197 Q_EMIT touchUp(tp->id(), std::chrono::milliseconds(tp->time()), this);
198 });
199 connect(touch, &Touch::pointMoved, this, [this](TouchPoint *tp) {
200 Q_EMIT touchMotion(tp->id(), tp->position(), std::chrono::milliseconds(tp->time()), this);
201 });
202}
203
207
209{
210 return QString();
211}
212
214{
215 return QString();
216}
217
219{
220 return true;
221}
222
224{
225}
226
228{
229 return LEDs();
230}
231
233{
234}
235
237{
238 return m_keyboard != nullptr;
239}
240
242{
243 return m_pointer || m_relativePointer;
244}
245
247{
248 return false;
249}
250
252{
253 return m_touch != nullptr;
254}
255
257{
258 return false;
259}
260
262{
263 return false;
264}
265
267{
268 return false;
269}
270
272{
273 return false;
274}
275
276KWayland::Client::Pointer *WaylandInputDevice::nativePointer() const
277{
278 return m_pointer.get();
279}
280
282 : InputBackend(parent)
283 , m_backend(backend)
284{
285}
286
288{
289 WaylandSeat *seat = m_backend->seat();
290 if (seat->relativePointerDevice()) {
291 Q_EMIT deviceAdded(seat->relativePointerDevice());
292 }
293 if (seat->pointerDevice()) {
294 Q_EMIT deviceAdded(seat->pointerDevice());
295 }
296 if (seat->keyboardDevice()) {
297 Q_EMIT deviceAdded(seat->keyboardDevice());
298 }
299 if (seat->touchDevice()) {
300 Q_EMIT deviceAdded(seat->touchDevice());
301 }
302
305}
306
307WaylandSeat::WaylandSeat(KWayland::Client::Seat *nativeSeat, WaylandBackend *backend)
308 : QObject(nullptr)
309 , m_seat(nativeSeat)
310 , m_backend(backend)
311{
312 auto updateKeyboardDevice = [this](){
313 if (m_seat->hasKeyboard()) {
314 createKeyboardDevice();
315 } else {
316 destroyKeyboardDevice();
317 }
318 };
319
320 updateKeyboardDevice();
321 connect(m_seat, &Seat::hasKeyboardChanged, this, updateKeyboardDevice);
322
323 auto updatePointerDevice = [this]() {
324 if (m_seat->hasPointer()) {
325 createPointerDevice();
326 } else {
327 destroyPointerDevice();
328 }
329 };
330
331 updatePointerDevice();
332 connect(m_seat, &Seat::hasPointerChanged, this, updatePointerDevice);
333
334 auto updateTouchDevice = [this]() {
335 if (m_seat->hasTouch()) {
336 createTouchDevice();
337 } else {
338 destroyTouchDevice();
339 }
340 };
341
342 updateTouchDevice();
343 connect(m_seat, &Seat::hasTouchChanged, this, updateTouchDevice);
344}
345
347{
348 destroyPointerDevice();
349 destroyKeyboardDevice();
350 destroyTouchDevice();
351}
352
353void WaylandSeat::createPointerDevice()
354{
355 m_pointerDevice = std::make_unique<WaylandInputDevice>(m_seat->createPointer(), this);
356 Q_EMIT deviceAdded(m_pointerDevice.get());
357}
358
359void WaylandSeat::destroyPointerDevice()
360{
361 if (m_pointerDevice) {
362 Q_EMIT deviceRemoved(m_pointerDevice.get());
364 m_pointerDevice.reset();
365 }
366}
367
369{
370 KWayland::Client::RelativePointerManager *manager = m_backend->display()->relativePointerManager();
371 if (manager) {
372 m_relativePointerDevice = std::make_unique<WaylandInputDevice>(manager->createRelativePointer(m_pointerDevice->nativePointer()), this);
373 Q_EMIT deviceAdded(m_relativePointerDevice.get());
374 }
375}
376
378{
379 if (m_relativePointerDevice) {
380 Q_EMIT deviceRemoved(m_relativePointerDevice.get());
381 m_relativePointerDevice.reset();
382 }
383}
384
385void WaylandSeat::createKeyboardDevice()
386{
387 m_keyboardDevice = std::make_unique<WaylandInputDevice>(m_seat->createKeyboard(), this);
388 Q_EMIT deviceAdded(m_keyboardDevice.get());
389}
390
391void WaylandSeat::destroyKeyboardDevice()
392{
393 if (m_keyboardDevice) {
394 Q_EMIT deviceRemoved(m_keyboardDevice.get());
395 m_keyboardDevice.reset();
396 }
397}
398
399void WaylandSeat::createTouchDevice()
400{
401 m_touchDevice = std::make_unique<WaylandInputDevice>(m_seat->createTouch(), this);
402 Q_EMIT deviceAdded(m_touchDevice.get());
403}
404
405void WaylandSeat::destroyTouchDevice()
406{
407 if (m_touchDevice) {
408 Q_EMIT deviceRemoved(m_touchDevice.get());
409 m_touchDevice.reset();
410 }
411}
412
414 : OutputBackend(parent)
415 , m_options(options)
416{
417}
418
420{
421 m_eglDisplay.reset();
422 destroyOutputs();
423
424 m_buffers.clear();
425
426 m_seat.reset();
427 m_display.reset();
428
429 if (m_gbmDevice) {
430 gbm_device_destroy(m_gbmDevice);
431 }
432 qCDebug(KWIN_WAYLAND_BACKEND) << "Destroyed Wayland display";
433}
434
436{
437 m_display = std::make_unique<WaylandDisplay>();
438 if (!m_display->initialize(m_options.socketName)) {
439 return false;
440 }
441
442 if (WaylandLinuxDmabufV1 *dmabuf = m_display->linuxDmabuf()) {
443 m_drmFileDescriptor = FileDescriptor(open(dmabuf->mainDevice(), O_RDWR | O_CLOEXEC));
444 if (m_drmFileDescriptor.isValid()) {
445 m_gbmDevice = gbm_create_device(m_drmFileDescriptor.get());
446 } else {
447 qCWarning(KWIN_WAYLAND_BACKEND) << "Failed to open drm render node" << dmabuf->mainDevice();
448 }
449 }
450
451 createOutputs();
452
453 m_seat = std::make_unique<WaylandSeat>(m_display->seat(), this);
454
455 QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance();
456 QObject::connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, m_display.get(), &WaylandDisplay::flush);
457 QObject::connect(dispatcher, &QAbstractEventDispatcher::awake, m_display.get(), &WaylandDisplay::flush);
458
459 connect(this, &WaylandBackend::pointerLockChanged, this, [this](bool locked) {
460 if (locked) {
461 m_seat->createRelativePointer();
462 } else {
463 m_seat->destroyRelativePointer();
464 }
465 });
466
467 return true;
468}
469
470void WaylandBackend::createOutputs()
471{
472 // we need to multiply the initial window size with the scale in order to
473 // create an output window of this size in the end
474 const QSize pixelSize = m_options.outputSize * m_options.outputScale;
475 for (int i = 0; i < m_options.outputCount; i++) {
476 WaylandOutput *output = createOutput(QStringLiteral("WL-%1").arg(i), pixelSize, m_options.outputScale);
477 m_outputs << output;
478 Q_EMIT outputAdded(output);
479 output->updateEnabled(true);
480 }
481
482 Q_EMIT outputsQueried();
483}
484
485WaylandOutput *WaylandBackend::createOutput(const QString &name, const QSize &size, qreal scale)
486{
487 WaylandOutput *waylandOutput = new WaylandOutput(name, this);
488 waylandOutput->init(size, scale);
489
490 // Wait until the output window is configured by the host compositor.
491 while (!waylandOutput->isReady()) {
492 wl_display_roundtrip(m_display->nativeDisplay());
493 }
494
495 return waylandOutput;
496}
497
498void WaylandBackend::destroyOutputs()
499{
500 while (!m_outputs.isEmpty()) {
501 WaylandOutput *output = m_outputs.takeLast();
502 output->updateEnabled(false);
503 Q_EMIT outputRemoved(output);
504 delete output;
505 }
506}
507
508std::unique_ptr<InputBackend> WaylandBackend::createInputBackend()
509{
510 return std::make_unique<WaylandInputBackend>(this);
511}
512
513std::unique_ptr<OpenGLBackend> WaylandBackend::createOpenGLBackend()
514{
515 return std::make_unique<WaylandEglBackend>(this);
516}
517
518std::unique_ptr<QPainterBackend> WaylandBackend::createQPainterBackend()
519{
520 return std::make_unique<WaylandQPainterBackend>(this);
521}
522
523WaylandOutput *WaylandBackend::findOutput(KWayland::Client::Surface *nativeSurface) const
524{
525 for (WaylandOutput *output : m_outputs) {
526 if (output->surface() == nativeSurface) {
527 return output;
528 }
529 }
530 return nullptr;
531}
532
534{
535 return m_display->pointerConstraints() && m_display->relativePointerManager();
536}
537
539{
540 if (!supportsPointerLock()) {
541 return;
542 }
543 if (!m_seat) {
544 return;
545 }
546 auto pointer = m_seat->pointerDevice()->nativePointer();
547 if (!pointer) {
548 return;
549 }
550 if (m_outputs.isEmpty()) {
551 return;
552 }
553
554 for (auto output : std::as_const(m_outputs)) {
555 output->lockPointer(m_seat->pointerDevice()->nativePointer(), !m_pointerLockRequested);
556 }
557 m_pointerLockRequested = !m_pointerLockRequested;
558}
559
560QList<CompositingType> WaylandBackend::supportedCompositors() const
561{
562 QList<CompositingType> ret;
563 if (m_display->linuxDmabuf() && m_gbmDevice) {
564 ret.append(OpenGLCompositing);
565 }
566 ret.append(QPainterCompositing);
567 return ret;
568}
569
571{
572 return m_outputs;
573}
574
575Output *WaylandBackend::createVirtualOutput(const QString &name, const QSize &size, double scale)
576{
577 return createOutput(name, size * scale, scale);
578}
579
581{
582 WaylandOutput *waylandOutput = dynamic_cast<WaylandOutput *>(output);
583 if (waylandOutput && m_outputs.removeAll(waylandOutput)) {
584 waylandOutput->updateEnabled(false);
585 Q_EMIT outputRemoved(waylandOutput);
586 waylandOutput->unref();
587 }
588}
589
590static wl_buffer *importDmaBufBuffer(WaylandDisplay *display, const DmaBufAttributes *attributes)
591{
592 zwp_linux_buffer_params_v1 *params = zwp_linux_dmabuf_v1_create_params(display->linuxDmabuf()->handle());
593 for (int i = 0; i < attributes->planeCount; ++i) {
594 zwp_linux_buffer_params_v1_add(params,
595 attributes->fd[i].get(),
596 i,
597 attributes->offset[i],
598 attributes->pitch[i],
599 attributes->modifier >> 32,
600 attributes->modifier & 0xffffffff);
601 }
602
603 wl_buffer *buffer = zwp_linux_buffer_params_v1_create_immed(params, attributes->width, attributes->height, attributes->format, 0);
604 zwp_linux_buffer_params_v1_destroy(params);
605
606 return buffer;
607}
608
609static wl_buffer *importShmBuffer(WaylandDisplay *display, const ShmAttributes *attributes)
610{
611 wl_shm_format format;
612 switch (attributes->format) {
613 case DRM_FORMAT_ARGB8888:
614 format = WL_SHM_FORMAT_ARGB8888;
615 break;
616 case DRM_FORMAT_XRGB8888:
617 format = WL_SHM_FORMAT_XRGB8888;
618 break;
619 default:
620 format = static_cast<wl_shm_format>(attributes->format);
621 break;
622 }
623
624 wl_shm_pool *pool = wl_shm_create_pool(display->shm(), attributes->fd.get(), attributes->size.height() * attributes->stride);
625 wl_buffer *buffer = wl_shm_pool_create_buffer(pool,
626 attributes->offset,
627 attributes->size.width(),
628 attributes->size.height(),
629 attributes->stride,
630 format);
631 wl_shm_pool_destroy(pool);
632
633 return buffer;
634}
635
637{
638 auto &buffer = m_buffers[graphicsBuffer];
639 if (!buffer) {
640 wl_buffer *handle = nullptr;
641 if (const DmaBufAttributes *attributes = graphicsBuffer->dmabufAttributes()) {
642 handle = importDmaBufBuffer(m_display.get(), attributes);
643 } else if (const ShmAttributes *attributes = graphicsBuffer->shmAttributes()) {
644 handle = importShmBuffer(m_display.get(), attributes);
645 } else {
646 qCWarning(KWIN_WAYLAND_BACKEND) << graphicsBuffer << "has unknown type";
647 return nullptr;
648 }
649
650 buffer = std::make_unique<WaylandBuffer>(handle, graphicsBuffer);
651 connect(buffer.get(), &WaylandBuffer::defunct, this, [this, graphicsBuffer]() {
652 m_buffers.erase(graphicsBuffer);
653 });
654
655 static const wl_buffer_listener listener = {
656 .release = [](void *userData, wl_buffer *buffer) {
657 WaylandBuffer *slot = static_cast<WaylandBuffer *>(userData);
658 slot->unlock();
659 },
660 };
661 wl_buffer_add_listener(handle, &listener, buffer.get());
662 }
663
664 buffer->lock();
665 return buffer->handle();
666}
667
668void WaylandBackend::setEglDisplay(std::unique_ptr<EglDisplay> &&display)
669{
670 m_eglDisplay = std::move(display);
671}
672
674{
675 return m_eglDisplay.get();
676}
677
678WaylandBuffer::WaylandBuffer(wl_buffer *handle, GraphicsBuffer *graphicsBuffer)
679 : m_graphicsBuffer(graphicsBuffer)
680 , m_handle(handle)
681{
682 connect(graphicsBuffer, &GraphicsBuffer::destroyed, this, &WaylandBuffer::defunct);
683}
684
686{
687 m_graphicsBuffer->disconnect(this);
688 if (m_locked) {
689 m_graphicsBuffer->unref();
690 }
691 wl_buffer_destroy(m_handle);
692}
693
694wl_buffer *WaylandBuffer::handle() const
695{
696 return m_handle;
697}
698
700{
701 if (!m_locked) {
702 m_locked = true;
703 m_graphicsBuffer->ref();
704 }
705}
706
708{
709 if (m_locked) {
710 m_locked = false;
711 m_graphicsBuffer->unref();
712 }
713}
714}
715
716} // KWin
717
718#include "moc_wayland_backend.cpp"
virtual const DmaBufAttributes * dmabufAttributes() const
virtual const ShmAttributes * shmAttributes() const
void deviceAdded(InputDevice *device)
void deviceRemoved(InputDevice *device)
void touchFrame(InputDevice *device)
void touchMotion(qint32 id, const QPointF &absolutePos, std::chrono::microseconds time, InputDevice *device)
void touchCanceled(InputDevice *device)
void pointerMotion(const QPointF &delta, const QPointF &deltaNonAccelerated, std::chrono::microseconds time, InputDevice *device)
void pointerFrame(InputDevice *device)
void pointerButtonChanged(quint32 button, InputRedirection::PointerButtonState state, std::chrono::microseconds time, InputDevice *device)
void touchDown(qint32 id, const QPointF &absolutePos, std::chrono::microseconds time, InputDevice *device)
void pointerMotionAbsolute(const QPointF &position, std::chrono::microseconds time, InputDevice *device)
void keyChanged(quint32 key, InputRedirection::KeyboardKeyState, std::chrono::microseconds time, InputDevice *device)
void touchUp(qint32 id, std::chrono::microseconds time, InputDevice *device)
void pointerAxisChanged(InputRedirection::PointerAxis axis, qreal delta, qint32 deltaV120, InputRedirection::PointerAxisSource source, std::chrono::microseconds time, InputDevice *device)
void outputAdded(Output *output)
void outputRemoved(Output *output)
QRect geometry
Definition output.h:134
Class encapsulating all Wayland data structures needed by the Egl backend.
QList< CompositingType > supportedCompositors() const override
void setEglDisplay(std::unique_ptr< EglDisplay > &&display)
Outputs outputs() const override
std::unique_ptr< InputBackend > createInputBackend() override
WaylandDisplay * display() const
EglDisplay * sceneEglDisplayObject() const override
Output * createVirtualOutput(const QString &name, const QSize &size, double scale) override
std::unique_ptr< OpenGLBackend > createOpenGLBackend() override
void pointerLockChanged(bool locked)
wl_buffer * importBuffer(GraphicsBuffer *graphicsBuffer)
WaylandOutput * findOutput(KWayland::Client::Surface *nativeSurface) const
WaylandBackend(const WaylandBackendOptions &options, QObject *parent=nullptr)
void removeVirtualOutput(Output *output) override
std::unique_ptr< QPainterBackend > createQPainterBackend() override
WaylandBuffer(wl_buffer *handle, GraphicsBuffer *graphicsBuffer)
void setPointer(KWayland::Client::Pointer *pointer)
KWayland::Client::RelativePointerManager * relativePointerManager() const
WaylandLinuxDmabufV1 * linuxDmabuf() const
KWayland::Client::PointerGestures * pointerGestures() const
WaylandInputBackend(WaylandBackend *backend, QObject *parent=nullptr)
void setEnabled(bool enabled) override
KWayland::Client::Pointer * nativePointer() const
bool isTabletModeSwitch() const override
WaylandInputDevice(KWayland::Client::Touch *touch, WaylandSeat *seat)
zwp_linux_dmabuf_v1 * handle() const
WaylandCursor * cursor() const
void deviceRemoved(WaylandInputDevice *device)
WaylandSeat(KWayland::Client::Seat *nativeSeat, WaylandBackend *backend)
void deviceAdded(WaylandInputDevice *device)
WaylandBackend * backend() const
KWayland::Client::Output * waylandOutput(const QString &name)
GLenum format
Definition gltexture.cpp:49
@ QPainterCompositing
Definition globals.h:39
@ OpenGLCompositing
Definition globals.h:37
Options * options
Definition main.cpp:73
std::array< uint32_t, 4 > offset
std::array< uint32_t, 4 > pitch
std::array< FileDescriptor, 4 > fd