src/gui/embedded/qscreentransformed_qws.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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 &region)
       
   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 &region)
       
   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