0
|
1 |
/****************************************************************************
|
|
2 |
**
|
|
3 |
** Copyright (C) 2009 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 |
** No Commercial Usage
|
|
11 |
** This file contains pre-release code and may not be distributed.
|
|
12 |
** You may use this file in accordance with the terms and conditions
|
|
13 |
** contained in the Technology Preview License Agreement accompanying
|
|
14 |
** this package.
|
|
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 |
** If you have questions regarding the use of this file, please contact
|
|
29 |
** Nokia at qt-info@nokia.com.
|
|
30 |
**
|
|
31 |
**
|
|
32 |
**
|
|
33 |
**
|
|
34 |
**
|
|
35 |
**
|
|
36 |
**
|
|
37 |
**
|
|
38 |
** $QT_END_LICENSE$
|
|
39 |
**
|
|
40 |
****************************************************************************/
|
|
41 |
|
|
42 |
#include "qscreentransformed_qws.h"
|
|
43 |
|
|
44 |
#ifndef QT_NO_QWS_TRANSFORMED
|
|
45 |
#include <qscreendriverfactory_qws.h>
|
|
46 |
#include <qvector.h>
|
|
47 |
#include <private/qpainter_p.h>
|
|
48 |
#include <private/qmemrotate_p.h>
|
|
49 |
#include <qmatrix.h>
|
|
50 |
|
|
51 |
#include <unistd.h>
|
|
52 |
#include <sys/ioctl.h>
|
|
53 |
#include <sys/types.h>
|
|
54 |
#include <sys/stat.h>
|
|
55 |
#include <sys/mman.h>
|
|
56 |
#include <fcntl.h>
|
|
57 |
#include <errno.h>
|
|
58 |
|
|
59 |
#include <qwindowsystem_qws.h>
|
|
60 |
#include <qwsdisplay_qws.h>
|
|
61 |
|
|
62 |
QT_BEGIN_NAMESPACE
|
|
63 |
|
|
64 |
//#define QT_REGION_DEBUG
|
|
65 |
|
|
66 |
#ifdef QT_REGION_DEBUG
|
|
67 |
#include <QDebug>
|
|
68 |
#endif
|
|
69 |
|
|
70 |
class QTransformedScreenPrivate
|
|
71 |
{
|
|
72 |
public:
|
|
73 |
QTransformedScreenPrivate(QTransformedScreen *parent);
|
|
74 |
|
|
75 |
void configure();
|
|
76 |
|
|
77 |
QTransformedScreen::Transformation transformation;
|
|
78 |
#ifdef QT_QWS_DEPTH_GENERIC
|
|
79 |
bool doGenericColors;
|
|
80 |
#endif
|
|
81 |
QTransformedScreen *q;
|
|
82 |
};
|
|
83 |
|
|
84 |
QTransformedScreenPrivate::QTransformedScreenPrivate(QTransformedScreen *parent)
|
|
85 |
: transformation(QTransformedScreen::None),
|
|
86 |
#ifdef QT_QWS_DEPTH_GENERIC
|
|
87 |
doGenericColors(false),
|
|
88 |
#endif
|
|
89 |
q(parent)
|
|
90 |
{
|
|
91 |
}
|
|
92 |
|
|
93 |
extern "C"
|
|
94 |
#ifndef QT_BUILD_GUI_LIB
|
|
95 |
Q_DECL_EXPORT
|
|
96 |
#endif
|
|
97 |
void qws_setScreenTransformation(QScreen *that, int t)
|
|
98 |
{
|
|
99 |
QTransformedScreen *tscreen = static_cast<QTransformedScreen*>(that);
|
|
100 |
tscreen->setTransformation((QTransformedScreen::Transformation)t);
|
|
101 |
}
|
|
102 |
|
|
103 |
// ---------------------------------------------------------------------------
|
|
104 |
// Transformed Screen
|
|
105 |
// ---------------------------------------------------------------------------
|
|
106 |
|
|
107 |
/*!
|
|
108 |
\internal
|
|
109 |
|
|
110 |
\class QTransformedScreen
|
|
111 |
\ingroup qws
|
|
112 |
|
|
113 |
\brief The QTransformedScreen class implements a screen driver for
|
|
114 |
a transformed screen.
|
|
115 |
|
|
116 |
Note that this class is only available in \l{Qt for Embedded Linux}.
|
|
117 |
Custom screen drivers can be added by subclassing the
|
|
118 |
QScreenDriverPlugin class, using the QScreenDriverFactory class to
|
|
119 |
dynamically load the driver into the application, but there should
|
|
120 |
only be one screen object per application.
|
|
121 |
|
|
122 |
Use the QScreen::isTransformed() function to determine if a screen
|
|
123 |
is transformed. The QTransformedScreen class itself provides means
|
|
124 |
of rotating the screen with its setTransformation() function; the
|
|
125 |
transformation() function returns the currently set rotation in
|
|
126 |
terms of the \l Transformation enum (which describes the various
|
|
127 |
available rotation settings). Alternatively, QTransformedScreen
|
|
128 |
provides an implementation of the QScreen::transformOrientation()
|
|
129 |
function, returning the current rotation as an integer value.
|
|
130 |
|
|
131 |
\sa QScreen, QScreenDriverPlugin, {Running Applications}
|
|
132 |
*/
|
|
133 |
|
|
134 |
/*!
|
|
135 |
\enum QTransformedScreen::Transformation
|
|
136 |
|
|
137 |
This enum describes the various rotations a transformed screen can
|
|
138 |
have.
|
|
139 |
|
|
140 |
\value None No rotation
|
|
141 |
\value Rot90 90 degrees rotation
|
|
142 |
\value Rot180 180 degrees rotation
|
|
143 |
\value Rot270 270 degrees rotation
|
|
144 |
*/
|
|
145 |
|
|
146 |
/*!
|
|
147 |
\fn bool QTransformedScreen::isTransformed() const
|
|
148 |
\reimp
|
|
149 |
*/
|
|
150 |
|
|
151 |
/*!
|
|
152 |
Constructs a QTransformedScreen object. The \a displayId argument
|
|
153 |
identifies the Qt for Embedded Linux server to connect to.
|
|
154 |
*/
|
|
155 |
QTransformedScreen::QTransformedScreen(int displayId)
|
|
156 |
: QProxyScreen(displayId, QScreen::TransformedClass)
|
|
157 |
{
|
|
158 |
d_ptr = new QTransformedScreenPrivate(this);
|
|
159 |
d_ptr->transformation = None;
|
|
160 |
|
|
161 |
#ifdef QT_REGION_DEBUG
|
|
162 |
qDebug() << "QTransformedScreen::QTransformedScreen";
|
|
163 |
#endif
|
|
164 |
}
|
|
165 |
|
|
166 |
void QTransformedScreenPrivate::configure()
|
|
167 |
{
|
|
168 |
// ###: works because setTransformation recalculates unconditionally
|
|
169 |
q->setTransformation(transformation);
|
|
170 |
}
|
|
171 |
|
|
172 |
/*!
|
|
173 |
Destroys the QTransformedScreen object.
|
|
174 |
*/
|
|
175 |
QTransformedScreen::~QTransformedScreen()
|
|
176 |
{
|
|
177 |
delete d_ptr;
|
|
178 |
}
|
|
179 |
|
|
180 |
static int getDisplayId(const QString &spec)
|
|
181 |
{
|
|
182 |
QRegExp regexp(QLatin1String(":(\\d+)\\b"));
|
|
183 |
if (regexp.lastIndexIn(spec) != -1) {
|
|
184 |
const QString capture = regexp.cap(1);
|
|
185 |
return capture.toInt();
|
|
186 |
}
|
|
187 |
return 0;
|
|
188 |
}
|
|
189 |
|
|
190 |
static QTransformedScreen::Transformation filterTransformation(QString &spec)
|
|
191 |
{
|
|
192 |
QRegExp regexp(QLatin1String("\\bRot(\\d+):?\\b"), Qt::CaseInsensitive);
|
|
193 |
if (regexp.indexIn(spec) == -1)
|
|
194 |
return QTransformedScreen::None;
|
|
195 |
|
|
196 |
const int degrees = regexp.cap(1).toInt();
|
|
197 |
spec.remove(regexp.pos(0), regexp.matchedLength());
|
|
198 |
|
|
199 |
return static_cast<QTransformedScreen::Transformation>(degrees / 90);
|
|
200 |
}
|
|
201 |
|
|
202 |
/*!
|
|
203 |
\reimp
|
|
204 |
*/
|
|
205 |
bool QTransformedScreen::connect(const QString &displaySpec)
|
|
206 |
{
|
|
207 |
QString dspec = displaySpec.trimmed();
|
|
208 |
if (dspec.startsWith(QLatin1String("Transformed:"), Qt::CaseInsensitive))
|
|
209 |
dspec = dspec.mid(QString::fromLatin1("Transformed:").size());
|
|
210 |
else if (!dspec.compare(QLatin1String("Transformed"), Qt::CaseInsensitive))
|
|
211 |
dspec = QString();
|
|
212 |
|
|
213 |
const QString displayIdSpec = QString::fromLatin1(" :%1").arg(displayId);
|
|
214 |
if (dspec.endsWith(displayIdSpec))
|
|
215 |
dspec = dspec.left(dspec.size() - displayIdSpec.size());
|
|
216 |
|
|
217 |
d_ptr->transformation = filterTransformation(dspec);
|
|
218 |
|
|
219 |
QString driver = dspec;
|
|
220 |
int colon = driver.indexOf(QLatin1Char(':'));
|
|
221 |
if (colon >= 0)
|
|
222 |
driver.truncate(colon);
|
|
223 |
|
|
224 |
if (!QScreenDriverFactory::keys().contains(driver, Qt::CaseInsensitive))
|
|
225 |
if (!dspec.isEmpty())
|
|
226 |
dspec.prepend(QLatin1Char(':'));
|
|
227 |
|
|
228 |
const int id = getDisplayId(dspec);
|
|
229 |
QScreen *s = qt_get_screen(id, dspec.toLatin1().constData());
|
|
230 |
setScreen(s);
|
|
231 |
|
|
232 |
#ifdef QT_QWS_DEPTH_GENERIC
|
|
233 |
d_ptr->doGenericColors = dspec.contains(QLatin1String("genericcolors"));
|
|
234 |
#endif
|
|
235 |
|
|
236 |
d_ptr->configure();
|
|
237 |
|
|
238 |
// XXX
|
|
239 |
qt_screen = this;
|
|
240 |
|
|
241 |
return true;
|
|
242 |
}
|
|
243 |
|
|
244 |
/*!
|
|
245 |
Returns the currently set rotation.
|
|
246 |
|
|
247 |
\sa setTransformation(), QScreen::transformOrientation()
|
|
248 |
*/
|
|
249 |
QTransformedScreen::Transformation QTransformedScreen::transformation() const
|
|
250 |
{
|
|
251 |
return d_ptr->transformation;
|
|
252 |
}
|
|
253 |
|
|
254 |
/*!
|
|
255 |
\reimp
|
|
256 |
*/
|
|
257 |
int QTransformedScreen::transformOrientation() const
|
|
258 |
{
|
|
259 |
return (int)d_ptr->transformation;
|
|
260 |
}
|
|
261 |
|
|
262 |
/*!
|
|
263 |
\reimp
|
|
264 |
*/
|
|
265 |
void QTransformedScreen::exposeRegion(QRegion region, int changing)
|
|
266 |
{
|
|
267 |
if (!data || d_ptr->transformation == None) {
|
|
268 |
QProxyScreen::exposeRegion(region, changing);
|
|
269 |
return;
|
|
270 |
}
|
|
271 |
QScreen::exposeRegion(region, changing);
|
|
272 |
}
|
|
273 |
|
|
274 |
/*!
|
|
275 |
Rotates this screen object according to the specified \a transformation.
|
|
276 |
|
|
277 |
\sa transformation()
|
|
278 |
*/
|
|
279 |
void QTransformedScreen::setTransformation(Transformation transformation)
|
|
280 |
{
|
|
281 |
d_ptr->transformation = transformation;
|
|
282 |
QSize size = mapFromDevice(QSize(dw, dh));
|
|
283 |
w = size.width();
|
|
284 |
h = size.height();
|
|
285 |
|
|
286 |
const QScreen *s = screen();
|
|
287 |
size = mapFromDevice(QSize(s->physicalWidth(), s->physicalHeight()));
|
|
288 |
physWidth = size.width();
|
|
289 |
physHeight = size.height();
|
|
290 |
|
|
291 |
#ifdef QT_REGION_DEBUG
|
|
292 |
qDebug() << "QTransformedScreen::setTransformation" << transformation
|
|
293 |
<< "size" << w << h << "dev size" << dw << dh;
|
|
294 |
#endif
|
|
295 |
|
|
296 |
}
|
|
297 |
|
|
298 |
static inline QRect correctNormalized(const QRect &r) {
|
|
299 |
const int x1 = qMin(r.left(), r.right());
|
|
300 |
const int x2 = qMax(r.left(), r.right());
|
|
301 |
const int y1 = qMin(r.top(), r.bottom());
|
|
302 |
const int y2 = qMax(r.top(), r.bottom());
|
|
303 |
|
|
304 |
return QRect( QPoint(x1,y1), QPoint(x2,y2) );
|
|
305 |
}
|
|
306 |
|
|
307 |
template <class DST, class SRC>
|
|
308 |
static inline void blit90(QScreen *screen, const QImage &image,
|
|
309 |
const QRect &rect, const QPoint &topLeft)
|
|
310 |
{
|
|
311 |
const SRC *src = (const SRC*)(image.scanLine(rect.top())) + rect.left();
|
|
312 |
DST *dest = (DST*)(screen->base() + topLeft.y() * screen->linestep())
|
|
313 |
+ topLeft.x();
|
|
314 |
qt_memrotate90(src, rect.width(), rect.height(), image.bytesPerLine(),
|
|
315 |
dest, screen->linestep());
|
|
316 |
}
|
|
317 |
|
|
318 |
template <class DST, class SRC>
|
|
319 |
static inline void blit180(QScreen *screen, const QImage &image,
|
|
320 |
const QRect &rect, const QPoint &topLeft)
|
|
321 |
{
|
|
322 |
const SRC *src = (const SRC*)(image.scanLine(rect.top())) + rect.left();
|
|
323 |
DST *dest = (DST*)(screen->base() + topLeft.y() * screen->linestep())
|
|
324 |
+ topLeft.x();
|
|
325 |
qt_memrotate180(src, rect.width(), rect.height(), image.bytesPerLine(),
|
|
326 |
dest, screen->linestep());
|
|
327 |
}
|
|
328 |
|
|
329 |
template <class DST, class SRC>
|
|
330 |
static inline void blit270(QScreen *screen, const QImage &image,
|
|
331 |
const QRect &rect, const QPoint &topLeft)
|
|
332 |
{
|
|
333 |
const SRC *src = (const SRC *)(image.scanLine(rect.top())) + rect.left();
|
|
334 |
DST *dest = (DST*)(screen->base() + topLeft.y() * screen->linestep())
|
|
335 |
+ topLeft.x();
|
|
336 |
qt_memrotate270(src, rect.width(), rect.height(), image.bytesPerLine(),
|
|
337 |
dest, screen->linestep());
|
|
338 |
}
|
|
339 |
|
|
340 |
typedef void (*BlitFunc)(QScreen *, const QImage &, const QRect &, const QPoint &);
|
|
341 |
|
|
342 |
#define SET_BLIT_FUNC(dst, src, rotation, func) \
|
|
343 |
do { \
|
|
344 |
switch (rotation) { \
|
|
345 |
case Rot90: \
|
|
346 |
func = blit90<dst, src>; \
|
|
347 |
break; \
|
|
348 |
case Rot180: \
|
|
349 |
func = blit180<dst, src>; \
|
|
350 |
break; \
|
|
351 |
case Rot270: \
|
|
352 |
func = blit270<dst, src>; \
|
|
353 |
break; \
|
|
354 |
default: \
|
|
355 |
break; \
|
|
356 |
} \
|
|
357 |
} while (0)
|
|
358 |
|
|
359 |
/*!
|
|
360 |
\reimp
|
|
361 |
*/
|
|
362 |
void QTransformedScreen::blit(const QImage &image, const QPoint &topLeft,
|
|
363 |
const QRegion ®ion)
|
|
364 |
{
|
|
365 |
const Transformation trans = d_ptr->transformation;
|
|
366 |
if (trans == None) {
|
|
367 |
QProxyScreen::blit(image, topLeft, region);
|
|
368 |
return;
|
|
369 |
}
|
|
370 |
|
|
371 |
const QVector<QRect> rects = region.rects();
|
|
372 |
const QRect bound = QRect(0, 0, QScreen::w, QScreen::h)
|
|
373 |
& QRect(topLeft, image.size());
|
|
374 |
|
|
375 |
BlitFunc func = 0;
|
|
376 |
#ifdef QT_QWS_DEPTH_GENERIC
|
|
377 |
if (d_ptr->doGenericColors && depth() == 16) {
|
|
378 |
if (image.depth() == 16)
|
|
379 |
SET_BLIT_FUNC(qrgb_generic16, quint16, trans, func);
|
|
380 |
else
|
|
381 |
SET_BLIT_FUNC(qrgb_generic16, quint32, trans, func);
|
|
382 |
} else
|
|
383 |
#endif
|
|
384 |
switch (depth()) {
|
|
385 |
#ifdef QT_QWS_DEPTH_32
|
|
386 |
case 32:
|
|
387 |
#ifdef QT_QWS_DEPTH_16
|
|
388 |
if (image.depth() == 16)
|
|
389 |
SET_BLIT_FUNC(quint32, quint16, trans, func);
|
|
390 |
else
|
|
391 |
#endif
|
|
392 |
SET_BLIT_FUNC(quint32, quint32, trans, func);
|
|
393 |
break;
|
|
394 |
#endif
|
|
395 |
#if defined(QT_QWS_DEPTH_24) || defined(QT_QWS_DEPTH18)
|
|
396 |
case 24:
|
|
397 |
case 18:
|
|
398 |
SET_BLIT_FUNC(quint24, quint24, trans, func);
|
|
399 |
break;
|
|
400 |
#endif
|
|
401 |
#if defined(QT_QWS_DEPTH_16) || defined(QT_QWS_DEPTH_15) || defined(QT_QWS_DEPTH_12)
|
|
402 |
case 16:
|
|
403 |
#if defined QT_QWS_ROTATE_BGR
|
|
404 |
if (pixelType() == BGRPixel && image.depth() == 16) {
|
|
405 |
SET_BLIT_FUNC(qbgr565, quint16, trans, func);
|
|
406 |
break;
|
|
407 |
} //fall-through here!!!
|
|
408 |
#endif
|
|
409 |
case 15:
|
|
410 |
#if defined QT_QWS_ROTATE_BGR
|
|
411 |
if (pixelType() == BGRPixel && image.format() == QImage::Format_RGB555) {
|
|
412 |
SET_BLIT_FUNC(qbgr555, qrgb555, trans, func);
|
|
413 |
break;
|
|
414 |
} //fall-through here!!!
|
|
415 |
#endif
|
|
416 |
case 12:
|
|
417 |
if (image.depth() == 16)
|
|
418 |
SET_BLIT_FUNC(quint16, quint16, trans, func);
|
|
419 |
else
|
|
420 |
SET_BLIT_FUNC(quint16, quint32, trans, func);
|
|
421 |
break;
|
|
422 |
#endif
|
|
423 |
#ifdef QT_QWS_DEPTH_8
|
|
424 |
case 8:
|
|
425 |
if (image.format() == QImage::Format_RGB444)
|
|
426 |
SET_BLIT_FUNC(quint8, qrgb444, trans, func);
|
|
427 |
else if (image.depth() == 16)
|
|
428 |
SET_BLIT_FUNC(quint8, quint16, trans, func);
|
|
429 |
else
|
|
430 |
SET_BLIT_FUNC(quint8, quint32, trans, func);
|
|
431 |
break;
|
|
432 |
#endif
|
|
433 |
default:
|
|
434 |
return;
|
|
435 |
}
|
|
436 |
if (!func)
|
|
437 |
return;
|
|
438 |
|
|
439 |
QWSDisplay::grab();
|
|
440 |
for (int i = 0; i < rects.size(); ++i) {
|
|
441 |
const QRect r = rects.at(i) & bound;
|
|
442 |
|
|
443 |
QPoint dst;
|
|
444 |
switch (trans) {
|
|
445 |
case Rot90:
|
|
446 |
dst = mapToDevice(r.topRight(), QSize(w, h));
|
|
447 |
break;
|
|
448 |
case Rot180:
|
|
449 |
dst = mapToDevice(r.bottomRight(), QSize(w, h));
|
|
450 |
break;
|
|
451 |
case Rot270:
|
|
452 |
dst = mapToDevice(r.bottomLeft(), QSize(w, h));
|
|
453 |
break;
|
|
454 |
default:
|
|
455 |
break;
|
|
456 |
}
|
|
457 |
func(this, image, r.translated(-topLeft), dst);
|
|
458 |
}
|
|
459 |
QWSDisplay::ungrab();
|
|
460 |
|
|
461 |
}
|
|
462 |
|
|
463 |
/*!
|
|
464 |
\reimp
|
|
465 |
*/
|
|
466 |
void QTransformedScreen::solidFill(const QColor &color, const QRegion ®ion)
|
|
467 |
{
|
|
468 |
const QRegion tr = mapToDevice(region, QSize(w,h));
|
|
469 |
|
|
470 |
Q_ASSERT(tr.boundingRect() == mapToDevice(region.boundingRect(), QSize(w,h)));
|
|
471 |
|
|
472 |
#ifdef QT_REGION_DEBUG
|
|
473 |
qDebug() << "QTransformedScreen::solidFill region" << region << "transformed" << tr;
|
|
474 |
#endif
|
|
475 |
QProxyScreen::solidFill(color, tr);
|
|
476 |
}
|
|
477 |
|
|
478 |
/*!
|
|
479 |
\reimp
|
|
480 |
*/
|
|
481 |
QSize QTransformedScreen::mapToDevice(const QSize &s) const
|
|
482 |
{
|
|
483 |
switch (d_ptr->transformation) {
|
|
484 |
case None:
|
|
485 |
case Rot180:
|
|
486 |
break;
|
|
487 |
case Rot90:
|
|
488 |
case Rot270:
|
|
489 |
return QSize(s.height(), s.width());
|
|
490 |
break;
|
|
491 |
}
|
|
492 |
return s;
|
|
493 |
}
|
|
494 |
|
|
495 |
/*!
|
|
496 |
\reimp
|
|
497 |
*/
|
|
498 |
QSize QTransformedScreen::mapFromDevice(const QSize &s) const
|
|
499 |
{
|
|
500 |
switch (d_ptr->transformation) {
|
|
501 |
case None:
|
|
502 |
case Rot180:
|
|
503 |
break;
|
|
504 |
case Rot90:
|
|
505 |
case Rot270:
|
|
506 |
return QSize(s.height(), s.width());
|
|
507 |
break;
|
|
508 |
}
|
|
509 |
return s;
|
|
510 |
}
|
|
511 |
|
|
512 |
/*!
|
|
513 |
\reimp
|
|
514 |
*/
|
|
515 |
QPoint QTransformedScreen::mapToDevice(const QPoint &p, const QSize &s) const
|
|
516 |
{
|
|
517 |
QPoint rp(p);
|
|
518 |
|
|
519 |
switch (d_ptr->transformation) {
|
|
520 |
case None:
|
|
521 |
break;
|
|
522 |
case Rot90:
|
|
523 |
rp.setX(p.y());
|
|
524 |
rp.setY(s.width() - p.x() - 1);
|
|
525 |
break;
|
|
526 |
case Rot180:
|
|
527 |
rp.setX(s.width() - p.x() - 1);
|
|
528 |
rp.setY(s.height() - p.y() - 1);
|
|
529 |
break;
|
|
530 |
case Rot270:
|
|
531 |
rp.setX(s.height() - p.y() - 1);
|
|
532 |
rp.setY(p.x());
|
|
533 |
break;
|
|
534 |
}
|
|
535 |
|
|
536 |
return rp;
|
|
537 |
}
|
|
538 |
|
|
539 |
/*!
|
|
540 |
\reimp
|
|
541 |
*/
|
|
542 |
QPoint QTransformedScreen::mapFromDevice(const QPoint &p, const QSize &s) const
|
|
543 |
{
|
|
544 |
QPoint rp(p);
|
|
545 |
|
|
546 |
switch (d_ptr->transformation) {
|
|
547 |
case None:
|
|
548 |
break;
|
|
549 |
case Rot90:
|
|
550 |
rp.setX(s.height() - p.y() - 1);
|
|
551 |
rp.setY(p.x());
|
|
552 |
break;
|
|
553 |
case Rot180:
|
|
554 |
rp.setX(s.width() - p.x() - 1);
|
|
555 |
rp.setY(s.height() - p.y() - 1);
|
|
556 |
break;
|
|
557 |
case Rot270:
|
|
558 |
rp.setX(p.y());
|
|
559 |
rp.setY(s.width() - p.x() - 1);
|
|
560 |
break;
|
|
561 |
}
|
|
562 |
|
|
563 |
return rp;
|
|
564 |
}
|
|
565 |
|
|
566 |
/*!
|
|
567 |
\reimp
|
|
568 |
*/
|
|
569 |
QRect QTransformedScreen::mapToDevice(const QRect &r, const QSize &s) const
|
|
570 |
{
|
|
571 |
if (r.isNull())
|
|
572 |
return QRect();
|
|
573 |
|
|
574 |
QRect tr;
|
|
575 |
switch (d_ptr->transformation) {
|
|
576 |
case None:
|
|
577 |
tr = r;
|
|
578 |
break;
|
|
579 |
case Rot90:
|
|
580 |
tr.setCoords(r.y(), s.width() - r.x() - 1,
|
|
581 |
r.bottom(), s.width() - r.right() - 1);
|
|
582 |
break;
|
|
583 |
case Rot180:
|
|
584 |
tr.setCoords(s.width() - r.x() - 1, s.height() - r.y() - 1,
|
|
585 |
s.width() - r.right() - 1, s.height() - r.bottom() - 1);
|
|
586 |
break;
|
|
587 |
case Rot270:
|
|
588 |
tr.setCoords(s.height() - r.y() - 1, r.x(),
|
|
589 |
s.height() - r.bottom() - 1, r.right());
|
|
590 |
break;
|
|
591 |
}
|
|
592 |
|
|
593 |
return correctNormalized(tr);
|
|
594 |
}
|
|
595 |
|
|
596 |
/*!
|
|
597 |
\reimp
|
|
598 |
*/
|
|
599 |
QRect QTransformedScreen::mapFromDevice(const QRect &r, const QSize &s) const
|
|
600 |
{
|
|
601 |
if (r.isNull())
|
|
602 |
return QRect();
|
|
603 |
|
|
604 |
QRect tr;
|
|
605 |
switch (d_ptr->transformation) {
|
|
606 |
case None:
|
|
607 |
tr = r;
|
|
608 |
break;
|
|
609 |
case Rot90:
|
|
610 |
tr.setCoords(s.height() - r.y() - 1, r.x(),
|
|
611 |
s.height() - r.bottom() - 1, r.right());
|
|
612 |
break;
|
|
613 |
case Rot180:
|
|
614 |
tr.setCoords(s.width() - r.x() - 1, s.height() - r.y() - 1,
|
|
615 |
s.width() - r.right() - 1, s.height() - r.bottom() - 1);
|
|
616 |
break;
|
|
617 |
case Rot270:
|
|
618 |
tr.setCoords(r.y(), s.width() - r.x() - 1,
|
|
619 |
r.bottom(), s.width() - r.right() - 1);
|
|
620 |
break;
|
|
621 |
}
|
|
622 |
|
|
623 |
return correctNormalized(tr);
|
|
624 |
}
|
|
625 |
|
|
626 |
/*!
|
|
627 |
\reimp
|
|
628 |
*/
|
|
629 |
QRegion QTransformedScreen::mapToDevice(const QRegion &rgn, const QSize &s) const
|
|
630 |
{
|
|
631 |
if (d_ptr->transformation == None)
|
|
632 |
return QProxyScreen::mapToDevice(rgn, s);
|
|
633 |
|
|
634 |
#ifdef QT_REGION_DEBUG
|
|
635 |
qDebug() << "mapToDevice size" << s << "rgn: " << rgn;
|
|
636 |
#endif
|
|
637 |
QRect tr;
|
|
638 |
QRegion trgn;
|
|
639 |
QVector<QRect> a = rgn.rects();
|
|
640 |
const QRect *r = a.data();
|
|
641 |
|
|
642 |
int w = s.width();
|
|
643 |
int h = s.height();
|
|
644 |
int size = a.size();
|
|
645 |
|
|
646 |
switch (d_ptr->transformation) {
|
|
647 |
case None:
|
|
648 |
break;
|
|
649 |
case Rot90:
|
|
650 |
for (int i = 0; i < size; i++, r++) {
|
|
651 |
tr.setCoords(r->y(), w - r->x() - 1,
|
|
652 |
r->bottom(), w - r->right() - 1);
|
|
653 |
trgn |= correctNormalized(tr);
|
|
654 |
}
|
|
655 |
break;
|
|
656 |
case Rot180:
|
|
657 |
for (int i = 0; i < size; i++, r++) {
|
|
658 |
tr.setCoords(w - r->x() - 1, h - r->y() - 1,
|
|
659 |
w - r->right() - 1, h - r->bottom() - 1);
|
|
660 |
trgn |= correctNormalized(tr);
|
|
661 |
}
|
|
662 |
break;
|
|
663 |
case Rot270:
|
|
664 |
for (int i = 0; i < size; i++, r++) {
|
|
665 |
tr.setCoords(h - r->y() - 1, r->x(),
|
|
666 |
h - r->bottom() - 1, r->right());
|
|
667 |
trgn |= correctNormalized(tr);
|
|
668 |
}
|
|
669 |
break;
|
|
670 |
}
|
|
671 |
#ifdef QT_REGION_DEBUG
|
|
672 |
qDebug() << "mapToDevice trgn: " << trgn;
|
|
673 |
#endif
|
|
674 |
return trgn;
|
|
675 |
}
|
|
676 |
|
|
677 |
/*!
|
|
678 |
\reimp
|
|
679 |
*/
|
|
680 |
QRegion QTransformedScreen::mapFromDevice(const QRegion &rgn, const QSize &s) const
|
|
681 |
{
|
|
682 |
if (d_ptr->transformation == None)
|
|
683 |
return QProxyScreen::mapFromDevice(rgn, s);
|
|
684 |
|
|
685 |
#ifdef QT_REGION_DEBUG
|
|
686 |
qDebug() << "fromDevice: realRegion count: " << rgn.rects().size() << " isEmpty? " << rgn.isEmpty() << " bounds:" << rgn.boundingRect();
|
|
687 |
#endif
|
|
688 |
QRect tr;
|
|
689 |
QRegion trgn;
|
|
690 |
QVector<QRect> a = rgn.rects();
|
|
691 |
const QRect *r = a.data();
|
|
692 |
|
|
693 |
int w = s.width();
|
|
694 |
int h = s.height();
|
|
695 |
int size = a.size();
|
|
696 |
|
|
697 |
switch (d_ptr->transformation) {
|
|
698 |
case None:
|
|
699 |
break;
|
|
700 |
case Rot90:
|
|
701 |
for (int i = 0; i < size; i++, r++) {
|
|
702 |
tr.setCoords(h - r->y() - 1, r->x(),
|
|
703 |
h - r->bottom() - 1, r->right());
|
|
704 |
trgn |= correctNormalized(tr);
|
|
705 |
}
|
|
706 |
break;
|
|
707 |
case Rot180:
|
|
708 |
for (int i = 0; i < size; i++, r++) {
|
|
709 |
tr.setCoords(w - r->x() - 1, h - r->y() - 1,
|
|
710 |
w - r->right() - 1, h - r->bottom() - 1);
|
|
711 |
trgn |= correctNormalized(tr);
|
|
712 |
}
|
|
713 |
break;
|
|
714 |
case Rot270:
|
|
715 |
for (int i = 0; i < size; i++, r++) {
|
|
716 |
tr.setCoords(r->y(), w - r->x() - 1,
|
|
717 |
r->bottom(), w - r->right() - 1);
|
|
718 |
trgn |= correctNormalized(tr);
|
|
719 |
}
|
|
720 |
break;
|
|
721 |
}
|
|
722 |
#ifdef QT_REGION_DEBUG
|
|
723 |
qDebug() << "fromDevice: transRegion count: " << trgn.rects().size() << " isEmpty? " << trgn.isEmpty() << " bounds:" << trgn.boundingRect();
|
|
724 |
#endif
|
|
725 |
return trgn;
|
|
726 |
}
|
|
727 |
|
|
728 |
/*!
|
|
729 |
\reimp
|
|
730 |
*/
|
|
731 |
void QTransformedScreen::setDirty(const QRect& rect)
|
|
732 |
{
|
|
733 |
const QRect r = mapToDevice(rect, QSize(width(), height()));
|
|
734 |
QProxyScreen::setDirty(r);
|
|
735 |
}
|
|
736 |
|
|
737 |
/*!
|
|
738 |
\reimp
|
|
739 |
*/
|
|
740 |
QRegion QTransformedScreen::region() const
|
|
741 |
{
|
|
742 |
QRegion deviceRegion = QProxyScreen::region();
|
|
743 |
return mapFromDevice(deviceRegion, QSize(deviceWidth(), deviceHeight()));
|
|
744 |
}
|
|
745 |
|
|
746 |
QT_END_NAMESPACE
|
|
747 |
|
|
748 |
#endif // QT_NO_QWS_TRANSFORMED
|