1/********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5Copyright (C) 2011 Martin Gräßlin <mgraesslin@kde.org>
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19*********************************************************************/
20#ifndef KWIN_SHADOW_H
21#define KWIN_SHADOW_H
22
23#include <QObject>
24#include <QtGui/QPixmap>
25#include <kwineffects.h>
26#include <qvarlengtharray.h>
27
28namespace KWin {
29
30class Toplevel;
31
32/**
33 * @short Class representing a Window's Shadow to be rendered by the Compositor.
34 *
35 * This class holds all information about the Shadow to be rendered together with the
36 * window during the Compositing stage. The Shadow consists of several pixmaps and offsets.
37 * For a complete description please refer to http://community.kde.org/KWin/Shadow
38 *
39 * To create a Shadow instance use the static factory method @link createShadow which will
40 * create an instance for the currently used Compositing Backend. It will read the X11 Property
41 * and create the Shadow and all required data (such as WindowQuads). If there is no Shadow
42 * defined for the Toplevel the factory method returns @c NULL.
43 *
44 * @author Martin Gräßlin <mgraesslin@kde.org>
45 * @todo React on Toplevel size changes.
46 **/
47class Shadow : public QObject
48{
49 Q_OBJECT
50public:
51 virtual ~Shadow();
52
53 /**
54 * @return Region of the shadow.
55 **/
56 const QRegion &shadowRegion() const {
57 return m_shadowRegion;
58 };
59 /**
60 * @return Cached Shadow Quads
61 **/
62 const WindowQuadList &shadowQuads() const {
63 return m_shadowQuads;
64 };
65 WindowQuadList &shadowQuads() {
66 return m_shadowQuads;
67 };
68
69 /**
70 * This method updates the Shadow when the property has been changed.
71 * It is the responsibility of the owner of the Shadow to call this method
72 * whenever the owner receives a PropertyNotify event.
73 * This method will invoke a re-read of the Property. In case the Property has
74 * been withdrawn the method returns @c false. In that case the owner should
75 * delete the Shadow.
76 * @returns @c true when the shadow has been updated, @c false if the property is not set anymore.
77 **/
78 virtual bool updateShadow();
79
80 /**
81 * Factory Method to create the shadow from the property.
82 * This method takes care of creating an instance of the
83 * Shadow class for the current Compositing Backend.
84 *
85 * If there is no shadow defined for @p toplevel this method
86 * will return @c NULL.
87 * @param toplevel The Toplevel for which the shadow should be created
88 * @return Created Shadow or @c NULL in case there is no shadow defined.
89 **/
90 static Shadow *createShadow(Toplevel *toplevel);
91
92 /**
93 * Reparents the shadow to @p toplevel.
94 * Used when a window is deleted.
95 * @param toplevel The new parent
96 **/
97 void setToplevel(Toplevel *toplevel);
98
99public Q_SLOTS:
100 void geometryChanged();
101
102protected:
103 Shadow(Toplevel *toplevel);
104 enum ShadowElements {
105 ShadowElementTop,
106 ShadowElementTopRight,
107 ShadowElementRight,
108 ShadowElementBottomRight,
109 ShadowElementBottom,
110 ShadowElementBottomLeft,
111 ShadowElementLeft,
112 ShadowElementTopLeft,
113 ShadowElementsCount
114 };
115
116 inline const QPixmap &shadowPixmap(ShadowElements element) const {
117 return m_shadowElements[element];
118 };
119
120 int topOffset() const {
121 return m_topOffset;
122 };
123 int rightOffset() const {
124 return m_rightOffset;
125 };
126 int bottomOffset() const {
127 return m_bottomOffset;
128 };
129 int leftOffset() const {
130 return m_leftOffset;
131 };
132 virtual void buildQuads();
133 void updateShadowRegion();
134 Toplevel *topLevel() {
135 return m_topLevel;
136 };
137 void setShadowRegion(const QRegion &region) {
138 m_shadowRegion = region;
139 };
140 virtual bool prepareBackend() = 0;
141 WindowQuadList m_shadowQuads;
142
143private:
144 static QVector<long> readX11ShadowProperty(WId id);
145 bool init(const QVector<long> &data);
146 Toplevel *m_topLevel;
147 // shadow pixmaps
148 QPixmap m_shadowElements[ShadowElementsCount];
149 // shadow offsets
150 int m_topOffset;
151 int m_rightOffset;
152 int m_bottomOffset;
153 int m_leftOffset;
154 // caches
155 QRegion m_shadowRegion;
156 QSize m_cachedSize;
157};
158
159}
160
161#endif // KWIN_SHADOW_H
162