File indexing completed on 2024-11-10 04:56:37

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 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 
0011 #include "core/output.h"
0012 #include <kwin_export.h>
0013 
0014 #include <QObject>
0015 #include <QSize>
0016 #include <QString>
0017 
0018 #include <unordered_map>
0019 
0020 #include <xcb/xcb.h>
0021 #include <xcb/present.h>
0022 
0023 class NETWinInfo;
0024 
0025 namespace KWin
0026 {
0027 
0028 class GraphicsBuffer;
0029 class X11WindowedBackend;
0030 class X11WindowedOutput;
0031 class OutputFrame;
0032 
0033 struct DmaBufAttributes;
0034 struct ShmAttributes;
0035 
0036 class X11WindowedBuffer : public QObject
0037 {
0038     Q_OBJECT
0039 
0040 public:
0041     X11WindowedBuffer(X11WindowedOutput *output, xcb_pixmap_t pixmap, GraphicsBuffer *buffer);
0042     ~X11WindowedBuffer() override;
0043 
0044     GraphicsBuffer *buffer() const;
0045     xcb_pixmap_t pixmap() const;
0046 
0047     void lock();
0048     void unlock();
0049 
0050 Q_SIGNALS:
0051     void defunct();
0052 
0053 private:
0054     X11WindowedOutput *m_output;
0055     GraphicsBuffer *m_buffer;
0056     xcb_pixmap_t m_pixmap;
0057     bool m_locked = false;
0058 };
0059 
0060 class X11WindowedCursor
0061 {
0062 public:
0063     explicit X11WindowedCursor(X11WindowedOutput *output);
0064     ~X11WindowedCursor();
0065 
0066     void update(const QImage &image, const QPointF &hotspot);
0067 
0068 private:
0069     X11WindowedOutput *m_output;
0070     xcb_cursor_t m_handle = XCB_CURSOR_NONE;
0071 };
0072 
0073 /**
0074  * Wayland outputs in a nested X11 setup
0075  */
0076 class KWIN_EXPORT X11WindowedOutput : public Output
0077 {
0078     Q_OBJECT
0079 public:
0080     explicit X11WindowedOutput(X11WindowedBackend *backend);
0081     ~X11WindowedOutput() override;
0082 
0083     RenderLoop *renderLoop() const override;
0084 
0085     void init(const QSize &pixelSize, qreal scale);
0086     void resize(const QSize &pixelSize);
0087 
0088     X11WindowedBackend *backend() const;
0089     X11WindowedCursor *cursor() const;
0090     xcb_window_t window() const;
0091     int depth() const;
0092 
0093     xcb_pixmap_t importBuffer(GraphicsBuffer *buffer);
0094 
0095     QPoint internalPosition() const;
0096     QPoint hostPosition() const;
0097     void setHostPosition(const QPoint &pos);
0098 
0099     void setWindowTitle(const QString &title);
0100 
0101     /**
0102      * Translates the global X11 screen coordinate @p pos to output coordinates.
0103      */
0104     QPointF mapFromGlobal(const QPointF &pos) const;
0105 
0106     bool updateCursorLayer() override;
0107 
0108     QRegion exposedArea() const;
0109     void addExposedArea(const QRect &rect);
0110     void clearExposedArea();
0111 
0112     void updateEnabled(bool enabled);
0113 
0114     void handlePresentCompleteNotify(xcb_present_complete_notify_event_t *event);
0115     void handlePresentIdleNotify(xcb_present_idle_notify_event_t *event);
0116     void framePending(const std::shared_ptr<OutputFrame> &frame);
0117 
0118 private:
0119     void initXInputForWindow();
0120 
0121     xcb_pixmap_t importDmaBufBuffer(const DmaBufAttributes *attributes);
0122     xcb_pixmap_t importShmBuffer(const ShmAttributes *attributes);
0123 
0124     xcb_window_t m_window = XCB_WINDOW_NONE;
0125     xcb_present_event_t m_presentEvent = XCB_NONE;
0126     std::unique_ptr<NETWinInfo> m_winInfo;
0127     std::unique_ptr<RenderLoop> m_renderLoop;
0128     std::unique_ptr<X11WindowedCursor> m_cursor;
0129     std::unordered_map<GraphicsBuffer *, std::unique_ptr<X11WindowedBuffer>> m_buffers;
0130     QPoint m_hostPosition;
0131     QRegion m_exposedArea;
0132     std::shared_ptr<OutputFrame> m_frame;
0133 
0134     X11WindowedBackend *m_backend;
0135 };
0136 
0137 } // namespace KWin