1 /*
2     KWin - the KDE window manager
3     This file is part of the KDE project.
4 
5     SPDX-FileCopyrightText: 2008 Lubos Lunak <l.lunak@kde.org>
6 
7     SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 
10 #ifndef KWIN_XRENDERUTILS_H
11 #define KWIN_XRENDERUTILS_H
12 
13 // KWin
14 #include <kwinxrenderutils_export.h>
15 // Qt
16 #include <QExplicitlySharedDataPointer>
17 #include <QRegion>
18 #include <QVector>
19 // XCB
20 #include <xcb/xfixes.h>
21 
22 class QColor;
23 class QPixmap;
24 
25 /** @addtogroup kwineffects */
26 /** @{ */
27 
28 namespace KWin
29 {
30 /**
31  * dumps a QColor into a xcb_render_color_t
32  */
33 KWINXRENDERUTILS_EXPORT xcb_render_color_t preMultiply(const QColor &c, float opacity = 1.0);
34 
35 /** @internal */
36 class KWINXRENDERUTILS_EXPORT XRenderPictureData
37     : public QSharedData
38 {
39 public:
40     explicit XRenderPictureData(xcb_render_picture_t pic = XCB_RENDER_PICTURE_NONE);
41     ~XRenderPictureData();
42     xcb_render_picture_t value();
43 private:
44     xcb_render_picture_t picture;
45     Q_DISABLE_COPY(XRenderPictureData)
46 };
47 
48 /**
49  * @short Wrapper around XRender Picture.
50  *
51  * This class wraps XRender's Picture, providing proper initialization,
52  * convenience constructors and freeing of resources.
53  * It should otherwise act exactly like the Picture type.
54  */
55 class KWINXRENDERUTILS_EXPORT XRenderPicture
56 {
57 public:
58     explicit XRenderPicture(xcb_render_picture_t pic = XCB_RENDER_PICTURE_NONE);
59     explicit XRenderPicture(const QImage &img);
60     XRenderPicture(xcb_pixmap_t pix, int depth);
61     operator xcb_render_picture_t();
62 private:
63     void fromImage(const QImage &img);
64     QExplicitlySharedDataPointer< XRenderPictureData > d;
65 };
66 
67 class KWINXRENDERUTILS_EXPORT XFixesRegion
68 {
69 public:
70     explicit XFixesRegion(const QRegion &region);
71     virtual ~XFixesRegion();
72 
73     operator xcb_xfixes_region_t();
74 private:
75     xcb_xfixes_region_t m_region;
76 };
77 
78 inline
XRenderPictureData(xcb_render_picture_t pic)79 XRenderPictureData::XRenderPictureData(xcb_render_picture_t pic)
80     : picture(pic)
81 {
82 }
83 
84 inline
value()85 xcb_render_picture_t XRenderPictureData::value()
86 {
87     return picture;
88 }
89 
90 inline
XRenderPicture(xcb_render_picture_t pic)91 XRenderPicture::XRenderPicture(xcb_render_picture_t pic)
92     : d(new XRenderPictureData(pic))
93 {
94 }
95 
96 inline
xcb_render_picture_t()97 XRenderPicture::operator xcb_render_picture_t()
98 {
99     return d->value();
100 }
101 
102 inline
xcb_xfixes_region_t()103 XFixesRegion::operator xcb_xfixes_region_t()
104 {
105     return m_region;
106 }
107 
108 /**
109  * Static 1x1 picture used to deliver a black pixel with given opacity (for blending performance)
110  * Call and Use, the PixelPicture will stay, but may change it's opacity meanwhile. It's NOT threadsafe either
111  */
112 KWINXRENDERUTILS_EXPORT XRenderPicture xRenderBlendPicture(double opacity);
113 /**
114  * Creates a 1x1 Picture filled with c
115  */
116 KWINXRENDERUTILS_EXPORT XRenderPicture xRenderFill(const xcb_render_color_t &c);
117 KWINXRENDERUTILS_EXPORT XRenderPicture xRenderFill(const QColor &c);
118 
119 /**
120  * Allows to render a window into a (transparent) pixmap
121  * NOTICE: the result can be queried as xRenderWindowOffscreenTarget()
122  * NOTICE: it may be 0
123  * NOTICE: when done call setXRenderWindowOffscreen(false) to continue normal render process
124  */
125 KWINXRENDERUTILS_EXPORT void setXRenderOffscreen(bool b);
126 
127 /**
128  * Allows to define a persistent effect member as render target
129  * The window (including shadows) is rendered into the top left corner
130  * NOTICE: do NOT call setXRenderOffscreen(true) in addition!
131  * NOTICE: do not forget to xRenderPopTarget once you're done to continue the normal render process
132  */
133 KWINXRENDERUTILS_EXPORT void xRenderPushTarget(XRenderPicture *pic);
134 KWINXRENDERUTILS_EXPORT void xRenderPopTarget();
135 
136 /**
137  * Whether windows are currently rendered into an offscreen target buffer
138  */
139 KWINXRENDERUTILS_EXPORT bool xRenderOffscreen();
140 /**
141  * The offscreen buffer as set by the renderer because of setXRenderWindowOffscreen(true)
142  */
143 KWINXRENDERUTILS_EXPORT xcb_render_picture_t xRenderOffscreenTarget();
144 
145 /**
146  * NOTICE: HANDS OFF!!!
147  * scene_setXRenderWindowOffscreenTarget() is ONLY to be used by the renderer - DO NOT TOUCH!
148  */
149 KWINXRENDERUTILS_EXPORT void scene_setXRenderOffscreenTarget(xcb_render_picture_t pix);
150 /**
151  * scene_xRenderWindowOffscreenTarget() is used by the scene to figure the target set by an effect
152  */
153 KWINXRENDERUTILS_EXPORT XRenderPicture *scene_xRenderOffscreenTarget();
154 
155 namespace XRenderUtils
156 {
157 /**
158  * @internal
159  */
160 KWINXRENDERUTILS_EXPORT void init(xcb_connection_t *connection, xcb_window_t rootWindow);
161 
162 /**
163  * Returns the Xrender format that corresponds to the given visual ID.
164  */
165 KWINXRENDERUTILS_EXPORT xcb_render_pictformat_t findPictFormat(xcb_visualid_t visual);
166 
167 /**
168  * Returns the xcb_render_directformat_t for the given Xrender format.
169  */
170 KWINXRENDERUTILS_EXPORT const xcb_render_directformat_t *findPictFormatInfo(xcb_render_pictformat_t format);
171 
172 /**
173  * @internal
174  */
175 KWINXRENDERUTILS_EXPORT void cleanup();
176 
177 } // namespace XRenderUtils
178 
179 } // namespace KWin
180 
181 /** @} */
182 
183 #endif
184