source: trunk/src/gui/painting/qwindowsurface_s60.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 7.7 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <qglobal.h> // for Q_WS_WIN define (non-PCH)
43
44#include <QtGui/qpaintdevice.h>
45#include <private/qwidget_p.h>
46#include <private/qwindowsurface_s60_p.h>
47#include <private/qpixmap_s60_p.h>
48#include <private/qt_s60_p.h>
49#include <private/qapplication_p.h>
50#include <private/qdrawhelper_p.h>
51
52#ifdef QT_GRAPHICSSYSTEM_RUNTIME
53#include <private/qgraphicssystem_runtime_p.h>
54#endif
55
56QT_BEGIN_NAMESPACE
57
58struct QS60WindowSurfacePrivate
59{
60 QPixmap device;
61 QList<QImage*> bufferImages;
62};
63
64TDisplayMode displayMode(bool opaque)
65{
66
67 TDisplayMode mode = S60->screenDevice()->DisplayMode();
68 if (opaque) {
69 mode = EColor16MU;
70 } else {
71 if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3)
72 mode = Q_SYMBIAN_ECOLOR16MAP; // Symbian^3 WServ has support for ARGB32_PRE
73 else
74 mode = EColor16MA; // Symbian prior to Symbian^3 sw accelerates EColor16MA
75 }
76 return mode;
77}
78
79QS60WindowSurface::QS60WindowSurface(QWidget* widget)
80 : QWindowSurface(widget), d_ptr(new QS60WindowSurfacePrivate)
81{
82 TDisplayMode mode = displayMode(qt_widget_private(widget)->isOpaque);
83 // We create empty CFbsBitmap here -> it will be resized in setGeometry
84 CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); // CBase derived object needs check on new
85 qt_symbian_throwIfError( bitmap->Create( TSize(0, 0), mode ) );
86
87 QS60PixmapData *data = new QS60PixmapData(QPixmapData::PixmapType);
88 if (data) {
89 data->fromSymbianBitmap(bitmap, true);
90 d_ptr->device = QPixmap(data);
91 }
92
93 setStaticContentsSupport(true);
94}
95
96QS60WindowSurface::~QS60WindowSurface()
97{
98#if defined(QT_GRAPHICSSYSTEM_RUNTIME) && defined(Q_SYMBIAN_SUPPORTS_SURFACES)
99 if(QApplicationPrivate::runtime_graphics_system) {
100 QRuntimeGraphicsSystem *runtimeGraphicsSystem =
101 static_cast<QRuntimeGraphicsSystem*>(QApplicationPrivate::graphics_system);
102 if(runtimeGraphicsSystem->graphicsSystemName() == QLatin1String("openvg")) {
103
104 // Graphics system has been switched from raster to openvg.
105 // Issue empty redraw to clear the UI surface
106
107 QWidget *w = window();
108 if (w->testAttribute(Qt::WA_WState_Created)) {
109 RWindow *const window = static_cast<RWindow *>(w->winId()->DrawableWindow());
110 window->BeginRedraw();
111 window->EndRedraw();
112 }
113 }
114 }
115#endif
116
117 delete d_ptr;
118}
119
120void QS60WindowSurface::beginPaint(const QRegion &rgn)
121{
122#ifdef Q_SYMBIAN_SUPPORTS_SURFACES
123 S60->wsSession().Finish();
124#endif
125
126 if (!qt_widget_private(window())->isOpaque) {
127 QS60PixmapData *pixmapData = static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data());
128
129 TDisplayMode mode = displayMode(false);
130 if (pixmapData->cfbsBitmap->DisplayMode() != mode)
131 pixmapData->convertToDisplayMode(mode);
132
133 pixmapData->beginDataAccess();
134
135 QPainter p(&pixmapData->image);
136 p.setCompositionMode(QPainter::CompositionMode_Source);
137 const QVector<QRect> rects = rgn.rects();
138 const QColor blank = Qt::transparent;
139 for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
140 p.fillRect(*it, blank);
141 }
142
143 pixmapData->endDataAccess();
144 }
145}
146
147void QS60WindowSurface::endPaint(const QRegion &)
148{
149 qDeleteAll(d_ptr->bufferImages);
150 d_ptr->bufferImages.clear();
151}
152
153QImage* QS60WindowSurface::buffer(const QWidget *widget)
154{
155 if (widget->window() != window())
156 return 0;
157
158 QPaintDevice *pdev = paintDevice();
159 if (!pdev)
160 return 0;
161
162 const QPoint off = offset(widget);
163 QImage *img = &(static_cast<QS60PixmapData *>(d_ptr->device.data_ptr().data())->image);
164
165 QRect rect(off, widget->size());
166 rect &= QRect(QPoint(), img->size());
167
168 if (rect.isEmpty())
169 return 0;
170
171 img = new QImage(img->scanLine(rect.y()) + rect.x() * img->depth() / 8,
172 rect.width(), rect.height(),
173 img->bytesPerLine(), img->format());
174 d_ptr->bufferImages.append(img);
175
176 return img;
177}
178
179void QS60WindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &)
180{
181 QWidget *window = widget->window();
182 Q_ASSERT(window);
183 QTLWExtra *topExtra = window->d_func()->maybeTopData();
184 Q_ASSERT(topExtra);
185 QRect qr = region.boundingRect();
186 if (!topExtra->inExpose) {
187 topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again
188 TRect tr = qt_QRect2TRect(qr);
189 widget->winId()->DrawNow(tr);
190 topExtra->inExpose = false;
191 } else {
192 // This handles the case when syncBackingStore updates content outside of the
193 // original drawing rectangle. This might happen if there are pending update()
194 // events at the same time as we get a Draw() from Symbian.
195 QRect drawRect = qt_TRect2QRect(widget->winId()->DrawableWindow()->GetDrawRect());
196 if (!drawRect.contains(qr))
197 widget->winId()->DrawDeferred();
198 }
199}
200
201bool QS60WindowSurface::scroll(const QRegion &area, int dx, int dy)
202{
203 QRect rect = area.boundingRect();
204
205 if (dx == 0 && dy == 0)
206 return false;
207
208 if (d_ptr->device.isNull())
209 return false;
210
211 QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data());
212 data->scroll(dx, dy, rect);
213
214 return true;
215}
216
217QPaintDevice* QS60WindowSurface::paintDevice()
218{
219 return &d_ptr->device;
220}
221
222void QS60WindowSurface::setGeometry(const QRect& rect)
223{
224 if (rect == geometry())
225 return;
226
227 QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data());
228 data->resize(rect.width(), rect.height());
229
230 QWindowSurface::setGeometry(rect);
231}
232
233CFbsBitmap* QS60WindowSurface::symbianBitmap() const
234{
235 QS60PixmapData *data = static_cast<QS60PixmapData*>(d_ptr->device.data_ptr().data());
236 return data->cfbsBitmap;
237}
238
239QT_END_NAMESPACE
240
Note: See TracBrowser for help on using the repository browser.