1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2015 The Qt Company Ltd. 4 ** Contact: http://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtGui module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see http://www.qt.io/terms-conditions. For further 15 ** information use the contact form at http://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 2.1 or version 3 as published by the Free 20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 ** following information to ensure the GNU Lesser General Public License 23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 ** 26 ** As a special exception, The Qt Company gives you certain additional 27 ** rights. These rights are described in The Qt Company LGPL Exception 28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 ** 30 ** GNU General Public License Usage 31 ** Alternatively, this file may be used under the terms of the GNU 32 ** General Public License version 3.0 as published by the Free Software 33 ** Foundation and appearing in the file LICENSE.GPL included in the 34 ** packaging of this file. Please review the following information to 35 ** ensure the GNU General Public License version 3.0 requirements will be 36 ** met: http://www.gnu.org/copyleft/gpl.html. 37 ** 38 ** $QT_END_LICENSE$ 39 ** 40 ****************************************************************************/ 41 42 #ifndef QBACKINGSTORE_P_H 43 #define QBACKINGSTORE_P_H 44 45 // 46 // W A R N I N G 47 // ------------- 48 // 49 // This file is not part of the Qt API. It exists purely as an 50 // implementation detail. This header file may change from version to 51 // version without notice, or even be removed. 52 // 53 // We mean it. 54 // 55 56 #include <QDebug> 57 #include <QtGui/qwidget.h> 58 #include <private/qwidget_p.h> 59 #include <private/qwindowsurface_p.h> 60 #ifdef Q_WS_QWS 61 #include <private/qwindowsurface_qws_p.h> 62 #endif 63 64 QT_BEGIN_NAMESPACE 65 66 class QWindowSurface; 67 68 struct BeginPaintInfo { BeginPaintInfoBeginPaintInfo69 inline BeginPaintInfo() : wasFlushed(0), nothingToPaint(0), windowSurfaceRecreated(0) {} 70 uint wasFlushed : 1; 71 uint nothingToPaint : 1; 72 uint windowSurfaceRecreated : 1; 73 }; 74 75 class Q_AUTOTEST_EXPORT QWidgetBackingStore 76 { 77 public: 78 QWidgetBackingStore(QWidget *t); 79 ~QWidgetBackingStore(); 80 81 static void showYellowThing(QWidget *widget, const QRegion &rgn, int msec, bool); 82 83 void sync(QWidget *exposedWidget, const QRegion &exposedRegion); 84 void sync(); 85 void flush(QWidget *widget = 0, QWindowSurface *surface = 0); 86 topLevelOffset()87 inline QPoint topLevelOffset() const { return tlwOffset; } 88 surface()89 QWindowSurface *surface() const { return windowSurface; } 90 isDirty()91 inline bool isDirty() const 92 { 93 return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && !hasDirtyFromPreviousSync 94 && !fullUpdatePending 95 #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) 96 && !hasDirtyWindowDecoration() 97 #endif 98 ); 99 } 100 101 // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). 102 void markDirty(const QRegion &rgn, QWidget *widget, bool updateImmediately = false, 103 bool invalidateBuffer = false); 104 void markDirty(const QRect &rect, QWidget *widget, bool updateImmediately = false, 105 bool invalidateBuffer = false); 106 107 private: 108 QWidget *tlw; 109 QRegion dirtyOnScreen; // needsFlush 110 QRegion dirty; // needsRepaint 111 QRegion dirtyFromPreviousSync; 112 QVector<QWidget *> dirtyWidgets; 113 QVector<QWidget *> *dirtyOnScreenWidgets; 114 QList<QWidget *> staticWidgets; 115 QWindowSurface *windowSurface; 116 #ifdef Q_BACKINGSTORE_SUBSURFACES 117 QList<QWindowSurface*> subSurfaces; 118 #endif 119 uint hasDirtyFromPreviousSync : 1; 120 uint fullUpdatePending : 1; 121 122 QPoint tlwOffset; 123 124 static bool flushPaint(QWidget *widget, const QRegion &rgn); 125 static void unflushPaint(QWidget *widget, const QRegion &rgn); 126 127 bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget); 128 void releaseBuffer(); 129 130 void beginPaint(QRegion &toClean, QWidget *widget, QWindowSurface *windowSurface, 131 BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates = true); 132 void endPaint(const QRegion &cleaned, QWindowSurface *windowSurface, BeginPaintInfo *beginPaintInfo); 133 134 QRegion dirtyRegion(QWidget *widget = 0) const; 135 QRegion staticContents(QWidget *widget = 0, const QRect &withinClipRect = QRect()) const; 136 137 void markDirtyOnScreen(const QRegion &dirtyOnScreen, QWidget *widget, const QPoint &topLevelOffset); 138 139 void removeDirtyWidget(QWidget *w); 140 141 #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) 142 bool hasDirtyWindowDecoration() const; 143 void paintWindowDecoration(); 144 #endif 145 void updateLists(QWidget *widget); 146 addDirtyWidget(QWidget * widget,const QRegion & rgn)147 inline void addDirtyWidget(QWidget *widget, const QRegion &rgn) 148 { 149 if (widget && !widget->d_func()->inDirtyList && !widget->data->in_destructor) { 150 QWidgetPrivate *widgetPrivate = widget->d_func(); 151 #ifndef QT_NO_GRAPHICSEFFECT 152 if (widgetPrivate->graphicsEffect) 153 widgetPrivate->dirty = widgetPrivate->effectiveRectFor(rgn.boundingRect()); 154 else 155 #endif //QT_NO_GRAPHICSEFFECT 156 widgetPrivate->dirty = rgn; 157 dirtyWidgets.append(widget); 158 widgetPrivate->inDirtyList = true; 159 } 160 } 161 dirtyWidgetsRemoveAll(QWidget * widget)162 inline void dirtyWidgetsRemoveAll(QWidget *widget) 163 { 164 int i = 0; 165 while (i < dirtyWidgets.size()) { 166 if (dirtyWidgets.at(i) == widget) 167 dirtyWidgets.remove(i); 168 else 169 ++i; 170 } 171 } 172 addStaticWidget(QWidget * widget)173 inline void addStaticWidget(QWidget *widget) 174 { 175 if (!widget) 176 return; 177 178 Q_ASSERT(widget->testAttribute(Qt::WA_StaticContents)); 179 if (!staticWidgets.contains(widget)) 180 staticWidgets.append(widget); 181 } 182 removeStaticWidget(QWidget * widget)183 inline void removeStaticWidget(QWidget *widget) 184 { staticWidgets.removeAll(widget); } 185 186 // Move the reparented widget and all its static children from this backing store 187 // to the new backing store if reparented into another top-level / backing store. moveStaticWidgets(QWidget * reparented)188 inline void moveStaticWidgets(QWidget *reparented) 189 { 190 Q_ASSERT(reparented); 191 QWidgetBackingStore *newBs = reparented->d_func()->maybeBackingStore(); 192 if (newBs == this) 193 return; 194 195 int i = 0; 196 while (i < staticWidgets.size()) { 197 QWidget *w = staticWidgets.at(i); 198 if (reparented == w || reparented->isAncestorOf(w)) { 199 staticWidgets.removeAt(i); 200 if (newBs) 201 newBs->addStaticWidget(w); 202 } else { 203 ++i; 204 } 205 } 206 } 207 topLevelRect()208 inline QRect topLevelRect() const 209 { 210 #ifdef Q_WS_QWS 211 return tlw->frameGeometry(); 212 #else 213 return tlw->data->crect; 214 #endif 215 } 216 appendDirtyOnScreenWidget(QWidget * widget)217 inline void appendDirtyOnScreenWidget(QWidget *widget) 218 { 219 if (!widget) 220 return; 221 222 if (!dirtyOnScreenWidgets) { 223 dirtyOnScreenWidgets = new QVector<QWidget *>; 224 dirtyOnScreenWidgets->append(widget); 225 } else if (!dirtyOnScreenWidgets->contains(widget)) { 226 dirtyOnScreenWidgets->append(widget); 227 } 228 } 229 dirtyOnScreenWidgetsRemoveAll(QWidget * widget)230 inline void dirtyOnScreenWidgetsRemoveAll(QWidget *widget) 231 { 232 if (!widget || !dirtyOnScreenWidgets) 233 return; 234 235 int i = 0; 236 while (i < dirtyOnScreenWidgets->size()) { 237 if (dirtyOnScreenWidgets->at(i) == widget) 238 dirtyOnScreenWidgets->remove(i); 239 else 240 ++i; 241 } 242 } 243 resetWidget(QWidget * widget)244 inline void resetWidget(QWidget *widget) 245 { 246 if (widget) { 247 widget->d_func()->inDirtyList = false; 248 widget->d_func()->isScrolled = false; 249 widget->d_func()->isMoved = false; 250 widget->d_func()->dirty = QRegion(); 251 } 252 } 253 updateStaticContentsSize()254 inline void updateStaticContentsSize() 255 { 256 for (int i = 0; i < staticWidgets.size(); ++i) { 257 QWidgetPrivate *wd = staticWidgets.at(i)->d_func(); 258 if (!wd->extra) 259 wd->createExtra(); 260 wd->extra->staticContentsSize = wd->data.crect.size(); 261 } 262 } 263 hasStaticContents()264 inline bool hasStaticContents() const 265 { return !staticWidgets.isEmpty() && windowSurface->hasFeature(QWindowSurface::StaticContents); } 266 267 friend QRegion qt_dirtyRegion(QWidget *); 268 friend class QWidgetPrivate; 269 friend class QWidget; 270 friend class QWSManagerPrivate; 271 friend class QETWidget; 272 friend class QWindowSurface; 273 friend class QWSWindowSurface; 274 }; 275 276 QT_END_NAMESPACE 277 278 #endif // QBACKINGSTORE_P_H 279