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 #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
QTransformedScreenPrivate(QTransformedScreen * parent)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
qws_setScreenTransformation(QScreen * that,int t)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 */
QTransformedScreen(int displayId)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
configure()166 void QTransformedScreenPrivate::configure()
167 {
168 // ###: works because setTransformation recalculates unconditionally
169 q->setTransformation(transformation);
170 }
171
172 /*!
173 Destroys the QTransformedScreen object.
174 */
~QTransformedScreen()175 QTransformedScreen::~QTransformedScreen()
176 {
177 delete d_ptr;
178 }
179
getDisplayId(const QString & spec)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
filterTransformation(QString & spec)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 */
connect(const QString & displaySpec)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 */
transformation() const249 QTransformedScreen::Transformation QTransformedScreen::transformation() const
250 {
251 return d_ptr->transformation;
252 }
253
254 /*!
255 \reimp
256 */
transformOrientation() const257 int QTransformedScreen::transformOrientation() const
258 {
259 return (int)d_ptr->transformation;
260 }
261
262 /*!
263 \reimp
264 */
exposeRegion(QRegion region,int changing)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 */
setTransformation(Transformation transformation)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
correctNormalized(const QRect & r)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>
blit90(QScreen * screen,const QImage & image,const QRect & rect,const QPoint & topLeft)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>
blit180(QScreen * screen,const QImage & image,const QRect & rect,const QPoint & topLeft)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>
blit270(QScreen * screen,const QImage & image,const QRect & rect,const QPoint & topLeft)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 */
blit(const QImage & image,const QPoint & topLeft,const QRegion & region)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 */
solidFill(const QColor & color,const QRegion & region)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 */
mapToDevice(const QSize & s) const481 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 */
mapFromDevice(const QSize & s) const498 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 */
mapToDevice(const QPoint & p,const QSize & s) const515 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 */
mapFromDevice(const QPoint & p,const QSize & s) const542 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 */
mapToDevice(const QRect & r,const QSize & s) const569 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 */
mapFromDevice(const QRect & r,const QSize & s) const599 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 */
mapToDevice(const QRegion & rgn,const QSize & s) const629 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 */
mapFromDevice(const QRegion & rgn,const QSize & s) const680 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 */
setDirty(const QRect & rect)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 */
region() const740 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
749