File indexing completed on 2024-05-19 16:33:53
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 "utils/filedescriptor.h" 0018 #include <kwinglobals.h> 0019 // Qt 0020 #include <QHash> 0021 #include <QImage> 0022 #include <QObject> 0023 #include <QPoint> 0024 #include <QSize> 0025 0026 struct wl_display; 0027 struct gbm_device; 0028 struct gbm_bo; 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 DpmsInputEventFilter; 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 0101 class WaylandInputBackend : public InputBackend 0102 { 0103 Q_OBJECT 0104 0105 public: 0106 explicit WaylandInputBackend(WaylandBackend *backend, QObject *parent = nullptr); 0107 0108 void initialize() override; 0109 0110 private: 0111 WaylandBackend *m_backend; 0112 }; 0113 0114 class WaylandSeat : public QObject 0115 { 0116 Q_OBJECT 0117 public: 0118 WaylandSeat(KWayland::Client::Seat *nativeSeat, WaylandBackend *backend); 0119 ~WaylandSeat() override; 0120 0121 WaylandBackend *backend() const 0122 { 0123 return m_backend; 0124 } 0125 0126 WaylandInputDevice *pointerDevice() const 0127 { 0128 return m_pointerDevice.get(); 0129 } 0130 WaylandInputDevice *relativePointerDevice() const 0131 { 0132 return m_relativePointerDevice.get(); 0133 } 0134 WaylandInputDevice *keyboardDevice() const 0135 { 0136 return m_keyboardDevice.get(); 0137 } 0138 WaylandInputDevice *touchDevice() const 0139 { 0140 return m_touchDevice.get(); 0141 } 0142 0143 void createRelativePointer(); 0144 void destroyRelativePointer(); 0145 0146 Q_SIGNALS: 0147 void deviceAdded(WaylandInputDevice *device); 0148 void deviceRemoved(WaylandInputDevice *device); 0149 0150 private: 0151 void createPointerDevice(); 0152 void destroyPointerDevice(); 0153 void createKeyboardDevice(); 0154 void destroyKeyboardDevice(); 0155 void createTouchDevice(); 0156 void destroyTouchDevice(); 0157 0158 KWayland::Client::Seat *m_seat; 0159 WaylandBackend *m_backend; 0160 0161 std::unique_ptr<WaylandInputDevice> m_pointerDevice; 0162 std::unique_ptr<WaylandInputDevice> m_relativePointerDevice; 0163 std::unique_ptr<WaylandInputDevice> m_keyboardDevice; 0164 std::unique_ptr<WaylandInputDevice> m_touchDevice; 0165 }; 0166 0167 struct WaylandBackendOptions 0168 { 0169 QString socketName; 0170 int outputCount = 1; 0171 qreal outputScale = 1; 0172 QSize outputSize = QSize(1024, 768); 0173 }; 0174 0175 /** 0176 * @brief Class encapsulating all Wayland data structures needed by the Egl backend. 0177 * 0178 * It creates the connection to the Wayland Compositor, sets up the registry and creates 0179 * the Wayland output surfaces and its shell mappings. 0180 */ 0181 class KWIN_EXPORT WaylandBackend : public OutputBackend 0182 { 0183 Q_OBJECT 0184 0185 public: 0186 explicit WaylandBackend(const WaylandBackendOptions &options, QObject *parent = nullptr); 0187 ~WaylandBackend() override; 0188 bool initialize() override; 0189 0190 std::unique_ptr<InputBackend> createInputBackend() override; 0191 std::unique_ptr<OpenGLBackend> createOpenGLBackend() override; 0192 std::unique_ptr<QPainterBackend> createQPainterBackend() override; 0193 0194 WaylandDisplay *display() const 0195 { 0196 return m_display.get(); 0197 } 0198 WaylandSeat *seat() const 0199 { 0200 return m_seat.get(); 0201 } 0202 0203 bool supportsPointerLock(); 0204 void togglePointerLock(); 0205 0206 QVector<CompositingType> supportedCompositors() const override; 0207 0208 WaylandOutput *findOutput(KWayland::Client::Surface *nativeSurface) const; 0209 Outputs outputs() const override; 0210 QVector<WaylandOutput *> waylandOutputs() const 0211 { 0212 return m_outputs; 0213 } 0214 void createDpmsFilter(); 0215 void clearDpmsFilter(); 0216 0217 Output *createVirtualOutput(const QString &name, const QSize &size, double scale) override; 0218 void removeVirtualOutput(Output *output) override; 0219 0220 std::optional<DmaBufParams> testCreateDmaBuf(const QSize &size, quint32 format, const QVector<uint64_t> &modifiers) override; 0221 std::shared_ptr<DmaBufTexture> createDmaBufTexture(const QSize &size, quint32 format, uint64_t modifier) override; 0222 0223 gbm_device *gbmDevice() const 0224 { 0225 return m_gbmDevice; 0226 } 0227 0228 void setEglBackend(WaylandEglBackend *eglBackend) 0229 { 0230 m_eglBackend = eglBackend; 0231 } 0232 0233 Q_SIGNALS: 0234 void pointerLockChanged(bool locked); 0235 0236 private: 0237 void createOutputs(); 0238 void destroyOutputs(); 0239 WaylandOutput *createOutput(const QString &name, const QSize &size, qreal scale); 0240 0241 WaylandBackendOptions m_options; 0242 std::unique_ptr<WaylandDisplay> m_display; 0243 std::unique_ptr<WaylandSeat> m_seat; 0244 WaylandEglBackend *m_eglBackend = nullptr; 0245 QVector<WaylandOutput *> m_outputs; 0246 std::unique_ptr<DpmsInputEventFilter> m_dpmsFilter; 0247 bool m_pointerLockRequested = false; 0248 FileDescriptor m_drmFileDescriptor; 0249 gbm_device *m_gbmDevice; 0250 }; 0251 0252 } // namespace Wayland 0253 } // namespace KWin