1 /*
2     KWin - the KDE window manager
3     This file is part of the KDE project.
4 
5     SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #pragma once
11 
12 #include <QObject>
13 #include <QUrl>
14 #include <QRect>
15 
16 #include <kwineffects_export.h>
17 
18 #include "kwineffects.h"
19 
20 #include <memory>
21 
22 class QKeyEvent;
23 class QMouseEvent;
24 
25 class QMouseEvent;
26 class QKeyEvent;
27 
28 class QQmlContext;
29 class QQuickItem;
30 
31 namespace KWin
32 {
33 class GLTexture;
34 
35 class EffectQuickView;
36 
37 /**
38  * @brief The KwinQuickView class provides a convenient API for exporting
39  * QtQuick scenes as buffers that can be composited in any other fashion.
40  *
41  * Contents can be fetched as a GL Texture or as a QImage
42  * If data is to be fetched as an image, it should be specified upfront as
43  * blitting is performed when we update our FBO to keep kwin's render loop
44  * as fast as possible.
45  */
46 class KWINEFFECTS_EXPORT EffectQuickView : public QObject
47 {
48     Q_OBJECT
49 
50 public:
51     enum class ExportMode {
52         /** The contents will be available as a texture in the shared contexts. Image will be blank*/
53         Texture,
54         /** The contents will be blit during the update into a QImage buffer. */
55         Image
56     };
57 
58     /**
59      * Construct a new KWinQuickView
60      * Export mode will be determined by the current effectsHandler
61      */
62     EffectQuickView(QObject *parent);
63 
64     /**
65      * Construct a new EffectQuickView with the specified @a parent and the
66      * render window @a renderWindow. The render window can be used by QtQuick
67      * to compute the scale factor.
68      */
69     EffectQuickView(QObject *parent, QWindow *renderWindow);
70 
71     /**
72      * Construct a new EffectQuickView with the specified @a parent and the
73      * render window @a renderWindow. The render window can be used by QtQuick
74      * to compute the scale factor.
75      */
76     EffectQuickView(QObject *parent, QWindow *renderWindow, ExportMode exportMode);
77 
78     /**
79      * Construct a new KWinQuickView explicitly stating an export mode
80      */
81     EffectQuickView(QObject *parent, ExportMode exportMode);
82 
83     /**
84      * Note that this may change the current GL Context
85      */
86     ~EffectQuickView();
87 
88     QSize size() const;
89 
90     /**
91      * The geometry of the current view
92      * This may be out of sync with the current buffer size if an update is pending
93      */
94     void setGeometry(const QRect &rect);
95     QRect geometry() const;
96 
97     /**
98      * Render the current scene graph into the FBO.
99      * This is typically done automatically when the scene changes
100      * albeit deffered by a timer
101      *
102      * It can be manually invoked to update the contents immediately.
103      * Note this will change the GL context
104      */
105     void update();
106 
107     /** The invisble root item of the window*/
108     QQuickItem *contentItem() const;
109 
110     /**
111      * @brief Marks the window as visible/invisible
112      * This can be used to release resources used by the window
113      * The default is true.
114      */
115     void setVisible(bool visible);
116     bool isVisible() const;
117 
118     void show();
119     void hide();
120 
121     bool automaticRepaint() const;
122     void setAutomaticRepaint(bool set);
123 
124     /**
125      * Returns the current output of the scene graph
126      * @note The render context must valid at the time of calling
127      */
128     GLTexture *bufferAsTexture();
129 
130     /**
131      * Returns the current output of the scene graph
132      */
133     QImage bufferAsImage() const;
134 
135     /**
136      * Inject any mouse event into the QQuickWindow.
137      * Local co-ordinates are transformed
138      * If it is handled the event will be accepted
139      */
140     void forwardMouseEvent(QEvent *mouseEvent);
141     /**
142      * Inject a key event into the window.
143      * If it is handled the event will be accepted
144      */
145     void forwardKeyEvent(QKeyEvent *keyEvent);
146 
147 Q_SIGNALS:
148     /**
149      * The frame buffer has changed, contents need re-rendering on screen
150      */
151     void repaintNeeded();
152     void geometryChanged(const QRect &oldGeometry, const QRect &newGeometry);
153     void renderRequested();
154     void sceneChanged();
155 
156 private:
157     void handleRenderRequested();
158     void handleSceneChanged();
159 
160     class Private;
161     QScopedPointer<Private> d;
162 };
163 
164 /**
165  * The KWinQuickScene class extends KWinQuickView
166  * adding QML support. This will represent a context
167  * powered by an engine
168  */
169 class KWINEFFECTS_EXPORT EffectQuickScene : public EffectQuickView
170 {
171 public:
172     EffectQuickScene(QObject *parent);
173     EffectQuickScene(QObject *parent, ExportMode exportMode);
174     EffectQuickScene(QObject *parent, QWindow *renderWindow);
175     EffectQuickScene(QObject *parent, QWindow *renderWindow, ExportMode exportMode);
176     ~EffectQuickScene();
177 
178     QQmlContext *rootContext() const;
179     /** top level item in the given source*/
180     QQuickItem *rootItem() const;
181 
182     void setSource(const QUrl &source);
183 
184 private:
185     class Private;
186     QScopedPointer<Private> d;
187 };
188 
189 }
190