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