1 | /***************************************************************** |
2 | This file is part of the KDE project. |
3 | |
4 | Copyright (C) 2009 Lubos Lunak <l.lunak@kde.org> |
5 | Copyright (C) 2012 Martin Gräßlin <mgraesslin@kde.org> |
6 | |
7 | Permission is hereby granted, free of charge, to any person obtaining a |
8 | copy of this software and associated documentation files (the "Software"), |
9 | to deal in the Software without restriction, including without limitation |
10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
11 | and/or sell copies of the Software, and to permit persons to whom the |
12 | Software is furnished to do so, subject to the following conditions: |
13 | |
14 | The above copyright notice and this permission notice shall be included in |
15 | all copies or substantial portions of the Software. |
16 | |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | DEALINGS IN THE SOFTWARE. |
24 | ******************************************************************/ |
25 | |
26 | #ifndef PAINTREDIRECTOR_H |
27 | #define PAINTREDIRECTOR_H |
28 | |
29 | #include <qregion.h> |
30 | #include <qtimer.h> |
31 | #include <qwidget.h> |
32 | #include <qbasictimer.h> |
33 | // xcb |
34 | #include <xcb/render.h> |
35 | |
36 | namespace KWin |
37 | { |
38 | |
39 | // forward declarations |
40 | class Client; |
41 | class Deleted; |
42 | class XRenderPicture; |
43 | class GLTexture; |
44 | |
45 | // This class redirects all painting of a given widget (including its children) |
46 | // into a paint device (QPixmap). |
47 | class PaintRedirector |
48 | : public QObject |
49 | { |
50 | Q_OBJECT |
51 | public: |
52 | enum DecorationPixmap { |
53 | TopPixmap, |
54 | RightPixmap, |
55 | BottomPixmap, |
56 | LeftPixmap, |
57 | PixmapCount |
58 | }; |
59 | virtual ~PaintRedirector(); |
60 | virtual bool eventFilter(QObject* o, QEvent* e); |
61 | QRegion pendingRegion() const; |
62 | QRegion scheduledRepaintRegion(); |
63 | |
64 | void markAsRepainted() { |
65 | m_requiresRepaint = false; |
66 | } |
67 | bool requiresRepaint() const { |
68 | return m_requiresRepaint; |
69 | } |
70 | void resizePixmaps(); |
71 | |
72 | template <typename T> |
73 | T topDecoPixmap() const; |
74 | template <typename T> |
75 | T leftDecoPixmap() const; |
76 | template <typename T> |
77 | T bottomDecoPixmap() const; |
78 | template <typename T> |
79 | T rightDecoPixmap() const; |
80 | |
81 | /** |
82 | * Used by Deleted::copyToDeleted() to move the PaintRedirector to the Deleted. |
83 | * The actual redirecting ends as the decoration gets destroyed after the Deleted |
84 | * is created. |
85 | **/ |
86 | void reparent(Deleted *d); |
87 | static PaintRedirector *create(Client *c, QWidget* widget); |
88 | |
89 | public slots: |
90 | void ensurePixmapsPainted(); |
91 | protected: |
92 | PaintRedirector(Client *c, QWidget* widget); |
93 | virtual xcb_render_picture_t picture(DecorationPixmap border) const; |
94 | virtual GLTexture *texture(DecorationPixmap border) const; |
95 | virtual void resizePixmaps(const QRect *rects); |
96 | virtual void resize(DecorationPixmap border, const QSize &size); |
97 | virtual void preparePaint(const QPixmap &pending); |
98 | virtual void updatePixmaps(const QRect *rects, const QRegion ®ion); |
99 | virtual void paint(DecorationPixmap border, const QRect& r, const QRect &b, const QRegion ®); |
100 | virtual QPaintDevice *scratch() = 0; |
101 | virtual QPaintDevice *recreateScratch(const QSize &size) = 0; |
102 | virtual void fillScratch(Qt::GlobalColor color) = 0; |
103 | virtual void discardScratch() = 0; |
104 | |
105 | private: |
106 | void added(QWidget* widget); |
107 | void removed(QWidget* widget); |
108 | bool isToolTip(QWidget* widget) const; |
109 | void timerEvent(QTimerEvent* event); |
110 | |
111 | void performPendingPaint(); |
112 | void repaintPixmap(DecorationPixmap border, const QRect& r, QRegion reg); |
113 | QWidget* widget; |
114 | QRegion pending; |
115 | QRegion scheduled; |
116 | bool recursionCheck; |
117 | QBasicTimer cleanupTimer; |
118 | |
119 | Client *m_client; |
120 | bool m_requiresRepaint; |
121 | }; |
122 | |
123 | class ImageBasedPaintRedirector : public PaintRedirector |
124 | { |
125 | Q_OBJECT |
126 | public: |
127 | virtual ~ImageBasedPaintRedirector(); |
128 | protected: |
129 | ImageBasedPaintRedirector(Client *c, QWidget *widget); |
130 | virtual QPaintDevice *recreateScratch(const QSize &size); |
131 | virtual QPaintDevice *scratch(); |
132 | virtual void fillScratch(Qt::GlobalColor color); |
133 | virtual void discardScratch(); |
134 | const QImage &scratchImage() const; |
135 | private: |
136 | QImage m_scratchImage; |
137 | }; |
138 | |
139 | class OpenGLPaintRedirector : public ImageBasedPaintRedirector |
140 | { |
141 | Q_OBJECT |
142 | |
143 | enum Texture { LeftRight = 0, TopBottom, TextureCount }; |
144 | |
145 | public: |
146 | OpenGLPaintRedirector(Client *c, QWidget *widget); |
147 | virtual ~OpenGLPaintRedirector(); |
148 | |
149 | GLTexture *leftRightTexture() const { return m_textures[LeftRight]; } |
150 | GLTexture *topBottomTexture() const { return m_textures[TopBottom]; } |
151 | |
152 | protected: |
153 | virtual void resizePixmaps(const QRect *rects); |
154 | virtual void updatePixmaps(const QRect *rects, const QRegion ®ion); |
155 | virtual void preparePaint(const QPixmap &pending); |
156 | |
157 | private: |
158 | QImage m_tempImage; |
159 | GLTexture *m_textures[2]; |
160 | }; |
161 | |
162 | class NativeXRenderPaintRedirector : public PaintRedirector |
163 | { |
164 | Q_OBJECT |
165 | public: |
166 | NativeXRenderPaintRedirector(Client *c, QWidget *widget); |
167 | virtual ~NativeXRenderPaintRedirector(); |
168 | |
169 | protected: |
170 | virtual xcb_render_picture_t picture(DecorationPixmap border) const; |
171 | virtual void resize(DecorationPixmap border, const QSize &size); |
172 | virtual void paint(DecorationPixmap border, const QRect &r, const QRect &b, const QRegion ®); |
173 | virtual void fillScratch(Qt::GlobalColor color); |
174 | virtual QPaintDevice *recreateScratch(const QSize &size); |
175 | virtual QPaintDevice *scratch(); |
176 | virtual void discardScratch(); |
177 | private: |
178 | QPixmap m_pixmaps[PixmapCount]; |
179 | QPixmap m_scratch; |
180 | }; |
181 | |
182 | class RasterXRenderPaintRedirector : public ImageBasedPaintRedirector |
183 | { |
184 | Q_OBJECT |
185 | public: |
186 | RasterXRenderPaintRedirector(Client *c, QWidget *widget); |
187 | virtual ~RasterXRenderPaintRedirector(); |
188 | |
189 | protected: |
190 | virtual xcb_render_picture_t picture(DecorationPixmap border) const; |
191 | virtual void resize(DecorationPixmap border, const QSize &size); |
192 | virtual void paint(DecorationPixmap border, const QRect &r, const QRect &b, const QRegion ®); |
193 | virtual void preparePaint(const QPixmap &pending); |
194 | private: |
195 | QSize m_sizes[PixmapCount]; |
196 | xcb_pixmap_t m_pixmaps[PixmapCount]; |
197 | xcb_gcontext_t m_gc; |
198 | XRenderPicture* m_pictures[PixmapCount]; |
199 | QImage m_tempImage; |
200 | }; |
201 | |
202 | template <> |
203 | inline |
204 | GLTexture *PaintRedirector::bottomDecoPixmap() const |
205 | { |
206 | return texture(BottomPixmap); |
207 | } |
208 | |
209 | template <> |
210 | inline |
211 | GLTexture *PaintRedirector::leftDecoPixmap() const |
212 | { |
213 | return texture(LeftPixmap); |
214 | } |
215 | |
216 | template <> |
217 | inline |
218 | GLTexture *PaintRedirector::rightDecoPixmap() const |
219 | { |
220 | return texture(RightPixmap); |
221 | } |
222 | |
223 | template <> |
224 | inline |
225 | GLTexture *PaintRedirector::topDecoPixmap() const |
226 | { |
227 | return texture(TopPixmap); |
228 | } |
229 | |
230 | template <> |
231 | inline |
232 | xcb_render_picture_t PaintRedirector::bottomDecoPixmap() const |
233 | { |
234 | return picture(BottomPixmap); |
235 | } |
236 | |
237 | template <> |
238 | inline |
239 | xcb_render_picture_t PaintRedirector::leftDecoPixmap() const |
240 | { |
241 | return picture(LeftPixmap); |
242 | } |
243 | |
244 | template <> |
245 | inline |
246 | xcb_render_picture_t PaintRedirector::rightDecoPixmap() const |
247 | { |
248 | return picture(RightPixmap); |
249 | } |
250 | |
251 | template <> |
252 | inline |
253 | xcb_render_picture_t PaintRedirector::topDecoPixmap() const |
254 | { |
255 | return picture(TopPixmap); |
256 | } |
257 | |
258 | inline |
259 | const QImage &ImageBasedPaintRedirector::scratchImage() const |
260 | { |
261 | return m_scratchImage; |
262 | } |
263 | |
264 | } // namespace |
265 | |
266 | #endif |
267 | |