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

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 
0011 #include "core/inputbackend.h"
0012 #include "core/inputdevice.h"
0013 #include "core/outputbackend.h"
0014 #include "utils/filedescriptor.h"
0015 
0016 #include <kwin_export.h>
0017 
0018 #include <QObject>
0019 #include <QSize>
0020 
0021 #include <xcb/xcb.h>
0022 
0023 struct gbm_device;
0024 struct _XDisplay;
0025 typedef struct _XDisplay Display;
0026 typedef struct _XCBKeySymbols xcb_key_symbols_t;
0027 class NETWinInfo;
0028 class QSocketNotifier;
0029 
0030 namespace KWin
0031 {
0032 class X11WindowedBackend;
0033 class X11WindowedOutput;
0034 
0035 class X11WindowedInputDevice : public InputDevice
0036 {
0037     Q_OBJECT
0038 
0039 public:
0040     explicit X11WindowedInputDevice() = default;
0041 
0042     void setPointer(bool set);
0043     void setKeyboard(bool set);
0044     void setTouch(bool set);
0045     void setName(const QString &name);
0046 
0047     QString sysName() const override;
0048     QString name() const override;
0049 
0050     bool isEnabled() const override;
0051     void setEnabled(bool enabled) override;
0052 
0053     LEDs leds() const override;
0054     void setLeds(LEDs leds) override;
0055 
0056     bool isKeyboard() const override;
0057     bool isAlphaNumericKeyboard() const override;
0058     bool isPointer() const override;
0059     bool isTouchpad() const override;
0060     bool isTouch() const override;
0061     bool isTabletTool() const override;
0062     bool isTabletPad() const override;
0063     bool isTabletModeSwitch() const override;
0064     bool isLidSwitch() const override;
0065 
0066 private:
0067     QString m_name;
0068     bool m_pointer = false;
0069     bool m_keyboard = false;
0070     bool m_touch = false;
0071 };
0072 
0073 class X11WindowedInputBackend : public InputBackend
0074 {
0075     Q_OBJECT
0076 
0077 public:
0078     explicit X11WindowedInputBackend(X11WindowedBackend *backend);
0079 
0080     void initialize() override;
0081 
0082 private:
0083     X11WindowedBackend *m_backend;
0084 };
0085 
0086 struct X11WindowedBackendOptions
0087 {
0088     QString display;
0089     int outputCount = 1;
0090     qreal outputScale = 1;
0091     QSize outputSize = QSize(1024, 768);
0092 };
0093 
0094 class KWIN_EXPORT X11WindowedBackend : public OutputBackend
0095 {
0096     Q_OBJECT
0097 
0098 public:
0099     explicit X11WindowedBackend(const X11WindowedBackendOptions &options);
0100     ~X11WindowedBackend() override;
0101 
0102     ::Display *display() const;
0103     xcb_connection_t *connection() const;
0104     xcb_screen_t *screen() const;
0105     int screenNumer() const;
0106     xcb_window_t rootWindow() const;
0107     gbm_device *gbmDevice() const;
0108 
0109     bool hasXInput() const;
0110 
0111     QHash<uint32_t, QList<uint64_t>> driFormats() const;
0112     uint32_t driFormatForDepth(int depth) const;
0113     int driMajorVersion() const;
0114     int driMinorVersion() const;
0115 
0116     bool initialize() override;
0117     std::unique_ptr<OpenGLBackend> createOpenGLBackend() override;
0118     std::unique_ptr<QPainterBackend> createQPainterBackend() override;
0119     std::unique_ptr<InputBackend> createInputBackend() override;
0120     QList<CompositingType> supportedCompositors() const override;
0121     Outputs outputs() const override;
0122 
0123     X11WindowedInputDevice *pointerDevice() const;
0124     X11WindowedInputDevice *keyboardDevice() const;
0125     X11WindowedInputDevice *touchDevice() const;
0126 
0127     void setEglDisplay(std::unique_ptr<EglDisplay> &&display);
0128     EglDisplay *sceneEglDisplayObject() const override;
0129 
0130 private:
0131     void createOutputs();
0132     void grabKeyboard(xcb_timestamp_t time);
0133     void updateWindowTitle();
0134     void handleEvent(xcb_generic_event_t *event);
0135     void handleClientMessage(xcb_client_message_event_t *event);
0136     void handleButtonPress(xcb_button_press_event_t *event);
0137     void handleExpose(xcb_expose_event_t *event);
0138     void handleXinputEvent(xcb_ge_generic_event_t *event);
0139     void handlePresentEvent(xcb_ge_generic_event_t *event);
0140     void updateSize(xcb_configure_notify_event_t *event);
0141     void initXInput();
0142     void initDri3();
0143     X11WindowedOutput *findOutput(xcb_window_t window) const;
0144     void destroyOutputs();
0145 
0146     X11WindowedBackendOptions m_options;
0147     xcb_connection_t *m_connection = nullptr;
0148     xcb_screen_t *m_screen = nullptr;
0149     xcb_key_symbols_t *m_keySymbols = nullptr;
0150     int m_screenNumber = 0;
0151 
0152     std::unique_ptr<X11WindowedInputDevice> m_pointerDevice;
0153     std::unique_ptr<X11WindowedInputDevice> m_keyboardDevice;
0154     std::unique_ptr<X11WindowedInputDevice> m_touchDevice;
0155 
0156     xcb_atom_t m_protocols = XCB_ATOM_NONE;
0157     xcb_atom_t m_deleteWindowProtocol = XCB_ATOM_NONE;
0158     ::Display *m_display = nullptr;
0159     bool m_keyboardGrabbed = false;
0160     std::unique_ptr<QSocketNotifier> m_eventNotifier;
0161 
0162     bool m_hasXInput = false;
0163     int m_xiOpcode = 0;
0164     int m_majorVersion = 0;
0165     int m_minorVersion = 0;
0166 
0167     int m_presentOpcode = 0;
0168     int m_presentMajorVersion = 0;
0169     int m_presentMinorVersion = 0;
0170 
0171     bool m_hasShm = false;
0172 
0173     bool m_hasDri = false;
0174     int m_driMajorVersion = 0;
0175     int m_driMinorVersion = 0;
0176     QHash<uint32_t, QList<uint64_t>> m_driFormats;
0177 
0178     FileDescriptor m_drmFileDescriptor;
0179     gbm_device *m_gbmDevice = nullptr;
0180     std::unique_ptr<EglDisplay> m_eglDisplay;
0181 
0182     QList<X11WindowedOutput *> m_outputs;
0183 };
0184 
0185 } // namespace KWin