File indexing completed on 2024-05-19 05:31:27

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
0006     SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #pragma once
0011 
0012 #include <config-kwin.h>
0013 // KWin
0014 #include "core/inputbackend.h"
0015 #include "core/inputdevice.h"
0016 #include "core/outputbackend.h"
0017 #include "effect/globals.h"
0018 #include "utils/filedescriptor.h"
0019 // Qt
0020 #include <QHash>
0021 #include <QImage>
0022 #include <QObject>
0023 #include <QPoint>
0024 #include <QSize>
0025 
0026 struct wl_buffer;
0027 struct wl_display;
0028 struct gbm_device;
0029 
0030 namespace KWayland
0031 {
0032 namespace Client
0033 {
0034 class Keyboard;
0035 class Pointer;
0036 class PointerSwipeGesture;
0037 class PointerPinchGesture;
0038 class RelativePointer;
0039 class Seat;
0040 class Surface;
0041 class Touch;
0042 }
0043 }
0044 
0045 namespace KWin
0046 {
0047 class GraphicsBuffer;
0048 
0049 namespace Wayland
0050 {
0051 
0052 class WaylandBackend;
0053 class WaylandSeat;
0054 class WaylandOutput;
0055 class WaylandEglBackend;
0056 class WaylandDisplay;
0057 
0058 class WaylandInputDevice : public InputDevice
0059 {
0060     Q_OBJECT
0061 
0062 public:
0063     WaylandInputDevice(KWayland::Client::Touch *touch, WaylandSeat *seat);
0064     WaylandInputDevice(KWayland::Client::Keyboard *keyboard, WaylandSeat *seat);
0065     WaylandInputDevice(KWayland::Client::RelativePointer *relativePointer, WaylandSeat *seat);
0066     WaylandInputDevice(KWayland::Client::Pointer *pointer, WaylandSeat *seat);
0067     ~WaylandInputDevice() override;
0068 
0069     QString sysName() const override;
0070     QString name() const override;
0071 
0072     bool isEnabled() const override;
0073     void setEnabled(bool enabled) override;
0074 
0075     LEDs leds() const override;
0076     void setLeds(LEDs leds) override;
0077 
0078     bool isKeyboard() const override;
0079     bool isAlphaNumericKeyboard() const override;
0080     bool isPointer() const override;
0081     bool isTouchpad() const override;
0082     bool isTouch() const override;
0083     bool isTabletTool() const override;
0084     bool isTabletPad() const override;
0085     bool isTabletModeSwitch() const override;
0086     bool isLidSwitch() const override;
0087 
0088     KWayland::Client::Pointer *nativePointer() const;
0089 
0090 private:
0091     WaylandSeat *const m_seat;
0092 
0093     std::unique_ptr<KWayland::Client::Keyboard> m_keyboard;
0094     std::unique_ptr<KWayland::Client::Touch> m_touch;
0095     std::unique_ptr<KWayland::Client::RelativePointer> m_relativePointer;
0096     std::unique_ptr<KWayland::Client::Pointer> m_pointer;
0097     std::unique_ptr<KWayland::Client::PointerPinchGesture> m_pinchGesture;
0098     std::unique_ptr<KWayland::Client::PointerSwipeGesture> m_swipeGesture;
0099 
0100     QSet<quint32> m_pressedKeys;
0101 };
0102 
0103 class WaylandInputBackend : public InputBackend
0104 {
0105     Q_OBJECT
0106 
0107 public:
0108     explicit WaylandInputBackend(WaylandBackend *backend, QObject *parent = nullptr);
0109 
0110     void initialize() override;
0111 
0112 private:
0113     WaylandBackend *m_backend;
0114 };
0115 
0116 class WaylandSeat : public QObject
0117 {
0118     Q_OBJECT
0119 public:
0120     WaylandSeat(KWayland::Client::Seat *nativeSeat, WaylandBackend *backend);
0121     ~WaylandSeat() override;
0122 
0123     WaylandBackend *backend() const
0124     {
0125         return m_backend;
0126     }
0127 
0128     WaylandInputDevice *pointerDevice() const
0129     {
0130         return m_pointerDevice.get();
0131     }
0132     WaylandInputDevice *relativePointerDevice() const
0133     {
0134         return m_relativePointerDevice.get();
0135     }
0136     WaylandInputDevice *keyboardDevice() const
0137     {
0138         return m_keyboardDevice.get();
0139     }
0140     WaylandInputDevice *touchDevice() const
0141     {
0142         return m_touchDevice.get();
0143     }
0144 
0145     void createRelativePointer();
0146     void destroyRelativePointer();
0147 
0148 Q_SIGNALS:
0149     void deviceAdded(WaylandInputDevice *device);
0150     void deviceRemoved(WaylandInputDevice *device);
0151 
0152 private:
0153     void createPointerDevice();
0154     void destroyPointerDevice();
0155     void createKeyboardDevice();
0156     void destroyKeyboardDevice();
0157     void createTouchDevice();
0158     void destroyTouchDevice();
0159 
0160     KWayland::Client::Seat *m_seat;
0161     WaylandBackend *m_backend;
0162 
0163     std::unique_ptr<WaylandInputDevice> m_pointerDevice;
0164     std::unique_ptr<WaylandInputDevice> m_relativePointerDevice;
0165     std::unique_ptr<WaylandInputDevice> m_keyboardDevice;
0166     std::unique_ptr<WaylandInputDevice> m_touchDevice;
0167 };
0168 
0169 class WaylandBuffer : public QObject
0170 {
0171     Q_OBJECT
0172 
0173 public:
0174     WaylandBuffer(wl_buffer *handle, GraphicsBuffer *graphicsBuffer);
0175     ~WaylandBuffer() override;
0176 
0177     wl_buffer *handle() const;
0178 
0179     void lock();
0180     void unlock();
0181 
0182 Q_SIGNALS:
0183     void defunct();
0184 
0185 private:
0186     GraphicsBuffer *m_graphicsBuffer;
0187     wl_buffer *m_handle;
0188     bool m_locked = false;
0189 };
0190 
0191 struct WaylandBackendOptions
0192 {
0193     QString socketName;
0194     int outputCount = 1;
0195     qreal outputScale = 1;
0196     QSize outputSize = QSize(1024, 768);
0197 };
0198 
0199 /**
0200  * @brief Class encapsulating all Wayland data structures needed by the Egl backend.
0201  *
0202  * It creates the connection to the Wayland Compositor, sets up the registry and creates
0203  * the Wayland output surfaces and its shell mappings.
0204  */
0205 class KWIN_EXPORT WaylandBackend : public OutputBackend
0206 {
0207     Q_OBJECT
0208 
0209 public:
0210     explicit WaylandBackend(const WaylandBackendOptions &options, QObject *parent = nullptr);
0211     ~WaylandBackend() override;
0212     bool initialize() override;
0213 
0214     std::unique_ptr<InputBackend> createInputBackend() override;
0215     std::unique_ptr<OpenGLBackend> createOpenGLBackend() override;
0216     std::unique_ptr<QPainterBackend> createQPainterBackend() override;
0217 
0218     WaylandDisplay *display() const
0219     {
0220         return m_display.get();
0221     }
0222     WaylandSeat *seat() const
0223     {
0224         return m_seat.get();
0225     }
0226 
0227     bool supportsPointerLock();
0228     void togglePointerLock();
0229 
0230     QList<CompositingType> supportedCompositors() const override;
0231 
0232     WaylandOutput *findOutput(KWayland::Client::Surface *nativeSurface) const;
0233     Outputs outputs() const override;
0234     QList<WaylandOutput *> waylandOutputs() const
0235     {
0236         return m_outputs;
0237     }
0238 
0239     Output *createVirtualOutput(const QString &name, const QSize &size, double scale) override;
0240     void removeVirtualOutput(Output *output) override;
0241 
0242     wl_buffer *importBuffer(GraphicsBuffer *graphicsBuffer);
0243 
0244     gbm_device *gbmDevice() const
0245     {
0246         return m_gbmDevice;
0247     }
0248 
0249     void setEglBackend(WaylandEglBackend *eglBackend)
0250     {
0251         m_eglBackend = eglBackend;
0252     }
0253     void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
0254     EglDisplay *sceneEglDisplayObject() const override;
0255 
0256 Q_SIGNALS:
0257     void pointerLockChanged(bool locked);
0258 
0259 private:
0260     void createOutputs();
0261     void destroyOutputs();
0262     WaylandOutput *createOutput(const QString &name, const QSize &size, qreal scale);
0263 
0264     WaylandBackendOptions m_options;
0265     std::unique_ptr<WaylandDisplay> m_display;
0266     std::unique_ptr<WaylandSeat> m_seat;
0267     WaylandEglBackend *m_eglBackend = nullptr;
0268     QList<WaylandOutput *> m_outputs;
0269     bool m_pointerLockRequested = false;
0270     FileDescriptor m_drmFileDescriptor;
0271     gbm_device *m_gbmDevice = nullptr;
0272     std::unique_ptr<EglDisplay> m_eglDisplay;
0273     std::map<GraphicsBuffer *, std::unique_ptr<WaylandBuffer>> m_buffers;
0274 };
0275 
0276 } // namespace Wayland
0277 } // namespace KWin