src/gui/embedded/qscreen_qws.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
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 "qscreen_qws.h"
       
    43 
       
    44 #include "qcolormap.h"
       
    45 #include "qscreendriverfactory_qws.h"
       
    46 #include "qwindowsystem_qws.h"
       
    47 #include "qwidget.h"
       
    48 #include "qcolor.h"
       
    49 #include "qpixmap.h"
       
    50 #include "qvarlengtharray.h"
       
    51 #include "qwsdisplay_qws.h"
       
    52 #include "qpainter.h"
       
    53 #include <private/qdrawhelper_p.h>
       
    54 #include <private/qpaintengine_raster_p.h>
       
    55 #include <private/qpixmap_raster_p.h>
       
    56 #include <private/qwindowsurface_qws_p.h>
       
    57 #include <private/qpainter_p.h>
       
    58 #include <private/qwidget_p.h>
       
    59 #include <private/qgraphicssystem_qws_p.h>
       
    60 
       
    61 QT_BEGIN_NAMESPACE
       
    62 
       
    63 // #define QT_USE_MEMCPY_DUFF
       
    64 
       
    65 #ifndef QT_NO_QWS_CURSOR
       
    66 bool qt_sw_cursor=false;
       
    67 Q_GUI_EXPORT QScreenCursor * qt_screencursor = 0;
       
    68 #endif
       
    69 Q_GUI_EXPORT QScreen * qt_screen = 0;
       
    70 
       
    71 ClearCacheFunc QScreen::clearCacheFunc = 0;
       
    72 
       
    73 #ifndef QT_NO_QWS_CURSOR
       
    74 /*!
       
    75     \class QScreenCursor
       
    76     \ingroup qws
       
    77 
       
    78     \brief The QScreenCursor class is a base class for screen cursors
       
    79     in Qt for Embedded Linux.
       
    80 
       
    81     Note that this class is non-portable, and that it is only
       
    82     available in \l{Qt for Embedded Linux}.
       
    83 
       
    84     QScreenCursor implements a software cursor, but can be subclassed
       
    85     to support hardware cursors as well. When deriving from the
       
    86     QScreenCursor class it is important to maintain the cursor's
       
    87     image, position, hot spot (the point within the cursor's image
       
    88     that will be the position of the associated mouse events) and
       
    89     visibility as well as informing whether it is hardware accelerated
       
    90     or not.
       
    91 
       
    92     Note that there may only be one screen cursor at a time. Use the
       
    93     static instance() function to retrieve a pointer to the current
       
    94     screen cursor. Typically, the cursor is constructed by the QScreen
       
    95     class or one of its descendants when it is initializing the
       
    96     device; the QScreenCursor class should never be instantiated
       
    97     explicitly.
       
    98 
       
    99     Use the move() function to change the position of the cursor, and
       
   100     the set() function to alter its image or its hot spot. In
       
   101     addition, you can find out whether the cursor is accelerated or
       
   102     not, using the isAccelerated() function, and the boundingRect()
       
   103     function returns the cursor's bounding rectangle.
       
   104 
       
   105     The cursor's appearance can be controlled using the isVisible(),
       
   106     hide() and show() functions; alternatively the QWSServer class
       
   107     provides some means of controlling the cursor's appearance using
       
   108     the QWSServer::isCursorVisible() and QWSServer::setCursorVisible()
       
   109     functions.
       
   110 
       
   111     \sa QScreen, QWSServer
       
   112 */
       
   113 
       
   114 /*!
       
   115     \fn static QScreenCursor* QScreenCursor::instance()
       
   116     \since 4.2
       
   117 
       
   118     Returns a pointer to the application's unique screen cursor.
       
   119 */
       
   120 
       
   121 extern bool qws_sw_cursor;
       
   122 
       
   123 /*!
       
   124     Constructs a screen cursor
       
   125 */
       
   126 QScreenCursor::QScreenCursor()
       
   127 {
       
   128     pos = QPoint(qt_screen->deviceWidth()/2, qt_screen->deviceHeight()/2);
       
   129     size = QSize(0,0);
       
   130     enable = true;
       
   131     hwaccel = false;
       
   132     supportsAlpha = true;
       
   133 }
       
   134 
       
   135 /*!
       
   136     Destroys the screen cursor.
       
   137 */
       
   138 QScreenCursor::~QScreenCursor()
       
   139 {
       
   140 }
       
   141 
       
   142 /*!
       
   143     Hides the cursor from the screen.
       
   144 
       
   145     \sa show()
       
   146 */
       
   147 void QScreenCursor::hide()
       
   148 {
       
   149     if (enable) {
       
   150         enable = false;
       
   151         if (!hwaccel)
       
   152             qt_screen->exposeRegion(boundingRect(), 0);
       
   153     }
       
   154 }
       
   155 
       
   156 /*!
       
   157     Shows the mouse cursor.
       
   158 
       
   159     \sa hide()
       
   160 */
       
   161 void QScreenCursor::show()
       
   162 {
       
   163     if (!enable) {
       
   164         enable = true;
       
   165         if (!hwaccel)
       
   166             qt_screen->exposeRegion(boundingRect(), 0);
       
   167     }
       
   168 }
       
   169 
       
   170 /*!
       
   171     Sets the cursor's image to be the given \a image.
       
   172 
       
   173     The \a hotx and \a hoty parameters define the cursor's hot spot,
       
   174     i.e., the point within the cursor's image that will be the
       
   175     position of the associated mouse events.
       
   176 
       
   177     \sa move()
       
   178 */
       
   179 void QScreenCursor::set(const QImage &image, int hotx, int hoty)
       
   180 {
       
   181     const QRect r = boundingRect();
       
   182 
       
   183     hotspot = QPoint(hotx, hoty);
       
   184     // These are in almost all cases the fastest formats to blend
       
   185     QImage::Format f;
       
   186     switch (qt_screen->depth()) {
       
   187     case 12:
       
   188         f = QImage::Format_ARGB4444_Premultiplied;
       
   189         break;
       
   190     case 15:
       
   191         f =  QImage::Format_ARGB8555_Premultiplied;
       
   192         break;
       
   193     case 16:
       
   194         f = QImage::Format_ARGB8565_Premultiplied;
       
   195         break;
       
   196     case 18:
       
   197         f = QImage::Format_ARGB6666_Premultiplied;
       
   198         break;
       
   199     default:
       
   200         f =  QImage::Format_ARGB32_Premultiplied;
       
   201     }
       
   202 
       
   203     cursor = image.convertToFormat(f);
       
   204 
       
   205     size = image.size();
       
   206 
       
   207     if (enable && !hwaccel)
       
   208         qt_screen->exposeRegion(r | boundingRect(), 0);
       
   209 }
       
   210 
       
   211 /*!
       
   212     Moves the mouse cursor to the given position, i.e., (\a x, \a y).
       
   213 
       
   214     Note that the given position defines the top-left corner of the
       
   215     cursor's image, i.e., not the cursor's hot spot (the position of
       
   216     the associated mouse events).
       
   217 
       
   218     \sa set()
       
   219 */
       
   220 void QScreenCursor::move(int x, int y)
       
   221 {
       
   222     QRegion r = boundingRect();
       
   223     pos = QPoint(x,y);
       
   224     if (enable && !hwaccel) {
       
   225         r |= boundingRect();
       
   226         qt_screen->exposeRegion(r, 0);
       
   227     }
       
   228 }
       
   229 
       
   230 
       
   231 /*!
       
   232     \fn void QScreenCursor::initSoftwareCursor ()
       
   233 
       
   234     Initializes the screen cursor.
       
   235 
       
   236     This function is typically called from the screen driver when
       
   237     initializing the device. Alternatively, the cursor can be set
       
   238     directly using the pointer returned by the static instance()
       
   239     function.
       
   240 
       
   241     \sa QScreen::initDevice()
       
   242 */
       
   243 void QScreenCursor::initSoftwareCursor()
       
   244 {
       
   245     qt_screencursor = new QScreenCursor;
       
   246 }
       
   247 
       
   248 
       
   249 #endif // QT_NO_QWS_CURSOR
       
   250 
       
   251 
       
   252 /*!
       
   253     \fn QRect QScreenCursor::boundingRect () const
       
   254 
       
   255     Returns the cursor's bounding rectangle.
       
   256 */
       
   257 
       
   258 /*!
       
   259     \internal
       
   260     \fn bool QScreenCursor::enabled ()
       
   261 */
       
   262 
       
   263 /*!
       
   264     \fn QImage QScreenCursor::image () const
       
   265 
       
   266     Returns the cursor's image.
       
   267 */
       
   268 
       
   269 
       
   270 /*!
       
   271     \fn bool QScreenCursor::isAccelerated () const
       
   272 
       
   273     Returns true if the cursor is accelerated; otherwise false.
       
   274 */
       
   275 
       
   276 /*!
       
   277     \fn bool QScreenCursor::isVisible () const
       
   278 
       
   279     Returns true if the cursor is visible; otherwise false.
       
   280 */
       
   281 
       
   282 /*!
       
   283     \internal
       
   284     \fn bool QScreenCursor::supportsAlphaCursor () const
       
   285 */
       
   286 
       
   287 /*
       
   288     \variable QScreenCursor::cursor
       
   289 
       
   290     \brief the cursor's image.
       
   291 
       
   292     \sa image()
       
   293 */
       
   294 
       
   295 /*
       
   296     \variable QScreenCursor::size
       
   297 
       
   298     \brief the cursor's size
       
   299 */
       
   300 
       
   301 /*
       
   302     \variable QScreenCursor::pos
       
   303 
       
   304     \brief the cursor's position, i.e., the position of the top-left
       
   305     corner of the crsor's image
       
   306 
       
   307     \sa set(), move()
       
   308 */
       
   309 
       
   310 /*
       
   311     \variable QScreenCursor::hotspot
       
   312 
       
   313     \brief the cursor's hotspot, i.e., the point within the cursor's
       
   314     image that will be the position of the associated mouse events.
       
   315 
       
   316     \sa set(), move()
       
   317 */
       
   318 
       
   319 /*
       
   320     \variable QScreenCursor::enable
       
   321 
       
   322     \brief whether the cursor is visible or not
       
   323 
       
   324     \sa isVisible()
       
   325 */
       
   326 
       
   327 /*
       
   328     \variable QScreenCursor::hwaccel
       
   329 
       
   330     \brief holds whether the cursor is accelerated or not
       
   331 
       
   332     If the cursor is not accelerated, its image will be included by
       
   333     the screen when it composites the window surfaces.
       
   334 
       
   335     \sa isAccelerated()
       
   336 
       
   337 */
       
   338 
       
   339 /*
       
   340     \variable QScreenCursor::supportsAlpha
       
   341 */
       
   342 
       
   343 /*!
       
   344     \internal
       
   345     \macro qt_screencursor
       
   346     \relates QScreenCursor
       
   347 
       
   348     A global pointer referring to the unique screen cursor. It is
       
   349     equivalent to the pointer returned by the
       
   350     QScreenCursor::instance() function.
       
   351 */
       
   352 
       
   353 
       
   354 
       
   355 class QScreenPrivate
       
   356 {
       
   357 public:
       
   358     QScreenPrivate(QScreen *parent, QScreen::ClassId id = QScreen::CustomClass);
       
   359     ~QScreenPrivate();
       
   360 
       
   361     inline QImage::Format preferredImageFormat() const;
       
   362 
       
   363     typedef void (*SolidFillFunc)(QScreen*, const QColor&, const QRegion&);
       
   364     typedef void (*BlitFunc)(QScreen*, const QImage&, const QPoint&, const QRegion&);
       
   365 
       
   366     SolidFillFunc solidFill;
       
   367     BlitFunc blit;
       
   368 
       
   369     QPoint offset;
       
   370     QList<QScreen*> subScreens;
       
   371     QPixmapDataFactory* pixmapFactory;
       
   372     QGraphicsSystem* graphicsSystem;
       
   373     QWSGraphicsSystem defaultGraphicsSystem; //###
       
   374     QImage::Format pixelFormat;
       
   375 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
       
   376     bool fb_is_littleEndian;
       
   377 #endif
       
   378 #ifdef QT_QWS_CLIENTBLIT
       
   379     bool supportsBlitInClients;
       
   380 #endif
       
   381     int classId;
       
   382     QScreen *q_ptr;
       
   383 };
       
   384 
       
   385 template <typename T>
       
   386 static void solidFill_template(QScreen *screen, const QColor &color,
       
   387                                const QRegion &region)
       
   388 {
       
   389     T *dest = reinterpret_cast<T*>(screen->base());
       
   390     const T c = qt_colorConvert<T, quint32>(color.rgba(), 0);
       
   391     const int stride = screen->linestep();
       
   392     const QVector<QRect> rects = region.rects();
       
   393 
       
   394     for (int i = 0; i < rects.size(); ++i) {
       
   395         const QRect r = rects.at(i);
       
   396         qt_rectfill(dest, c, r.x(), r.y(), r.width(), r.height(), stride);
       
   397     }
       
   398 }
       
   399 
       
   400 #ifdef QT_QWS_DEPTH_GENERIC
       
   401 static void solidFill_rgb_32bpp(QScreen *screen, const QColor &color,
       
   402                                 const QRegion &region)
       
   403 {
       
   404     quint32 *dest = reinterpret_cast<quint32*>(screen->base());
       
   405     const quint32 c = qt_convertToRgb<quint32>(color.rgba());
       
   406 
       
   407     const int stride = screen->linestep();
       
   408     const QVector<QRect> rects = region.rects();
       
   409 
       
   410     for (int i = 0; i < rects.size(); ++i) {
       
   411         const QRect r = rects.at(i);
       
   412         qt_rectfill(dest, c, r.x(), r.y(), r.width(), r.height(), stride);
       
   413     }
       
   414 }
       
   415 
       
   416 static void solidFill_rgb_16bpp(QScreen *screen, const QColor &color,
       
   417                                 const QRegion &region)
       
   418 {
       
   419     quint16 *dest = reinterpret_cast<quint16*>(screen->base());
       
   420     const quint16 c = qt_convertToRgb<quint32>(color.rgba());
       
   421 
       
   422     const int stride = screen->linestep();
       
   423     const QVector<QRect> rects = region.rects();
       
   424 
       
   425     for (int i = 0; i < rects.size(); ++i) {
       
   426         const QRect r = rects.at(i);
       
   427         qt_rectfill(dest, c, r.x(), r.y(), r.width(), r.height(), stride);
       
   428     }
       
   429 }
       
   430 #endif // QT_QWS_DEPTH_GENERIC
       
   431 
       
   432 #ifdef QT_QWS_DEPTH_4
       
   433 static inline void qt_rectfill_gray4(quint8 *dest, quint8 value,
       
   434                                      int x, int y, int width, int height,
       
   435                                      int stride)
       
   436 {
       
   437     const int pixelsPerByte = 2;
       
   438     dest += y * stride + x / pixelsPerByte;
       
   439     const int doAlign = x & 1;
       
   440     const int doTail = (width - doAlign) & 1;
       
   441     const int width8 = (width - doAlign) / pixelsPerByte;
       
   442 
       
   443     for (int j = 0; j < height; ++j) {
       
   444         if (doAlign)
       
   445             *dest = (*dest & 0xf0) | (value & 0x0f);
       
   446         if (width8)
       
   447             qt_memfill<quint8>(dest + doAlign, value, width8);
       
   448         if (doTail) {
       
   449             quint8 *d = dest + doAlign + width8;
       
   450             *d = (*d & 0x0f) | (value & 0xf0);
       
   451         }
       
   452         dest += stride;
       
   453     }
       
   454 }
       
   455 
       
   456 static void solidFill_gray4(QScreen *screen, const QColor &color,
       
   457                             const QRegion &region)
       
   458 {
       
   459     quint8 *dest = reinterpret_cast<quint8*>(screen->base());
       
   460     const quint8 c = qGray(color.rgba()) >> 4;
       
   461     const quint8 c8 = (c << 4) | c;
       
   462 
       
   463     const int stride = screen->linestep();
       
   464     const QVector<QRect> rects = region.rects();
       
   465 
       
   466     for (int i = 0; i < rects.size(); ++i) {
       
   467         const QRect r = rects.at(i);
       
   468         qt_rectfill_gray4(dest, c8, r.x(), r.y(), r.width(), r.height(),
       
   469                           stride);
       
   470     }
       
   471 }
       
   472 #endif // QT_QWS_DEPTH_4
       
   473 
       
   474 #ifdef QT_QWS_DEPTH_1
       
   475 static inline void qt_rectfill_mono(quint8 *dest, quint8 value,
       
   476                                     int x, int y, int width, int height,
       
   477                                     int stride)
       
   478 {
       
   479     const int pixelsPerByte = 8;
       
   480     const int alignWidth = qMin(width, (8 - (x & 7)) & 7);
       
   481     const int doAlign = (alignWidth > 0 ? 1 : 0);
       
   482     const int alignStart = pixelsPerByte - 1 - (x & 7);
       
   483     const int alignStop = alignStart - (alignWidth - 1);
       
   484     const quint8 alignMask = ((1 << alignWidth) - 1) << alignStop;
       
   485     const int tailWidth = (width - alignWidth) & 7;
       
   486     const int doTail = (tailWidth > 0 ? 1 : 0);
       
   487     const quint8 tailMask = (1 << (pixelsPerByte - tailWidth)) - 1;
       
   488     const int width8 = (width - alignWidth) / pixelsPerByte;
       
   489 
       
   490     dest += y * stride + x / pixelsPerByte;
       
   491     stride -= (doAlign + width8);
       
   492 
       
   493     for (int j = 0; j < height; ++j) {
       
   494         if (doAlign) {
       
   495             *dest = (*dest & ~alignMask) | (value & alignMask);
       
   496             ++dest;
       
   497         }
       
   498         if (width8) {
       
   499             qt_memfill<quint8>(dest, value, width8);
       
   500             dest += width8;
       
   501         }
       
   502         if (doTail)
       
   503             *dest = (*dest & tailMask) | (value & ~tailMask);
       
   504         dest += stride;
       
   505     }
       
   506 }
       
   507 
       
   508 static void solidFill_mono(QScreen *screen, const QColor &color,
       
   509                            const QRegion &region)
       
   510 {
       
   511     quint8 *dest = reinterpret_cast<quint8*>(screen->base());
       
   512     const quint8 c8 = (qGray(color.rgba()) >> 7) * 0xff;
       
   513 
       
   514     const int stride = screen->linestep();
       
   515     const QVector<QRect> rects = region.rects();
       
   516 
       
   517     for (int i = 0; i < rects.size(); ++i) {
       
   518         const QRect r = rects.at(i);
       
   519         qt_rectfill_mono(dest, c8, r.x(), r.y(), r.width(), r.height(),
       
   520                          stride);
       
   521     }
       
   522 }
       
   523 #endif // QT_QWS_DEPTH_1
       
   524 
       
   525 void qt_solidFill_setup(QScreen *screen, const QColor &color,
       
   526                         const QRegion &region)
       
   527 {
       
   528     switch (screen->depth()) {
       
   529 #ifdef QT_QWS_DEPTH_32
       
   530     case 32:
       
   531         if (screen->pixelType() == QScreen::NormalPixel)
       
   532             screen->d_ptr->solidFill = solidFill_template<quint32>;
       
   533         else
       
   534             screen->d_ptr->solidFill = solidFill_template<qabgr8888>;
       
   535         break;
       
   536 #endif
       
   537 #ifdef QT_QWS_DEPTH_24
       
   538     case 24:
       
   539         if (screen->pixelType() == QScreen::NormalPixel)
       
   540             screen->d_ptr->solidFill = solidFill_template<qrgb888>;
       
   541         else
       
   542             screen->d_ptr->solidFill = solidFill_template<quint24>;
       
   543         break;
       
   544 #endif
       
   545 #ifdef QT_QWS_DEPTH_18
       
   546     case 18:
       
   547         screen->d_ptr->solidFill = solidFill_template<quint18>;
       
   548         break;
       
   549 #endif
       
   550 #ifdef QT_QWS_DEPTH_16
       
   551     case 16:
       
   552         if (screen->pixelType() == QScreen::NormalPixel)
       
   553             screen->d_ptr->solidFill = solidFill_template<quint16>;
       
   554         else
       
   555             screen->d_ptr->solidFill = solidFill_template<qbgr565>;
       
   556         break;
       
   557 #endif
       
   558 #ifdef QT_QWS_DEPTH_15
       
   559     case 15:
       
   560         if (screen->pixelType() == QScreen::NormalPixel)
       
   561             screen->d_ptr->solidFill = solidFill_template<qrgb555>;
       
   562         else
       
   563             screen->d_ptr->solidFill = solidFill_template<qbgr555>;
       
   564         break;
       
   565 #endif
       
   566 #ifdef QT_QWS_DEPTH_12
       
   567     case 12:
       
   568         screen->d_ptr->solidFill = solidFill_template<qrgb444>;
       
   569         break;
       
   570 #endif
       
   571 #ifdef QT_QWS_DEPTH_8
       
   572     case 8:
       
   573         screen->d_ptr->solidFill = solidFill_template<quint8>;
       
   574         break;
       
   575 #endif
       
   576 #ifdef QT_QWS_DEPTH_4
       
   577     case 4:
       
   578         screen->d_ptr->solidFill = solidFill_gray4;
       
   579         break;
       
   580 #endif
       
   581 #ifdef QT_QWS_DEPTH_1
       
   582     case 1:
       
   583         screen->d_ptr->solidFill = solidFill_mono;
       
   584         break;
       
   585 #endif
       
   586      default:
       
   587         qFatal("solidFill_setup(): Screen depth %d not supported!",
       
   588                screen->depth());
       
   589         screen->d_ptr->solidFill = 0;
       
   590         break;
       
   591     }
       
   592     screen->d_ptr->solidFill(screen, color, region);
       
   593 }
       
   594 
       
   595 template <typename DST, typename SRC>
       
   596 static void blit_template(QScreen *screen, const QImage &image,
       
   597                           const QPoint &topLeft, const QRegion &region)
       
   598 {
       
   599     DST *dest = reinterpret_cast<DST*>(screen->base());
       
   600     const int screenStride = screen->linestep();
       
   601     const int imageStride = image.bytesPerLine();
       
   602 
       
   603     if (region.numRects() == 1) {
       
   604         const QRect r = region.boundingRect();
       
   605         const SRC *src = reinterpret_cast<const SRC*>(image.scanLine(r.y()))
       
   606                          + r.x();
       
   607         qt_rectconvert<DST, SRC>(dest, src,
       
   608                                  r.x() + topLeft.x(), r.y() + topLeft.y(),
       
   609                                  r.width(), r.height(),
       
   610                                  screenStride, imageStride);
       
   611     } else {
       
   612         const QVector<QRect> rects = region.rects();
       
   613 
       
   614         for (int i = 0; i < rects.size(); ++i) {
       
   615             const QRect r = rects.at(i);
       
   616             const SRC *src = reinterpret_cast<const SRC*>(image.scanLine(r.y()))
       
   617                              + r.x();
       
   618             qt_rectconvert<DST, SRC>(dest, src,
       
   619                                      r.x() + topLeft.x(), r.y() + topLeft.y(),
       
   620                                      r.width(), r.height(),
       
   621                                      screenStride, imageStride);
       
   622         }
       
   623     }
       
   624 }
       
   625 
       
   626 #ifdef QT_QWS_DEPTH_32
       
   627 static void blit_32(QScreen *screen, const QImage &image,
       
   628                     const QPoint &topLeft, const QRegion &region)
       
   629 {
       
   630     switch (image.format()) {
       
   631     case QImage::Format_RGB32:
       
   632     case QImage::Format_ARGB32:
       
   633     case QImage::Format_ARGB32_Premultiplied:
       
   634         blit_template<quint32, quint32>(screen, image, topLeft, region);
       
   635         return;
       
   636 #ifdef QT_QWS_DEPTH_16
       
   637     case QImage::Format_RGB16:
       
   638         blit_template<quint32, quint16>(screen, image, topLeft, region);
       
   639         return;
       
   640 #endif
       
   641     default:
       
   642         qCritical("blit_32(): Image format %d not supported!", image.format());
       
   643     }
       
   644 }
       
   645 #endif // QT_QWS_DEPTH_32
       
   646 
       
   647 #ifdef QT_QWS_DEPTH_24
       
   648 static void blit_24(QScreen *screen, const QImage &image,
       
   649                     const QPoint &topLeft, const QRegion &region)
       
   650 {
       
   651     switch (image.format()) {
       
   652     case QImage::Format_RGB32:
       
   653     case QImage::Format_ARGB32:
       
   654     case QImage::Format_ARGB32_Premultiplied:
       
   655         blit_template<quint24, quint32>(screen, image, topLeft, region);
       
   656         return;
       
   657     case QImage::Format_RGB888:
       
   658         blit_template<quint24, qrgb888>(screen, image, topLeft, region);
       
   659         return;
       
   660 #ifdef QT_QWS_DEPTH_16
       
   661     case QImage::Format_RGB16:
       
   662         blit_template<quint24, quint16>(screen, image, topLeft, region);
       
   663         return;
       
   664 #endif
       
   665     default:
       
   666         qCritical("blit_24(): Image format %d not supported!", image.format());
       
   667     }
       
   668 }
       
   669 
       
   670 static void blit_qrgb888(QScreen *screen, const QImage &image,
       
   671                          const QPoint &topLeft, const QRegion &region)
       
   672 {
       
   673     switch (image.format()) {
       
   674     case QImage::Format_RGB32:
       
   675     case QImage::Format_ARGB32:
       
   676     case QImage::Format_ARGB32_Premultiplied:
       
   677         blit_template<qrgb888, quint32>(screen, image, topLeft, region);
       
   678         return;
       
   679     case QImage::Format_RGB888:
       
   680         blit_template<qrgb888, qrgb888>(screen, image, topLeft, region);
       
   681         return;
       
   682 #ifdef QT_QWS_DEPTH_16
       
   683     case QImage::Format_RGB16:
       
   684         blit_template<qrgb888, quint16>(screen, image, topLeft, region);
       
   685         return;
       
   686 #endif
       
   687     default:
       
   688         qCritical("blit_24(): Image format %d not supported!", image.format());
       
   689         break;
       
   690     }
       
   691 }
       
   692 #endif // QT_QWS_DEPTH_24
       
   693 
       
   694 #ifdef QT_QWS_DEPTH_18
       
   695 static void blit_18(QScreen *screen, const QImage &image,
       
   696                     const QPoint &topLeft, const QRegion &region)
       
   697 {
       
   698     switch (image.format()) {
       
   699     case QImage::Format_RGB32:
       
   700     case QImage::Format_ARGB32:
       
   701     case QImage::Format_ARGB32_Premultiplied:
       
   702         blit_template<qrgb666, quint32>(screen, image, topLeft, region);
       
   703         return;
       
   704     case QImage::Format_RGB666:
       
   705         blit_template<qrgb666, qrgb666>(screen, image, topLeft, region);
       
   706         return;
       
   707 #ifdef QT_QWS_DEPTH_16
       
   708     case QImage::Format_RGB16:
       
   709         blit_template<qrgb666, quint16>(screen, image, topLeft, region);
       
   710         return;
       
   711 #endif
       
   712     default:
       
   713         qCritical("blit_18(): Image format %d not supported!", image.format());
       
   714     }
       
   715 }
       
   716 #endif // QT_QWS_DEPTH_18
       
   717 
       
   718 #if (Q_BYTE_ORDER == Q_BIG_ENDIAN) && (defined(QT_QWS_DEPTH_16) || defined(QT_QWS_DEPTH_15))
       
   719 class quint16LE
       
   720 {
       
   721 public:
       
   722     inline quint16LE(quint32 v) {
       
   723         data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
       
   724     }
       
   725 
       
   726     inline quint16LE(int v) {
       
   727         data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
       
   728     }
       
   729 
       
   730     inline quint16LE(quint16 v) {
       
   731         data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
       
   732     }
       
   733 
       
   734     inline quint16LE(qrgb555 v) {
       
   735         data = (( (quint16)v & 0xff00) >> 8) |
       
   736                (( (quint16)v & 0x00ff) << 8);
       
   737     }
       
   738 
       
   739     inline bool operator==(const quint16LE &v) const
       
   740     {
       
   741         return data == v.data;
       
   742     }
       
   743 
       
   744 private:
       
   745     quint16 data;
       
   746 };
       
   747 #endif
       
   748 
       
   749 #ifdef QT_QWS_DEPTH_16
       
   750 static void blit_16(QScreen *screen, const QImage &image,
       
   751                     const QPoint &topLeft, const QRegion &region)
       
   752 {
       
   753     switch (image.format()) {
       
   754     case QImage::Format_RGB32:
       
   755     case QImage::Format_ARGB32:
       
   756     case QImage::Format_ARGB32_Premultiplied:
       
   757         // ### This probably doesn't work but it's a case which should never happen
       
   758         blit_template<quint16, quint32>(screen, image, topLeft, region);
       
   759         return;
       
   760     case QImage::Format_RGB16:
       
   761         blit_template<quint16, quint16>(screen, image, topLeft, region);
       
   762         return;
       
   763     default:
       
   764         qCritical("blit_16(): Image format %d not supported!", image.format());
       
   765     }
       
   766 }
       
   767 
       
   768 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
       
   769 static void blit_16_bigToLittleEndian(QScreen *screen, const QImage &image,
       
   770                                       const QPoint &topLeft,
       
   771                                       const QRegion &region)
       
   772 {
       
   773     switch (image.format()) {
       
   774     case QImage::Format_RGB32:
       
   775     case QImage::Format_ARGB32:
       
   776     case QImage::Format_ARGB32_Premultiplied:
       
   777         blit_template<quint16LE, quint32>(screen, image, topLeft, region);
       
   778         return;
       
   779     case QImage::Format_RGB16:
       
   780         blit_template<quint16LE, quint16>(screen, image, topLeft, region);
       
   781         return;
       
   782     default:
       
   783         qCritical("blit_16_bigToLittleEndian(): Image format %d not supported!", image.format());
       
   784     }
       
   785 }
       
   786 
       
   787 #endif // Q_BIG_ENDIAN
       
   788 #endif // QT_QWS_DEPTH_16
       
   789 
       
   790 #ifdef QT_QWS_DEPTH_15
       
   791 static void blit_15(QScreen *screen, const QImage &image,
       
   792                     const QPoint &topLeft, const QRegion &region)
       
   793 {
       
   794     switch (image.format()) {
       
   795     case QImage::Format_RGB32:
       
   796     case QImage::Format_ARGB32:
       
   797     case QImage::Format_ARGB32_Premultiplied:
       
   798         blit_template<qrgb555, quint32>(screen, image, topLeft, region);
       
   799         return;
       
   800     case QImage::Format_RGB555:
       
   801         blit_template<qrgb555, qrgb555>(screen, image, topLeft, region);
       
   802         return;
       
   803     case QImage::Format_RGB16:
       
   804         blit_template<qrgb555, quint16>(screen, image, topLeft, region);
       
   805         return;
       
   806     default:
       
   807         qCritical("blit_15(): Image format %d not supported!", image.format());
       
   808     }
       
   809 }
       
   810 
       
   811 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
       
   812 static void blit_15_bigToLittleEndian(QScreen *screen, const QImage &image,
       
   813                                       const QPoint &topLeft,
       
   814                                       const QRegion &region)
       
   815 {
       
   816     switch (image.format()) {
       
   817     case QImage::Format_RGB555:
       
   818         blit_template<quint16LE, qrgb555>(screen, image, topLeft, region);
       
   819         return;
       
   820     default:
       
   821         qCritical("blit_15_bigToLittleEndian(): Image format %d not supported!", image.format());
       
   822     }
       
   823 }
       
   824 #endif // Q_BIG_ENDIAN
       
   825 #endif // QT_QWS_DEPTH_15
       
   826 
       
   827 
       
   828 #ifdef QT_QWS_DEPTH_12
       
   829 static void blit_12(QScreen *screen, const QImage &image,
       
   830                     const QPoint &topLeft, const QRegion &region)
       
   831 {
       
   832     switch (image.format()) {
       
   833     case QImage::Format_ARGB4444_Premultiplied:
       
   834         blit_template<qrgb444, qargb4444>(screen, image, topLeft, region);
       
   835         return;
       
   836     case QImage::Format_RGB444:
       
   837         blit_template<qrgb444, qrgb444>(screen, image, topLeft, region);
       
   838         return;
       
   839     default:
       
   840         qCritical("blit_12(): Image format %d not supported!", image.format());
       
   841     }
       
   842 }
       
   843 #endif // QT_QWS_DEPTH_12
       
   844 
       
   845 #ifdef QT_QWS_DEPTH_8
       
   846 static void blit_8(QScreen *screen, const QImage &image,
       
   847                    const QPoint &topLeft, const QRegion &region)
       
   848 {
       
   849     switch (image.format()) {
       
   850     case QImage::Format_RGB32:
       
   851     case QImage::Format_ARGB32:
       
   852     case QImage::Format_ARGB32_Premultiplied:
       
   853         blit_template<quint8, quint32>(screen, image, topLeft, region);
       
   854         return;
       
   855     case QImage::Format_RGB16:
       
   856         blit_template<quint8, quint16>(screen, image, topLeft, region);
       
   857         return;
       
   858     case QImage::Format_ARGB4444_Premultiplied:
       
   859         blit_template<quint8, qargb4444>(screen, image, topLeft, region);
       
   860         return;
       
   861     case QImage::Format_RGB444:
       
   862         blit_template<quint8, qrgb444>(screen, image, topLeft, region);
       
   863         return;
       
   864     default:
       
   865         qCritical("blit_8(): Image format %d not supported!", image.format());
       
   866     }
       
   867 }
       
   868 #endif // QT_QWS_DEPTH_8
       
   869 
       
   870 #ifdef QT_QWS_DEPTH_4
       
   871 
       
   872 struct qgray4 { quint8 dummy; } Q_PACKED;
       
   873 
       
   874 template <typename SRC>
       
   875 Q_STATIC_TEMPLATE_FUNCTION inline quint8 qt_convertToGray4(SRC color);
       
   876 
       
   877 template <>
       
   878 inline quint8 qt_convertToGray4(quint32 color)
       
   879 {
       
   880     return qGray(color) >> 4;
       
   881 }
       
   882 
       
   883 template <>
       
   884 inline quint8 qt_convertToGray4(quint16 color)
       
   885 {
       
   886     const int r = (color & 0xf800) >> 11;
       
   887     const int g = (color & 0x07e0) >> 6; // only keep 5 bit
       
   888     const int b = (color & 0x001f);
       
   889     return (r * 11 + g * 16 + b * 5) >> 6;
       
   890 }
       
   891 
       
   892 template <>
       
   893 inline quint8 qt_convertToGray4(qrgb444 color)
       
   894 {
       
   895     return qt_convertToGray4(quint32(color));
       
   896 }
       
   897 
       
   898 template <>
       
   899 inline quint8 qt_convertToGray4(qargb4444 color)
       
   900 {
       
   901     return qt_convertToGray4(quint32(color));
       
   902 }
       
   903 
       
   904 template <typename SRC>
       
   905 Q_STATIC_TEMPLATE_FUNCTION inline void qt_rectconvert_gray4(qgray4 *dest4, const SRC *src,
       
   906                                         int x, int y, int width, int height,
       
   907                                         int dstStride, int srcStride)
       
   908 {
       
   909     const int pixelsPerByte = 2;
       
   910     quint8 *dest8 = reinterpret_cast<quint8*>(dest4)
       
   911                     + y * dstStride + x / pixelsPerByte;
       
   912     const int doAlign = x & 1;
       
   913     const int doTail = (width - doAlign) & 1;
       
   914     const int width8 = (width - doAlign) / pixelsPerByte;
       
   915     const int count8 = (width8 + 3) / 4;
       
   916 
       
   917     srcStride = srcStride / sizeof(SRC) - width;
       
   918     dstStride -= (width8 + doAlign);
       
   919 
       
   920     for (int i = 0; i < height; ++i) {
       
   921         if (doAlign) {
       
   922             *dest8 = (*dest8 & 0xf0) | qt_convertToGray4<SRC>(*src++);
       
   923             ++dest8;
       
   924         }
       
   925         if (count8) {
       
   926             int n = count8;
       
   927             switch (width8 & 0x03) // duff's device
       
   928             {
       
   929             case 0: do { *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
       
   930                                     | qt_convertToGray4<SRC>(src[1]);
       
   931                          src += 2;
       
   932             case 3:      *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
       
   933                                     | qt_convertToGray4<SRC>(src[1]);
       
   934                          src += 2;
       
   935             case 2:      *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
       
   936                                     | qt_convertToGray4<SRC>(src[1]);
       
   937                          src += 2;
       
   938             case 1:      *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
       
   939                                     | qt_convertToGray4<SRC>(src[1]);
       
   940                          src += 2;
       
   941             } while (--n > 0);
       
   942             }
       
   943         }
       
   944 
       
   945         if (doTail)
       
   946             *dest8 = qt_convertToGray4<SRC>(*src++) << 4 | (*dest8 & 0x0f);
       
   947 
       
   948         dest8 += dstStride;
       
   949         src += srcStride;
       
   950     }
       
   951 }
       
   952 
       
   953 template <>
       
   954 void qt_rectconvert(qgray4 *dest, const quint32 *src,
       
   955                     int x, int y, int width, int height,
       
   956                     int dstStride, int srcStride)
       
   957 {
       
   958     qt_rectconvert_gray4<quint32>(dest, src, x, y, width, height,
       
   959                                   dstStride, srcStride);
       
   960 }
       
   961 
       
   962 template <>
       
   963 void qt_rectconvert(qgray4 *dest, const quint16 *src,
       
   964                     int x, int y, int width, int height,
       
   965                     int dstStride, int srcStride)
       
   966 {
       
   967     qt_rectconvert_gray4<quint16>(dest, src, x, y, width, height,
       
   968                                   dstStride, srcStride);
       
   969 }
       
   970 
       
   971 template <>
       
   972 void qt_rectconvert(qgray4 *dest, const qrgb444 *src,
       
   973                     int x, int y, int width, int height,
       
   974                     int dstStride, int srcStride)
       
   975 {
       
   976     qt_rectconvert_gray4<qrgb444>(dest, src, x, y, width, height,
       
   977                                   dstStride, srcStride);
       
   978 }
       
   979 
       
   980 template <>
       
   981 void qt_rectconvert(qgray4 *dest, const qargb4444 *src,
       
   982                     int x, int y, int width, int height,
       
   983                     int dstStride, int srcStride)
       
   984 {
       
   985     qt_rectconvert_gray4<qargb4444>(dest, src, x, y, width, height,
       
   986                                     dstStride, srcStride);
       
   987 }
       
   988 
       
   989 static void blit_4(QScreen *screen, const QImage &image,
       
   990                    const QPoint &topLeft, const QRegion &region)
       
   991 {
       
   992     switch (image.format()) {
       
   993     case QImage::Format_ARGB32_Premultiplied:
       
   994         blit_template<qgray4, quint32>(screen, image, topLeft, region);
       
   995         return;
       
   996     case QImage::Format_RGB16:
       
   997         blit_template<qgray4, quint16>(screen, image, topLeft, region);
       
   998         return;
       
   999     case QImage::Format_RGB444:
       
  1000         blit_template<qgray4, qrgb444>(screen, image, topLeft, region);
       
  1001         return;
       
  1002     case QImage::Format_ARGB4444_Premultiplied:
       
  1003         blit_template<qgray4, qargb4444>(screen, image, topLeft, region);
       
  1004         return;
       
  1005     default:
       
  1006         qCritical("blit_4(): Image format %d not supported!", image.format());
       
  1007     }
       
  1008 }
       
  1009 #endif // QT_QWS_DEPTH_4
       
  1010 
       
  1011 #ifdef QT_QWS_DEPTH_1
       
  1012 
       
  1013 struct qmono { quint8 dummy; } Q_PACKED;
       
  1014 
       
  1015 template <typename SRC>
       
  1016 Q_STATIC_TEMPLATE_FUNCTION inline quint8 qt_convertToMono(SRC color);
       
  1017 
       
  1018 template <>
       
  1019 inline quint8 qt_convertToMono(quint32 color)
       
  1020 {
       
  1021     return qGray(color) >> 7;
       
  1022 }
       
  1023 
       
  1024 template <>
       
  1025 inline quint8 qt_convertToMono(quint16 color)
       
  1026 {
       
  1027     return (qGray(qt_colorConvert<quint32, quint16>(color, 0)) >> 7);
       
  1028 }
       
  1029 
       
  1030 template <>
       
  1031 inline quint8 qt_convertToMono(qargb4444 color)
       
  1032 {
       
  1033     return (qGray(quint32(color)) >> 7);
       
  1034 }
       
  1035 
       
  1036 template <>
       
  1037 inline quint8 qt_convertToMono(qrgb444 color)
       
  1038 {
       
  1039     return (qGray(quint32(color)) >> 7);
       
  1040 }
       
  1041 
       
  1042 template <typename SRC>
       
  1043 inline void qt_rectconvert_mono(qmono *dest, const SRC *src,
       
  1044                                        int x, int y, int width, int height,
       
  1045                                        int dstStride, int srcStride)
       
  1046 {
       
  1047     const int pixelsPerByte = 8;
       
  1048     quint8 *dest8 = reinterpret_cast<quint8*>(dest)
       
  1049                     + y * dstStride + x / pixelsPerByte;
       
  1050     const int alignWidth = qMin(width, (8 - (x & 7)) & 7);
       
  1051     const int doAlign = (alignWidth > 0 ? 1 : 0);
       
  1052     const int alignStart = pixelsPerByte - 1 - (x & 7);
       
  1053     const int alignStop = alignStart - (alignWidth - 1);
       
  1054     const quint8 alignMask = ((1 << alignWidth) - 1) << alignStop;
       
  1055     const int tailWidth = (width - alignWidth) & 7;
       
  1056     const int doTail = (tailWidth > 0 ? 1 : 0);
       
  1057     const quint8 tailMask = (1 << (pixelsPerByte - tailWidth)) - 1;
       
  1058     const int width8 = (width - alignWidth) / pixelsPerByte;
       
  1059 
       
  1060     srcStride = srcStride / sizeof(SRC) - (width8 * 8 + alignWidth);
       
  1061     dstStride -= (width8 + doAlign);
       
  1062 
       
  1063     for (int j = 0;  j < height; ++j) {
       
  1064         if (doAlign) {
       
  1065             quint8 d = *dest8 & ~alignMask;
       
  1066             for (int i = alignStart; i >= alignStop; --i)
       
  1067                 d |= qt_convertToMono<SRC>(*src++) << i;
       
  1068             *dest8++ = d;
       
  1069         }
       
  1070         for (int i = 0; i < width8; ++i) {
       
  1071             *dest8 = (qt_convertToMono<SRC>(src[0]) << 7)
       
  1072                      | (qt_convertToMono<SRC>(src[1]) << 6)
       
  1073                      | (qt_convertToMono<SRC>(src[2]) << 5)
       
  1074                      | (qt_convertToMono<SRC>(src[3]) << 4)
       
  1075                      | (qt_convertToMono<SRC>(src[4]) << 3)
       
  1076                      | (qt_convertToMono<SRC>(src[5]) << 2)
       
  1077                      | (qt_convertToMono<SRC>(src[6]) << 1)
       
  1078                      | (qt_convertToMono<SRC>(src[7]));
       
  1079             src += 8;
       
  1080             ++dest8;
       
  1081         }
       
  1082         if (doTail) {
       
  1083             quint8 d = *dest8 & tailMask;
       
  1084             switch (tailWidth) {
       
  1085             case 7: d |= qt_convertToMono<SRC>(src[6]) << 1;
       
  1086             case 6: d |= qt_convertToMono<SRC>(src[5]) << 2;
       
  1087             case 5: d |= qt_convertToMono<SRC>(src[4]) << 3;
       
  1088             case 4: d |= qt_convertToMono<SRC>(src[3]) << 4;
       
  1089             case 3: d |= qt_convertToMono<SRC>(src[2]) << 5;
       
  1090             case 2: d |= qt_convertToMono<SRC>(src[1]) << 6;
       
  1091             case 1: d |= qt_convertToMono<SRC>(src[0]) << 7;
       
  1092             }
       
  1093             *dest8 = d;
       
  1094         }
       
  1095 
       
  1096         dest8 += dstStride;
       
  1097         src += srcStride;
       
  1098     }
       
  1099 }
       
  1100 
       
  1101 template <>
       
  1102 void qt_rectconvert(qmono *dest, const quint32 *src,
       
  1103                     int x, int y, int width, int height,
       
  1104                     int dstStride, int srcStride)
       
  1105 {
       
  1106     qt_rectconvert_mono<quint32>(dest, src, x, y, width, height,
       
  1107                                  dstStride, srcStride);
       
  1108 }
       
  1109 
       
  1110 template <>
       
  1111 void qt_rectconvert(qmono *dest, const quint16 *src,
       
  1112                     int x, int y, int width, int height,
       
  1113                     int dstStride, int srcStride)
       
  1114 {
       
  1115     qt_rectconvert_mono<quint16>(dest, src, x, y, width, height,
       
  1116                                  dstStride, srcStride);
       
  1117 }
       
  1118 
       
  1119 template <>
       
  1120 void qt_rectconvert(qmono *dest, const qrgb444 *src,
       
  1121                     int x, int y, int width, int height,
       
  1122                     int dstStride, int srcStride)
       
  1123 {
       
  1124     qt_rectconvert_mono<qrgb444>(dest, src, x, y, width, height,
       
  1125                                  dstStride, srcStride);
       
  1126 }
       
  1127 
       
  1128 template <>
       
  1129 void qt_rectconvert(qmono *dest, const qargb4444 *src,
       
  1130                     int x, int y, int width, int height,
       
  1131                     int dstStride, int srcStride)
       
  1132 {
       
  1133     qt_rectconvert_mono<qargb4444>(dest, src, x, y, width, height,
       
  1134                                    dstStride, srcStride);
       
  1135 }
       
  1136 
       
  1137 static void blit_1(QScreen *screen, const QImage &image,
       
  1138                    const QPoint &topLeft, const QRegion &region)
       
  1139 {
       
  1140     switch (image.format()) {
       
  1141     case QImage::Format_ARGB32_Premultiplied:
       
  1142         blit_template<qmono, quint32>(screen, image, topLeft, region);
       
  1143         return;
       
  1144     case QImage::Format_RGB16:
       
  1145         blit_template<qmono, quint16>(screen, image, topLeft, region);
       
  1146         return;
       
  1147     case QImage::Format_RGB444:
       
  1148         blit_template<qmono, qrgb444>(screen, image, topLeft, region);
       
  1149         return;
       
  1150     case QImage::Format_ARGB4444_Premultiplied:
       
  1151         blit_template<qmono, qargb4444>(screen, image, topLeft, region);
       
  1152         return;
       
  1153     default:
       
  1154         qCritical("blit_1(): Image format %d not supported!", image.format());
       
  1155     }
       
  1156 }
       
  1157 #endif // QT_QWS_DEPTH_1
       
  1158 
       
  1159 #ifdef QT_QWS_DEPTH_GENERIC
       
  1160 
       
  1161 static void blit_rgb(QScreen *screen, const QImage &image,
       
  1162                      const QPoint &topLeft, const QRegion &region)
       
  1163 {
       
  1164     switch (image.format()) {
       
  1165     case QImage::Format_ARGB32_Premultiplied:
       
  1166         blit_template<qrgb, quint32>(screen, image, topLeft, region);
       
  1167         return;
       
  1168     case QImage::Format_RGB16:
       
  1169         blit_template<qrgb, quint16>(screen, image, topLeft, region);
       
  1170         return;
       
  1171     default:
       
  1172         qCritical("blit_rgb(): Image format %d not supported!", image.format());
       
  1173     }
       
  1174 }
       
  1175 
       
  1176 void qt_set_generic_blit(QScreen *screen, int bpp,
       
  1177                          int len_red, int len_green, int len_blue, int len_alpha,
       
  1178                          int off_red, int off_green, int off_blue, int off_alpha)
       
  1179 {
       
  1180     qrgb::bpp = bpp / 8;
       
  1181     qrgb::len_red = len_red;
       
  1182     qrgb::len_green = len_green;
       
  1183     qrgb::len_blue = len_blue;
       
  1184     qrgb::len_alpha = len_alpha;
       
  1185     qrgb::off_red = off_red;
       
  1186     qrgb::off_green = off_green;
       
  1187     qrgb::off_blue = off_blue;
       
  1188     qrgb::off_alpha = off_alpha;
       
  1189     screen->d_ptr->blit = blit_rgb;
       
  1190     if (bpp == 16)
       
  1191         screen->d_ptr->solidFill = solidFill_rgb_16bpp;
       
  1192     else if (bpp == 32)
       
  1193         screen->d_ptr->solidFill = solidFill_rgb_32bpp;
       
  1194 }
       
  1195 
       
  1196 #endif // QT_QWS_DEPTH_GENERIC
       
  1197 
       
  1198 void qt_blit_setup(QScreen *screen, const QImage &image,
       
  1199                    const QPoint &topLeft, const QRegion &region)
       
  1200 {
       
  1201     switch (screen->depth()) {
       
  1202 #ifdef QT_QWS_DEPTH_32
       
  1203     case 32:
       
  1204         if (screen->pixelType() == QScreen::NormalPixel)
       
  1205             screen->d_ptr->blit = blit_32;
       
  1206         else
       
  1207             screen->d_ptr->blit = blit_template<qabgr8888, quint32>;
       
  1208         break;
       
  1209 #endif
       
  1210 #ifdef QT_QWS_DEPTH_24
       
  1211     case 24:
       
  1212         if (screen->pixelType() == QScreen::NormalPixel)
       
  1213             screen->d_ptr->blit = blit_qrgb888;
       
  1214         else
       
  1215             screen->d_ptr->blit = blit_24;
       
  1216         break;
       
  1217 #endif
       
  1218 #ifdef QT_QWS_DEPTH_18
       
  1219     case 18:
       
  1220         screen->d_ptr->blit = blit_18;
       
  1221         break;
       
  1222 #endif
       
  1223 #ifdef QT_QWS_DEPTH_16
       
  1224     case 16:
       
  1225 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
       
  1226         if (screen->d_ptr->fb_is_littleEndian)
       
  1227             screen->d_ptr->blit = blit_16_bigToLittleEndian;
       
  1228         else
       
  1229 #endif
       
  1230         if (screen->pixelType() == QScreen::NormalPixel)
       
  1231             screen->d_ptr->blit = blit_16;
       
  1232         else
       
  1233             screen->d_ptr->blit = blit_template<qbgr565, quint16>;
       
  1234         break;
       
  1235 #endif
       
  1236 #ifdef QT_QWS_DEPTH_15
       
  1237     case 15:
       
  1238 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
       
  1239         if (screen->d_ptr->fb_is_littleEndian)
       
  1240             screen->d_ptr->blit = blit_15_bigToLittleEndian;
       
  1241         else
       
  1242 #endif // Q_BIG_ENDIAN
       
  1243         if (screen->pixelType() == QScreen::NormalPixel)
       
  1244             screen->d_ptr->blit = blit_15;
       
  1245         else
       
  1246             screen->d_ptr->blit = blit_template<qbgr555, qrgb555>;
       
  1247         break;
       
  1248 #endif
       
  1249 #ifdef QT_QWS_DEPTH_12
       
  1250     case 12:
       
  1251         screen->d_ptr->blit = blit_12;
       
  1252         break;
       
  1253 #endif
       
  1254 #ifdef QT_QWS_DEPTH_8
       
  1255     case 8:
       
  1256         screen->d_ptr->blit = blit_8;
       
  1257         break;
       
  1258 #endif
       
  1259 #ifdef QT_QWS_DEPTH_4
       
  1260     case 4:
       
  1261         screen->d_ptr->blit = blit_4;
       
  1262         break;
       
  1263 #endif
       
  1264 #ifdef QT_QWS_DEPTH_1
       
  1265     case 1:
       
  1266         screen->d_ptr->blit = blit_1;
       
  1267         break;
       
  1268 #endif
       
  1269     default:
       
  1270         qFatal("blit_setup(): Screen depth %d not supported!",
       
  1271                screen->depth());
       
  1272         screen->d_ptr->blit = 0;
       
  1273         break;
       
  1274     }
       
  1275     screen->d_ptr->blit(screen, image, topLeft, region);
       
  1276 }
       
  1277 
       
  1278 QScreenPrivate::QScreenPrivate(QScreen *parent, QScreen::ClassId id)
       
  1279     : defaultGraphicsSystem(QWSGraphicsSystem(parent)),
       
  1280       pixelFormat(QImage::Format_Invalid),
       
  1281 #ifdef QT_QWS_CLIENTBLIT
       
  1282       supportsBlitInClients(false),
       
  1283 #endif
       
  1284       classId(id), q_ptr(parent)
       
  1285 {
       
  1286     solidFill = qt_solidFill_setup;
       
  1287     blit = qt_blit_setup;
       
  1288 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
       
  1289     fb_is_littleEndian = false;
       
  1290 #endif
       
  1291     pixmapFactory = 0;
       
  1292     graphicsSystem = &defaultGraphicsSystem;
       
  1293 }
       
  1294 
       
  1295 QScreenPrivate::~QScreenPrivate()
       
  1296 {
       
  1297 }
       
  1298 
       
  1299 QImage::Format QScreenPrivate::preferredImageFormat() const
       
  1300 {
       
  1301     if (pixelFormat > QImage::Format_Indexed8)
       
  1302         return pixelFormat;
       
  1303 
       
  1304     if (q_ptr->depth() <= 16)
       
  1305         return QImage::Format_RGB16;
       
  1306     else
       
  1307         return QImage::Format_ARGB32_Premultiplied;
       
  1308 }
       
  1309 
       
  1310 /*!
       
  1311     \class QScreen
       
  1312     \ingroup qws
       
  1313 
       
  1314     \brief The QScreen class is a base class for screen drivers in
       
  1315     Qt for Embedded Linux.
       
  1316 
       
  1317     Note that this class is only available in \l{Qt for Embedded Linux}.
       
  1318 
       
  1319     \l{Qt for Embedded Linux} provides ready-made drivers for several screen
       
  1320     protocols, see the \l{Qt for Embedded Linux Display Management}{display
       
  1321     management} documentation for details. Custom screen drivers can
       
  1322     be implemented by subclassing the QScreen class and creating a
       
  1323     screen driver plugin (derived from QScreenDriverPlugin). The
       
  1324     default implementation of the QScreenDriverFactory class
       
  1325     will automatically detect the plugin, and load the driver into the
       
  1326     server application at run-time using Qt's \l {How to Create Qt
       
  1327     Plugins}{plugin system}.
       
  1328 
       
  1329     When rendering, the default behavior is for each
       
  1330     client to render its widgets as well as its decorations into
       
  1331     memory, while the server copies the memory content to the device's
       
  1332     framebuffer using the screen driver. See the \l{Qt for Embedded Linux
       
  1333     Architecture} overview for details (note that it is possible for
       
  1334     the clients to manipulate and control the underlying hardware
       
  1335     directly as well).
       
  1336 
       
  1337     Starting with Qt 4.2, it is also possible to add an
       
  1338     accelerated graphics driver to take advantage of available
       
  1339     hardware resources. See the \l{Adding an Accelerated Graphics
       
  1340     Driver to Qt for Embedded Linux} documentation for details.
       
  1341 
       
  1342     \tableofcontents
       
  1343 
       
  1344     \section1 Framebuffer Management
       
  1345 
       
  1346     When a \l{Qt for Embedded Linux} application starts running, it
       
  1347     calls the screen driver's connect() function to map the
       
  1348     framebuffer and the accelerated drivers that the graphics card
       
  1349     control registers. The connect() function should then read out the
       
  1350     parameters of the framebuffer and use them as required to set this
       
  1351     class's protected variables.
       
  1352 
       
  1353     The initDevice() function can be reimplemented to initialize the
       
  1354     graphics card. Note, however, that connect() is called \e before
       
  1355     the initDevice() function, so, for some hardware configurations,
       
  1356     some of the initialization that would normally be done in the
       
  1357     initDevice() function might have to be done in the connect()
       
  1358     function.
       
  1359 
       
  1360     Likewise, just before a \l{Qt for Embedded Linux} application
       
  1361     exits, it calls the screen driver's disconnect() function. The
       
  1362     server application will in addition call the shutdownDevice()
       
  1363     function before it calls disconnect(). Note that the default
       
  1364     implementation of the shutdownDevice() function only hides the
       
  1365     mouse cursor.
       
  1366 
       
  1367     QScreen also provides the save() and restore() functions, making
       
  1368     it possible to save and restore the state of the graphics
       
  1369     card. Note that the default implementations do nothing. Hardware
       
  1370     screen drivers should reimplement these functions to save (and
       
  1371     restore) its registers, enabling switching between virtual
       
  1372     consoles.
       
  1373 
       
  1374     In addition, you can use the base() function to retrieve a pointer
       
  1375     to the beginning of the framebuffer, and the region() function to
       
  1376     retrieve the framebuffer's region. Use the onCard() function to
       
  1377     determine whether the framebuffer is within the graphics card's
       
  1378     memory, and the totalSize() function to determine the size of the
       
  1379     available graphics card memory (including the screen). Finally,
       
  1380     you can use the offset() function to retrieve the offset between
       
  1381     the framebuffer's coordinates and the application's coordinate
       
  1382     system.
       
  1383 
       
  1384     \section1 Palette Management
       
  1385 
       
  1386     QScreen provides several functions to retrieve information about
       
  1387     the color palette: The clut() function returns a pointer to the
       
  1388     color lookup table (i.e. its color palette). Use the numCols()
       
  1389     function to determine the number of entries in this table, and the
       
  1390     alloc() function to retrieve the palette index of the color that
       
  1391     is the closest match to a given RGB value.
       
  1392 
       
  1393     To determine if the screen driver supports a given color depth,
       
  1394     use the supportsDepth() function that returns true of the
       
  1395     specified depth is supported.
       
  1396 
       
  1397     \section1 Drawing on Screen
       
  1398 
       
  1399     When a screen update is required, the \l{Qt for Embedded Linux} server runs
       
  1400     through all the top-level windows that intersect with the region
       
  1401     that is about to be updated, and ensures that the associated
       
  1402     clients have updated their memory buffer. Then the server calls
       
  1403     the exposeRegion() function that composes the window surfaces and
       
  1404     copies the content of memory to screen by calling the blit() and
       
  1405     solidFill() functions.
       
  1406 
       
  1407     The blit() function copies a given region in a given image to a
       
  1408     specified point using device coordinates, while the solidFill()
       
  1409     function fills the given region of the screen with the specified
       
  1410     color. Note that normally there is no need to call either of these
       
  1411     functions explicitly.
       
  1412 
       
  1413     In addition, QScreen provides the blank() function that can be
       
  1414     reimplemented to prevent any contents from being displayed on the
       
  1415     screen, and the setDirty() function that can be reimplemented to
       
  1416     indicate that a given rectangle of the screen has been
       
  1417     altered. Note that the default implementations of these functions
       
  1418     do nothing.
       
  1419 
       
  1420     Reimplement the mapFromDevice() and mapToDevice() functions to
       
  1421     map objects from the framebuffer coordinate system to the
       
  1422     coordinate space used by the application, and vice versa. Be aware
       
  1423     that the default implementations simply return the given objects
       
  1424     as they are.
       
  1425 
       
  1426     \section1 Properties
       
  1427 
       
  1428     \table
       
  1429     \header \o Property \o Functions
       
  1430     \row
       
  1431     \o Size
       
  1432     \o
       
  1433 
       
  1434     The size of the screen can be retrieved using the screenSize()
       
  1435     function. The size is returned in bytes.
       
  1436 
       
  1437     The framebuffer's logical width and height can be retrieved using
       
  1438     width() and height(), respectively. These functions return values
       
  1439     are given in pixels. Alternatively, the physicalWidth() and
       
  1440     physicalHeight() function returns the same metrics in
       
  1441     millimeters. QScreen also provides the deviceWidth() and
       
  1442     deviceHeight() functions returning the physical width and height
       
  1443     of the device in pixels. Note that the latter metrics can differ
       
  1444     from the ones used if the display is centered within the
       
  1445     framebuffer.
       
  1446 
       
  1447     \row
       
  1448     \o Resolution
       
  1449     \o
       
  1450 
       
  1451     Reimplement the setMode() function to be able to set the
       
  1452     framebuffer to a new resolution (width and height) and bit depth.
       
  1453 
       
  1454     The current depth of the framebuffer can be always be retrieved
       
  1455     using the depth() function. Use the pixmapDepth() function to
       
  1456     obtain the preferred depth for pixmaps.
       
  1457 
       
  1458     \row
       
  1459     \o Pixmap Alignment
       
  1460     \o
       
  1461 
       
  1462     Use the pixmapOffsetAlignment() function to retrieve the value to
       
  1463     which the start address of pixmaps held in the graphics card's
       
  1464     memory, should be aligned.
       
  1465 
       
  1466     Use the pixmapLinestepAlignment() to retrieve the value to which
       
  1467     the \e {individual scanlines} of pixmaps should be aligned.
       
  1468 
       
  1469     \row
       
  1470     \o Image Display
       
  1471     \o
       
  1472 
       
  1473     The isInterlaced() function tells whether the screen is displaying
       
  1474     images progressively, and the isTransformed() function whether it
       
  1475     is rotated. The transformOrientation() function can be
       
  1476     reimplemented to return the current rotation.
       
  1477 
       
  1478     \row
       
  1479     \o Scanlines
       
  1480     \o
       
  1481 
       
  1482     Use the linestep() function to retrieve the length of each
       
  1483     scanline of the framebuffer.
       
  1484 
       
  1485     \row
       
  1486     \o Pixel Type
       
  1487     \o
       
  1488 
       
  1489     The pixelType() function returns the screen's pixel storage format as
       
  1490     described by the PixelType enum.
       
  1491 
       
  1492     \endtable
       
  1493 
       
  1494     \section1 Subclassing and Initial Values
       
  1495 
       
  1496     You need to set the following members when implementing a subclass of QScreen:
       
  1497 
       
  1498     \table
       
  1499     \header \o Member \o Initial Value
       
  1500     \row \o \l{QScreen::}{data} \o A pointer to the framebuffer if possible;
       
  1501     0 otherwise.
       
  1502     \row \o \l{QScreen::}{lstep} \o The number of bytes between each scanline
       
  1503     in the framebuffer.
       
  1504     \row \o \l{QScreen::}{w} \o The logical screen width in pixels.
       
  1505     \row \o \l{QScreen::}{h} \o The logical screen height in pixels.
       
  1506     \row \o \l{QScreen::}{dw} \o The real screen width in pixels.
       
  1507     \row \o \l{QScreen::}{dh} \o The real screen height in pixels.
       
  1508     \row \o \l{QScreen::}{d} \o The number of bits per pixel.
       
  1509     \row \o \l{QScreen::}{physWidth} \o The screen width in millimeters.
       
  1510     \row \o \l{QScreen::}{physHeight} \o The screen height in millimeters.
       
  1511     \endtable
       
  1512 
       
  1513     The logical screen values are the same as the real screen values unless the
       
  1514     screen is transformed in some way; e.g., rotated.
       
  1515 
       
  1516     See also the \l{Accelerated Graphics Driver Example} for an example that
       
  1517     shows how to initialize these values.
       
  1518 
       
  1519     \sa QScreenDriverPlugin, QScreenDriverFactory, {Qt for Embedded Linux Display
       
  1520     Management}
       
  1521 */
       
  1522 
       
  1523 /*!
       
  1524     \enum QScreen::PixelType
       
  1525 
       
  1526     This enum describes the pixel storage format of the screen,
       
  1527     i.e. the order of the red (R), green (G) and blue (B) components
       
  1528     of a pixel.
       
  1529 
       
  1530     \value NormalPixel Red-green-blue (RGB)
       
  1531     \value BGRPixel Blue-green-red (BGR)
       
  1532 
       
  1533     \sa pixelType()
       
  1534 */
       
  1535 
       
  1536 /*!
       
  1537     \enum QScreen::ClassId
       
  1538 
       
  1539     This enum defines the class identifiers for the known screen subclasses.
       
  1540 
       
  1541     \value LinuxFBClass QLinuxFBScreen
       
  1542     \value TransformedClass QTransformedScreen
       
  1543     \value VNCClass QVNCScreen
       
  1544     \value MultiClass QMultiScreen
       
  1545     \value VFbClass QVFbScreen
       
  1546     \value DirectFBClass QDirectFBScreen
       
  1547     \value SvgalibClass QSvgalibScreen
       
  1548     \value ProxyClass QProxyScreen
       
  1549     \value GLClass QGLScreen
       
  1550     \value CustomClass Unknown QScreen subclass
       
  1551 
       
  1552     \sa classId()
       
  1553 */
       
  1554 
       
  1555 /*!
       
  1556   \variable QScreen::screenclut
       
  1557   \brief the color table
       
  1558 
       
  1559   Initialize this variable in a subclass using a paletted screen mode,
       
  1560   and initialize its partner, QScreen::screencols.
       
  1561 
       
  1562   \sa screencols
       
  1563 */
       
  1564 
       
  1565 /*!
       
  1566   \variable QScreen::screencols
       
  1567   \brief the number of entries in the color table
       
  1568 
       
  1569   Initialize this variable in a subclass using a paletted screen mode,
       
  1570   and initialize its partner, QScreen::screenclut.
       
  1571 
       
  1572   \sa screenclut
       
  1573 */
       
  1574 
       
  1575 /*!
       
  1576   \variable QScreen::data
       
  1577   \brief points to the first visible pixel in the frame buffer.
       
  1578 
       
  1579   You must initialize this variable if you are using the default
       
  1580   implementation of non-buffered painting Qt::WA_PaintOnScreen,
       
  1581   QPixmap::grabWindow() or QDirectPainter::frameBuffer(). If you
       
  1582   initialize this variable, you must also initialize QScreen::size and
       
  1583   QScreen::mapsize.
       
  1584 
       
  1585   \sa QScreen::size, QScreen::mapsize
       
  1586 */
       
  1587 
       
  1588 /*!
       
  1589   \variable QScreen::w
       
  1590   \brief the logical width of the screen.
       
  1591 
       
  1592   This variable \e{must} be initialized by a subclass.
       
  1593 */
       
  1594 
       
  1595 /*!
       
  1596   \variable QScreen::lstep
       
  1597   \brief the number of bytes representing a line in the frame buffer.
       
  1598 
       
  1599   i.e., \e{line step}. \c {data[lstep * 2]} is the address of the
       
  1600   first visible pixel in the third line of the frame buffer.
       
  1601 
       
  1602   \sa data
       
  1603 */
       
  1604 
       
  1605 /*!
       
  1606   \variable QScreen::h
       
  1607   \brief the logical height of the screen.
       
  1608 
       
  1609   This variable \e{must} be initialized by a subclass.
       
  1610 */
       
  1611 
       
  1612 /*!
       
  1613   \variable QScreen::d
       
  1614   \brief the pixel depth
       
  1615 
       
  1616   This is the number of significant bits used to set a pixel
       
  1617   color. This variable \e{must} be initialized by a subclass.
       
  1618 */
       
  1619 
       
  1620 /*!
       
  1621   \variable QScreen::pixeltype
       
  1622   \brief set to BGRPixel
       
  1623 
       
  1624   Set this variable to BGRPixel in a subclass, if the screen pixel
       
  1625   format is a BGR type and you have used setPixelFormat() to set the
       
  1626   pixel format to the corresponding RGB format. e.g., you have set the
       
  1627   pixel format to QImage::Format_RGB555, but your screen really uses
       
  1628   BGR, not RGB.
       
  1629 */
       
  1630 
       
  1631 /*!
       
  1632   \variable QScreen::grayscale
       
  1633   \brief the gray scale screen mode flag
       
  1634 
       
  1635   Set this variable to true in a subclass, if you are using a
       
  1636   grayscale screen mode. e.g., in an 8-bit mode where you don't want
       
  1637   to use the palette, but you want to use the grayscales.
       
  1638 */
       
  1639 
       
  1640 /*!
       
  1641   \variable QScreen::dw
       
  1642   \brief the device width
       
  1643 
       
  1644   This is the number of pixels in a row of the physical screen.  It
       
  1645   \e{must} be initialized by a subclass. Normally, it should be set to
       
  1646   the logical width QScreen::w, but it might be different, e.g., if
       
  1647   you are doing rotations in software.
       
  1648 
       
  1649   \sa QScreen::w
       
  1650 */
       
  1651 
       
  1652 /*!
       
  1653   \variable QScreen::dh
       
  1654   \brief the device height
       
  1655 
       
  1656   This is the number of pixels in a column of the physical screen.  It
       
  1657   \e{must} be initialized by a subclass. Normally, it should be set to
       
  1658   the logical height QScreen::h, but it might be different, e.g., if
       
  1659   you are doing rotations in software.
       
  1660 
       
  1661   \sa QScreen::h
       
  1662 */
       
  1663 
       
  1664 /*!
       
  1665   \variable QScreen::size
       
  1666   \brief the number of bytes in the visible region of the frame buffer
       
  1667 
       
  1668   This is the number of bytes in the visible part of the block pointed
       
  1669   to by the QScreen::data pointer. You must initialize this variable
       
  1670   if you initialize the QScreen::data pointer.
       
  1671 
       
  1672   \sa QScreen::data, QScreen::mapsize
       
  1673 */
       
  1674 
       
  1675 /*!
       
  1676   \variable QScreen::mapsize
       
  1677   \brief the total number of bytes in the frame buffer
       
  1678 
       
  1679   This is the total number of bytes in the block pointed to by the
       
  1680   QScreen::data pointer. You must initialize this variable if you
       
  1681   initialize the QScreen::data pointer.
       
  1682 
       
  1683   \sa QScreen::data, QScreen::size
       
  1684 */
       
  1685 
       
  1686 /*!
       
  1687   \variable QScreen::physWidth
       
  1688   \brief the physical width of the screen in millimeters.
       
  1689 
       
  1690   Currently, this variable is used when calculating the screen DPI,
       
  1691   which in turn is used when deciding the actual font size Qt is
       
  1692   using.
       
  1693 */
       
  1694 
       
  1695 /*!
       
  1696   \variable QScreen::physHeight
       
  1697   \brief the physical height of the screen in millimeters.
       
  1698 
       
  1699   Currently, this variable is used when calculating the screen DPI,
       
  1700   which in turn is used when deciding the actual font size Qt is
       
  1701   using.
       
  1702 */
       
  1703 
       
  1704 /*!
       
  1705     \fn static QScreen* QScreen::instance()
       
  1706 
       
  1707     Returns a pointer to the application's QScreen instance.
       
  1708 
       
  1709     If this screen consists of several subscreens, operations to the
       
  1710     returned instance will affect all its subscreens. Use the
       
  1711     subscreens() function to retrieve access to a particular
       
  1712     subscreen.
       
  1713 
       
  1714     \sa subScreens(), subScreenIndexAt()
       
  1715 */
       
  1716 
       
  1717 /*!
       
  1718     \fn QList<QScreen*> QScreen::subScreens() const
       
  1719     \since 4.2
       
  1720 
       
  1721     Returns a list of this screen's subscreens. Use the
       
  1722     subScreenIndexAt() function to retrieve the index of a screen at a
       
  1723     given position.
       
  1724 
       
  1725     Note that if \e this screen consists of several subscreens,
       
  1726     operations to \e this instance will affect all subscreens by
       
  1727     default.
       
  1728 
       
  1729     \sa instance(), subScreenIndexAt()
       
  1730 */
       
  1731 
       
  1732 /*!
       
  1733     \fn int QScreen::physicalWidth() const
       
  1734     \since 4.2
       
  1735 
       
  1736     Returns the physical width of the screen in millimeters.
       
  1737 
       
  1738     \sa width(), deviceWidth(), physicalHeight()
       
  1739 */
       
  1740 
       
  1741 /*!
       
  1742     \fn int QScreen::physicalHeight() const
       
  1743     \since 4.2
       
  1744 
       
  1745     Returns the physical height of the screen in millimeters.
       
  1746 
       
  1747     \sa height(), deviceHeight(), physicalWidth()
       
  1748 */
       
  1749 
       
  1750 /*!
       
  1751     \fn virtual bool QScreen::initDevice() = 0
       
  1752 
       
  1753     This function is called by the \l{Qt for Embedded Linux} server to
       
  1754     initialize the framebuffer. Note that a server application will call the
       
  1755     connect() function prior to this function.
       
  1756 
       
  1757     Implement this function to make accelerated drivers set up the
       
  1758     graphics card. Return true to indicate success and false to indicate
       
  1759     failure.
       
  1760 
       
  1761     \sa shutdownDevice(), connect()
       
  1762 */
       
  1763 
       
  1764 /*!
       
  1765     \fn virtual bool QScreen::connect(const QString &displaySpec) = 0
       
  1766 
       
  1767     This function is called by every \l{Qt for Embedded Linux}
       
  1768     application on startup, and must be implemented to map in the
       
  1769     framebuffer and the accelerated drivers that the graphics card
       
  1770     control registers.  Note that coonnect must be called \e before
       
  1771     the initDevice() function.
       
  1772 
       
  1773     Ensure that true is returned if a connection to the screen device
       
  1774     is made. Otherwise, return false. Upon making the connection, the
       
  1775     function should read out the parameters of the framebuffer and use
       
  1776     them as required to set this class's protected variables.
       
  1777 
       
  1778     The \a displaySpec argument is passed by the QWS_DISPLAY
       
  1779     environment variable or the -display command line parameter, and
       
  1780     has the following syntax:
       
  1781 
       
  1782     \snippet doc/src/snippets/code/src_gui_embedded_qscreen_qws.cpp 0
       
  1783 
       
  1784     For example, to use the mach64 driver on fb1 as display 2:
       
  1785 
       
  1786     \snippet doc/src/snippets/code/src_gui_embedded_qscreen_qws.cpp 1
       
  1787 
       
  1788     See \l{Qt for Embedded Linux Display Management} for more details.
       
  1789 
       
  1790     \sa disconnect(), initDevice(), {Running Qt for Embedded Linux Applications}
       
  1791 */
       
  1792 
       
  1793 /*!
       
  1794     \fn QScreen::disconnect()
       
  1795 
       
  1796     This function is called by every \l{Qt for Embedded Linux} application
       
  1797     before exiting, and must be implemented to unmap the
       
  1798     framebuffer. Note that a server application will call the
       
  1799     shutdownDevice() function prior to this function.
       
  1800 
       
  1801     \sa connect(), shutdownDevice(), {Running Qt for Embedded Linux
       
  1802     Applications}
       
  1803 */
       
  1804 
       
  1805 /*!
       
  1806     \fn QScreen::setMode(int width, int height, int depth)
       
  1807 
       
  1808     Implement this function to reset the framebuffer's resolution (\a
       
  1809     width and \a height) and bit \a depth.
       
  1810 
       
  1811     After the resolution has been set, existing paint engines will be
       
  1812     invalid and the framebuffer should be completely redrawn. In a
       
  1813     multiple-process situation, all other applications must be
       
  1814     notified to reset their mode and update themselves accordingly.
       
  1815 */
       
  1816 
       
  1817 /*!
       
  1818     \fn QScreen::blank(bool on)
       
  1819 
       
  1820     Prevents the screen driver form displaying any content on the
       
  1821     screen.
       
  1822 
       
  1823     Note that the default implementation does nothing.
       
  1824 
       
  1825     Reimplement this function to prevent the screen driver from
       
  1826     displaying any contents on the screen if \a on is true; otherwise
       
  1827     the contents is expected to be shown.
       
  1828 
       
  1829     \sa blit()
       
  1830 */
       
  1831 
       
  1832 /*!
       
  1833     \fn int QScreen::pixmapOffsetAlignment()
       
  1834 
       
  1835     Returns the value (in bits) to which the start address of pixmaps
       
  1836     held in the graphics card's memory, should be aligned.
       
  1837 
       
  1838     Note that the default implementation returns 64; reimplement this
       
  1839     function to override the return value, e.g., when implementing an
       
  1840     accelerated driver (see the \l {Adding an Accelerated Graphics
       
  1841     Driver to Qt for Embedded Linux}{Adding an Accelerated Graphics Driver}
       
  1842     documentation for details).
       
  1843 
       
  1844     \sa pixmapLinestepAlignment()
       
  1845 */
       
  1846 
       
  1847 /*!
       
  1848     \fn int QScreen::pixmapLinestepAlignment()
       
  1849 
       
  1850     Returns the value (in bits) to which individual scanlines of
       
  1851     pixmaps held in the graphics card's memory, should be
       
  1852     aligned.
       
  1853 
       
  1854     Note that the default implementation returns 64; reimplement this
       
  1855     function to override the return value, e.g., when implementing an
       
  1856     accelerated driver (see the \l {Adding an Accelerated Graphics
       
  1857     Driver to Qt for Embedded Linux}{Adding an Accelerated Graphics Driver}
       
  1858     documentation for details).
       
  1859 
       
  1860     \sa pixmapOffsetAlignment()
       
  1861 */
       
  1862 
       
  1863 /*!
       
  1864     \fn QScreen::width() const
       
  1865 
       
  1866     Returns the logical width of the framebuffer in pixels.
       
  1867 
       
  1868     \sa deviceWidth(), physicalWidth(), height()
       
  1869 */
       
  1870 
       
  1871 /*!
       
  1872     \fn int QScreen::height() const
       
  1873 
       
  1874     Returns the logical height of the framebuffer in pixels.
       
  1875 
       
  1876     \sa deviceHeight(), physicalHeight(), width()
       
  1877 */
       
  1878 
       
  1879 /*!
       
  1880     \fn QScreen::depth() const
       
  1881 
       
  1882     Returns the depth of the framebuffer, in bits per pixel.
       
  1883 
       
  1884     Note that the returned depth is the number of bits each pixel
       
  1885     fills rather than the number of significant bits, so 24bpp and
       
  1886     32bpp express the same range of colors (8 bits of red, green and
       
  1887     blue).
       
  1888 
       
  1889     \sa clut(), pixmapDepth()
       
  1890 */
       
  1891 
       
  1892 /*!
       
  1893     \fn int QScreen::pixmapDepth() const
       
  1894 
       
  1895     Returns the preferred depth for pixmaps, in bits per pixel.
       
  1896 
       
  1897     \sa depth()
       
  1898 */
       
  1899 
       
  1900 /*!
       
  1901     \fn QScreen::linestep() const
       
  1902 
       
  1903     Returns the length of each scanline of the framebuffer in bytes.
       
  1904 
       
  1905     \sa isInterlaced()
       
  1906 */
       
  1907 
       
  1908 /*!
       
  1909     \fn QScreen::deviceWidth() const
       
  1910 
       
  1911     Returns the physical width of the framebuffer device in pixels.
       
  1912 
       
  1913     Note that the returned width can differ from the width which
       
  1914     \l{Qt for Embedded Linux} will actually use, that is if the display is
       
  1915     centered within the framebuffer.
       
  1916 
       
  1917     \sa width(), physicalWidth(), deviceHeight()
       
  1918 */
       
  1919 
       
  1920 /*!
       
  1921     \fn QScreen::deviceHeight() const
       
  1922 
       
  1923     Returns the full height of the framebuffer device in pixels.
       
  1924 
       
  1925     Note that the returned height can differ from the height which
       
  1926     \l{Qt for Embedded Linux} will actually use, that is if the display is
       
  1927     centered within the framebuffer.
       
  1928 
       
  1929     \sa height(), physicalHeight(), deviceWidth()
       
  1930 */
       
  1931 
       
  1932 /*!
       
  1933     \fn uchar *QScreen::base() const
       
  1934 
       
  1935     Returns a pointer to the beginning of the framebuffer.
       
  1936 
       
  1937     \sa onCard(), region(), totalSize()
       
  1938 */
       
  1939 
       
  1940 /*!
       
  1941     \fn uchar *QScreen::cache(int)
       
  1942 
       
  1943     \internal
       
  1944 
       
  1945     This function is used to store pixmaps in graphics memory for the
       
  1946     use of the accelerated drivers. See QLinuxFbScreen (where the
       
  1947     caching is implemented) for more information.
       
  1948 */
       
  1949 
       
  1950 /*!
       
  1951     \fn QScreen::uncache(uchar *)
       
  1952 
       
  1953     \internal
       
  1954 
       
  1955     This function is called on pixmap destruction to remove them from
       
  1956     graphics card memory.
       
  1957 */
       
  1958 
       
  1959 /*!
       
  1960     \fn QScreen::screenSize() const
       
  1961 
       
  1962     Returns the size of the screen in bytes.
       
  1963 
       
  1964     The screen size is always located at the beginning of framebuffer
       
  1965     memory, i.e. it can also be retrieved using the base() function.
       
  1966 
       
  1967     \sa base(), region()
       
  1968 */
       
  1969 
       
  1970 /*!
       
  1971     \fn QScreen::totalSize() const
       
  1972 
       
  1973     Returns the size of the available graphics card memory (including
       
  1974     the screen) in bytes.
       
  1975 
       
  1976     \sa onCard()
       
  1977 */
       
  1978 
       
  1979 // Unaccelerated screen/driver setup. Can be overridden by accelerated
       
  1980 // drivers
       
  1981 
       
  1982 /*!
       
  1983     \fn QScreen::QScreen(int displayId)
       
  1984 
       
  1985     Constructs a new screen driver.
       
  1986 
       
  1987     The \a displayId identifies the \l{Qt for Embedded Linux} server to connect
       
  1988     to.
       
  1989 */
       
  1990 
       
  1991 /*!
       
  1992     \fn QScreen::clut()
       
  1993 
       
  1994     Returns a pointer to the screen's color lookup table (i.e. its
       
  1995     color palette).
       
  1996 
       
  1997     Note that this function only apply in paletted modes like 8-bit,
       
  1998     i.e. in modes where only the palette indexes (and not the actual
       
  1999     color values) are stored in memory.
       
  2000 
       
  2001     \sa alloc(), depth(), numCols()
       
  2002 */
       
  2003 
       
  2004 /*!
       
  2005     \fn int QScreen::numCols()
       
  2006 
       
  2007     Returns the number of entries in the screen's color lookup table
       
  2008     (i.e. its color palette). A pointer to the color table can be
       
  2009     retrieved using the clut() function.
       
  2010 
       
  2011     \sa clut(), alloc()
       
  2012 */
       
  2013 
       
  2014 /*!
       
  2015     \since 4.4
       
  2016 
       
  2017     Constructs a new screen driver.
       
  2018 
       
  2019     The \a display_id identifies the \l{Qt for Embedded Linux}
       
  2020     server to connect to. The \a classId specifies the class
       
  2021     identifier.
       
  2022 */
       
  2023 QScreen::QScreen(int display_id, ClassId classId)
       
  2024     : screencols(0), data(0), entries(0), entryp(0), lowest(0),
       
  2025       w(0), lstep(0), h(0), d(1), pixeltype(NormalPixel), grayscale(false),
       
  2026       dw(0), dh(0), size(0), mapsize(0), displayId(display_id),
       
  2027       physWidth(0), physHeight(0), d_ptr(new QScreenPrivate(this, classId))
       
  2028 {
       
  2029     clearCacheFunc = 0;
       
  2030 }
       
  2031 
       
  2032 QScreen::QScreen(int display_id)
       
  2033     : screencols(0), data(0), entries(0), entryp(0), lowest(0),
       
  2034       w(0), lstep(0), h(0), d(1), pixeltype(NormalPixel), grayscale(false),
       
  2035       dw(0), dh(0), size(0), mapsize(0), displayId(display_id),
       
  2036       physWidth(0), physHeight(0), d_ptr(new QScreenPrivate(this))
       
  2037 {
       
  2038     clearCacheFunc = 0;
       
  2039 }
       
  2040 
       
  2041 /*!
       
  2042     Destroys this screen driver.
       
  2043 */
       
  2044 
       
  2045 QScreen::~QScreen()
       
  2046 {
       
  2047     delete d_ptr;
       
  2048 }
       
  2049 
       
  2050 /*!
       
  2051     This function is called by the \l{Qt for Embedded Linux} server before it
       
  2052     calls the disconnect() function when exiting.
       
  2053 
       
  2054     Note that the default implementation only hides the mouse cursor;
       
  2055     reimplement this function to do the necessary graphics card
       
  2056     specific cleanup.
       
  2057 
       
  2058     \sa initDevice(), disconnect()
       
  2059 */
       
  2060 
       
  2061 void QScreen::shutdownDevice()
       
  2062 {
       
  2063 #ifndef QT_NO_QWS_CURSOR
       
  2064     if (qt_screencursor)
       
  2065         qt_screencursor->hide();
       
  2066 #endif
       
  2067 }
       
  2068 
       
  2069 extern bool qws_accel; //in qapplication_qws.cpp
       
  2070 
       
  2071 /*!
       
  2072     \fn PixelType QScreen::pixelType() const
       
  2073 
       
  2074     Returns the pixel storage format of the screen.
       
  2075 */
       
  2076 
       
  2077 /*!
       
  2078   Returns the pixel format of the screen, or \c QImage::Format_Invalid
       
  2079   if the pixel format is not a supported image format.
       
  2080 
       
  2081 */
       
  2082 QImage::Format QScreen::pixelFormat() const
       
  2083 {
       
  2084     return d_ptr->pixelFormat;
       
  2085 }
       
  2086 
       
  2087 /*!
       
  2088   Sets the screen's pixel format to \a format.
       
  2089  */
       
  2090 void QScreen::setPixelFormat(QImage::Format format)
       
  2091 {
       
  2092     d_ptr->pixelFormat = format;
       
  2093 }
       
  2094 
       
  2095 
       
  2096 /*!
       
  2097     \fn int QScreen::alloc(unsigned int red, unsigned int green, unsigned int blue)
       
  2098 
       
  2099     Returns the index in the screen's palette which is the closest
       
  2100     match to the given RGB value (\a red, \a green, \a blue).
       
  2101 
       
  2102     Note that this function only apply in paletted modes like 8-bit,
       
  2103     i.e. in modes where only the palette indexes (and not the actual
       
  2104     color values) are stored in memory.
       
  2105 
       
  2106     \sa clut(), numCols()
       
  2107 */
       
  2108 
       
  2109 int QScreen::alloc(unsigned int r,unsigned int g,unsigned int b)
       
  2110 {
       
  2111     int ret = 0;
       
  2112     if (d == 8) {
       
  2113         if (grayscale)
       
  2114             return qGray(r, g, b);
       
  2115 
       
  2116         // First we look to see if we match a default color
       
  2117         const int pos = (r + 25) / 51 * 36 + (g + 25) / 51 * 6 + (b + 25) / 51;
       
  2118         if (pos < screencols && screenclut[pos] == qRgb(r, g, b)) {
       
  2119             return pos;
       
  2120         }
       
  2121 
       
  2122         // search for nearest color
       
  2123         unsigned int mindiff = 0xffffffff;
       
  2124         unsigned int diff;
       
  2125         int dr,dg,db;
       
  2126 
       
  2127         for (int loopc = 0; loopc < screencols; ++loopc) {
       
  2128             dr = qRed(screenclut[loopc]) - r;
       
  2129             dg = qGreen(screenclut[loopc]) - g;
       
  2130             db = qBlue(screenclut[loopc]) - b;
       
  2131             diff = dr*dr + dg*dg + db*db;
       
  2132 
       
  2133             if (diff < mindiff) {
       
  2134                 ret = loopc;
       
  2135                 if (!diff)
       
  2136                     break;
       
  2137                 mindiff = diff;
       
  2138             }
       
  2139         }
       
  2140     } else if (d == 4) {
       
  2141         ret = qGray(r, g, b) >> 4;
       
  2142     } else if (d == 1) {
       
  2143         ret = qGray(r, g, b) >= 128;
       
  2144     } else {
       
  2145         qFatal("cannot alloc %dbpp color", d);
       
  2146     }
       
  2147 
       
  2148     return ret;
       
  2149 }
       
  2150 
       
  2151 /*!
       
  2152     Saves the current state of the graphics card.
       
  2153 
       
  2154     For example, hardware screen drivers should reimplement the save()
       
  2155     and restore() functions to save and restore its registers,
       
  2156     enabling swintching between virtual consoles.
       
  2157 
       
  2158     Note that the default implementation does nothing.
       
  2159 
       
  2160     \sa restore()
       
  2161 */
       
  2162 
       
  2163 void QScreen::save()
       
  2164 {
       
  2165 }
       
  2166 
       
  2167 /*!
       
  2168     Restores the previously saved state of the graphics card.
       
  2169 
       
  2170     For example, hardware screen drivers should reimplement the save()
       
  2171     and restore() functions to save and restore its registers,
       
  2172     enabling swintching between virtual consoles.
       
  2173 
       
  2174     Note that the default implementation does nothing.
       
  2175 
       
  2176     \sa save()
       
  2177 */
       
  2178 
       
  2179 void QScreen::restore()
       
  2180 {
       
  2181 }
       
  2182 
       
  2183 void QScreen::blank(bool)
       
  2184 {
       
  2185 }
       
  2186 
       
  2187 /*!
       
  2188     \internal
       
  2189 */
       
  2190 
       
  2191 void QScreen::set(unsigned int, unsigned int, unsigned int, unsigned int)
       
  2192 {
       
  2193 }
       
  2194 
       
  2195 /*!
       
  2196     \fn bool QScreen::supportsDepth(int depth) const
       
  2197 
       
  2198     Returns true if the screen supports the specified color \a depth;
       
  2199     otherwise returns false.
       
  2200 
       
  2201     \sa clut()
       
  2202 */
       
  2203 
       
  2204 bool QScreen::supportsDepth(int d) const
       
  2205 {
       
  2206     if (false) {
       
  2207         //Just to simplify the ifdeffery
       
  2208 #ifdef QT_QWS_DEPTH_1
       
  2209     } else if(d==1) {
       
  2210         return true;
       
  2211 #endif
       
  2212 #ifdef QT_QWS_DEPTH_4
       
  2213     } else if(d==4) {
       
  2214         return true;
       
  2215 #endif
       
  2216 #ifdef QT_QWS_DEPTH_8
       
  2217     } else if(d==8) {
       
  2218         return true;
       
  2219 #endif
       
  2220 #ifdef QT_QWS_DEPTH_16
       
  2221     } else if(d==16) {
       
  2222         return true;
       
  2223 #endif
       
  2224 #ifdef QT_QWS_DEPTH_15
       
  2225     } else if (d == 15) {
       
  2226         return true;
       
  2227 #endif
       
  2228 #ifdef QT_QWS_DEPTH_18
       
  2229     } else if(d==18 || d==19) {
       
  2230         return true;
       
  2231 #endif
       
  2232 #ifdef QT_QWS_DEPTH_24
       
  2233     } else if(d==24) {
       
  2234         return true;
       
  2235 #endif
       
  2236 #ifdef QT_QWS_DEPTH_32
       
  2237     } else if(d==32) {
       
  2238         return true;
       
  2239 #endif
       
  2240     }
       
  2241     return false;
       
  2242 }
       
  2243 
       
  2244 /*!
       
  2245     \fn bool QScreen::onCard(const unsigned char *buffer) const
       
  2246 
       
  2247     Returns true if the specified \a buffer is within the graphics
       
  2248     card's memory; otherwise returns false (i.e. if it's in main RAM).
       
  2249 
       
  2250     \sa base(), totalSize()
       
  2251 */
       
  2252 
       
  2253 bool QScreen::onCard(const unsigned char * p) const
       
  2254 {
       
  2255     long t=(unsigned long)p;
       
  2256     long bmin=(unsigned long)data;
       
  2257     if (t < bmin)
       
  2258         return false;
       
  2259     if(t >= bmin+mapsize)
       
  2260         return false;
       
  2261     return true;
       
  2262 }
       
  2263 
       
  2264 /*!
       
  2265     \fn bool QScreen::onCard(const unsigned char * buffer, ulong& offset) const
       
  2266     \overload
       
  2267 
       
  2268     If the specified \a buffer is within the graphics card's memory,
       
  2269     this function stores the offset from the start of graphics card
       
  2270     memory (in bytes), in the location specified by the \a offset
       
  2271     parameter.
       
  2272 */
       
  2273 
       
  2274 bool QScreen::onCard(const unsigned char * p, ulong& offset) const
       
  2275 {
       
  2276     long t=(unsigned long)p;
       
  2277     long bmin=(unsigned long)data;
       
  2278     if (t < bmin)
       
  2279         return false;
       
  2280     long o = t - bmin;
       
  2281     if (o >= mapsize)
       
  2282         return false;
       
  2283     offset = o;
       
  2284     return true;
       
  2285 }
       
  2286 
       
  2287 /*
       
  2288 #if !defined(QT_NO_QWS_REPEATER)
       
  2289     { "Repeater", qt_get_screen_repeater, 0 },
       
  2290 #endif
       
  2291 #if defined(QT_QWS_EE)
       
  2292     { "EE", qt_get_screen_ee, 0 },
       
  2293 #endif
       
  2294 
       
  2295 */
       
  2296 
       
  2297 /*
       
  2298 Given a display_id (number of the \l{Qt for Embedded Linux} server to connect to)
       
  2299 and a spec (e.g. Mach64:/dev/fb0) return a QScreen-descendant.
       
  2300 The QScreenDriverFactory is queried for a suitable driver and, if found,
       
  2301 asked to create a driver.
       
  2302 People writing new graphics drivers should either hook their own
       
  2303 QScreen-descendant into QScreenDriverFactory or use the QScreenDriverPlugin
       
  2304 to make a dynamically loadable driver.
       
  2305 */
       
  2306 
       
  2307 Q_GUI_EXPORT QScreen* qt_get_screen(int display_id, const char *spec)
       
  2308 {
       
  2309     QString displaySpec = QString::fromAscii(spec);
       
  2310     QString driver = displaySpec;
       
  2311     int colon = displaySpec.indexOf(QLatin1Char(':'));
       
  2312     if (colon >= 0)
       
  2313         driver.truncate(colon);
       
  2314     driver = driver.trimmed();
       
  2315 
       
  2316     bool foundDriver = false;
       
  2317     QString driverName = driver;
       
  2318 
       
  2319     QStringList driverList;
       
  2320     if (!driver.isEmpty())
       
  2321         driverList << driver;
       
  2322     else
       
  2323         driverList = QScreenDriverFactory::keys();
       
  2324 
       
  2325     for (int i = 0; i < driverList.size(); ++i) {
       
  2326         const QString driverName = driverList.at(i);
       
  2327         qt_screen = QScreenDriverFactory::create(driverName, display_id);
       
  2328         if (qt_screen) {
       
  2329             foundDriver = true;
       
  2330             if (qt_screen->connect(displaySpec)) {
       
  2331                 return qt_screen;
       
  2332             } else {
       
  2333                 delete qt_screen;
       
  2334                 qt_screen = 0;
       
  2335             }
       
  2336         }
       
  2337     }
       
  2338 
       
  2339     if (driver.isNull())
       
  2340         qFatal("No suitable driver found");
       
  2341     else if (foundDriver)
       
  2342         qFatal("%s: driver cannot connect", driver.toLatin1().constData());
       
  2343     else
       
  2344         qFatal("%s: driver not found", driver.toLatin1().constData());
       
  2345 
       
  2346     return 0;
       
  2347 }
       
  2348 
       
  2349 #ifndef QT_NO_QWS_CURSOR
       
  2350 static void blendCursor(QImage *dest, const QImage &cursor, const QPoint &offset)
       
  2351 {
       
  2352     QRasterBuffer rb;
       
  2353     rb.prepare(dest);
       
  2354 
       
  2355     QSpanData spanData;
       
  2356     spanData.init(&rb, 0);
       
  2357     spanData.type = QSpanData::Texture;
       
  2358     spanData.initTexture(&cursor, 256);
       
  2359     spanData.dx = -offset.x();
       
  2360     spanData.dy = -offset.y();
       
  2361     if (!spanData.blend)
       
  2362         return;
       
  2363 
       
  2364     const QRect rect = QRect(offset, cursor.size())
       
  2365                        & QRect(QPoint(0, 0), dest->size());
       
  2366     const int w = rect.width();
       
  2367     const int h = rect.height();
       
  2368 
       
  2369     QVarLengthArray<QT_FT_Span, 32> spans(h);
       
  2370     for (int i = 0; i < h; ++i) {
       
  2371         spans[i].x = rect.x();
       
  2372         spans[i].len = w;
       
  2373         spans[i].y = rect.y() + i;
       
  2374         spans[i].coverage = 255;
       
  2375     }
       
  2376     spanData.blend(h, spans.constData(), &spanData);
       
  2377 }
       
  2378 #endif // QT_NO_QWS_CURSOR
       
  2379 
       
  2380 /*!
       
  2381     \fn void QScreen::exposeRegion(QRegion region, int windowIndex)
       
  2382 
       
  2383     This function is called by the \l{Qt for Embedded Linux} server whenever a
       
  2384     screen update is required. \a region is the area on the screen
       
  2385     that must be updated, and \a windowIndex is the index into
       
  2386     QWSServer::clientWindows() of the window that required the
       
  2387     update. QWSWindow::state() gives more information about the cause.
       
  2388 
       
  2389     The default implementation composes the
       
  2390     affected windows and paints the given \a region on screen by
       
  2391     calling the blit() and solidFill() functions
       
  2392 
       
  2393     This function can be reimplemented to perform composition in
       
  2394     hardware, or to perform transition effects.
       
  2395     For simpler hardware acceleration, or to interface with
       
  2396     this is typically done by reimplementing the blit() and
       
  2397     solidFill() functions instead.
       
  2398 
       
  2399     Note that there is no need to call this function explicitly.
       
  2400 
       
  2401     \sa blit(), solidFill(), blank()
       
  2402 */
       
  2403 void QScreen::exposeRegion(QRegion r, int windowIndex)
       
  2404 {
       
  2405     r &= region();
       
  2406     if (r.isEmpty())
       
  2407         return;
       
  2408 
       
  2409     int changing = windowIndex;
       
  2410     // when we have just lowered a window, we have to expose all the windows below where the
       
  2411     // window used to be.
       
  2412     if (changing && qwsServer->clientWindows().at(changing)->state() == QWSWindow::Lowering)
       
  2413         changing = 0;
       
  2414 #ifdef QTOPIA_PERFTEST
       
  2415     static enum { PerfTestUnknown, PerfTestOn, PerfTestOff } perfTestState = PerfTestUnknown;
       
  2416     if(PerfTestUnknown == perfTestState) {
       
  2417         if(::getenv("QTOPIA_PERFTEST"))
       
  2418             perfTestState = PerfTestOn;
       
  2419         else
       
  2420             perfTestState = PerfTestOff;
       
  2421     }
       
  2422     if(PerfTestOn == perfTestState) {
       
  2423         QWSWindow *changed = qwsServer->clientWindows().at(changing);
       
  2424         if(!changed->client()->identity().isEmpty())
       
  2425             qDebug() << "Performance  :  expose_region  :"
       
  2426                      << changed->client()->identity()
       
  2427                      << r.boundingRect() << ": "
       
  2428                      << qPrintable( QTime::currentTime().toString( "h:mm:ss.zzz" ) );
       
  2429     }
       
  2430 #endif
       
  2431 
       
  2432     const QRect bounds = r.boundingRect();
       
  2433     QRegion blendRegion;
       
  2434     QImage *blendBuffer = 0;
       
  2435 
       
  2436 #ifndef QT_NO_QWS_CURSOR
       
  2437     if (qt_screencursor && !qt_screencursor->isAccelerated()) {
       
  2438         blendRegion = r & qt_screencursor->boundingRect();
       
  2439     }
       
  2440 #endif
       
  2441     compose(0, r, blendRegion, &blendBuffer, changing);
       
  2442 
       
  2443     if (blendBuffer && !blendBuffer->isNull()) {
       
  2444         const QPoint offset = blendRegion.boundingRect().topLeft();
       
  2445 #ifndef QT_NO_QWS_CURSOR
       
  2446         if (qt_screencursor && !qt_screencursor->isAccelerated()) {
       
  2447             const QRect cursorRect = qt_screencursor->boundingRect();
       
  2448             if (blendRegion.intersects(cursorRect)) {
       
  2449                 blendCursor(blendBuffer, qt_screencursor->image(),
       
  2450                             cursorRect.topLeft() - offset);
       
  2451             }
       
  2452         }
       
  2453 #endif // QT_NO_QWS_CURSOR
       
  2454         blit(*blendBuffer, offset, blendRegion);
       
  2455         delete blendBuffer;
       
  2456     }
       
  2457 
       
  2458     if (r.numRects() == 1) {
       
  2459         setDirty(r.boundingRect());
       
  2460     } else {
       
  2461         const QVector<QRect> rects = r.rects();
       
  2462         for (int i = 0; i < rects.size(); ++i)
       
  2463             setDirty(rects.at(i));
       
  2464     }
       
  2465 }
       
  2466 
       
  2467 /*!
       
  2468     \fn void QScreen::blit(const QImage &image, const QPoint &topLeft, const QRegion &region)
       
  2469 
       
  2470     Copies the given \a region in the given \a image to the point
       
  2471     specified by \a topLeft using device coordinates.
       
  2472 
       
  2473     This function is called from the exposeRegion() function; it is
       
  2474     not intended to be called explicitly.
       
  2475 
       
  2476     Reimplement this function to make use of \l{Adding an Accelerated
       
  2477     Graphics Driver to Qt for Embedded Linux}{accelerated hardware}. Note that
       
  2478     this function must be reimplemented if the framebuffer format is
       
  2479     not supported by \l{Qt for Embedded Linux} (See the
       
  2480     \l{Qt for Embedded Linux Display Management}{Display Management}
       
  2481     documentation for more details).
       
  2482 
       
  2483     \sa exposeRegion(), solidFill(), blank()
       
  2484 */
       
  2485 void QScreen::blit(const QImage &img, const QPoint &topLeft, const QRegion &reg)
       
  2486 {
       
  2487     const QRect bound = (region() & QRect(topLeft, img.size())).boundingRect();
       
  2488     QWSDisplay::grab();
       
  2489     d_ptr->blit(this, img, topLeft - offset(),
       
  2490             (reg & bound).translated(-topLeft));
       
  2491     QWSDisplay::ungrab();
       
  2492 }
       
  2493 
       
  2494 #ifdef QT_QWS_CLIENTBLIT
       
  2495 /*!
       
  2496   Returns true if this screen driver supports calling QScreen::blit() and
       
  2497   QScreen::setDirty() directly from non-server applications, otherwise returns
       
  2498   false.
       
  2499 
       
  2500   If available, this is used to optimize the performance of non-occluded, opaque
       
  2501   client windows by removing the server round trip when they are updated.
       
  2502 
       
  2503   \sa setSupportsBlitInClients()
       
  2504  */
       
  2505 bool QScreen::supportsBlitInClients() const
       
  2506 {
       
  2507     return d_ptr->supportsBlitInClients;
       
  2508 }
       
  2509 
       
  2510 /*!
       
  2511   If \a supported, the screen driver is marked as supporting blitting directly
       
  2512   from non-server applications.
       
  2513 
       
  2514   \sa supportsBlitInClients()
       
  2515  */
       
  2516 void QScreen::setSupportsBlitInClients(bool supported)
       
  2517 {
       
  2518     d_ptr->supportsBlitInClients = supported;
       
  2519 }
       
  2520 #endif
       
  2521 
       
  2522 /*!
       
  2523     \internal
       
  2524 */
       
  2525 
       
  2526 void QScreen::blit(QWSWindow *win, const QRegion &clip)
       
  2527 {
       
  2528     QWSWindowSurface *surface = win->windowSurface();
       
  2529     if (!surface)
       
  2530         return;
       
  2531 
       
  2532     const QImage &img = surface->image();
       
  2533     if (img.isNull())
       
  2534         return;
       
  2535 
       
  2536     const QRegion rgn = clip & win->paintedRegion();
       
  2537     if (rgn.isEmpty())
       
  2538         return;
       
  2539 
       
  2540     surface->lock();
       
  2541     blit(img, win->requestedRegion().boundingRect().topLeft(), rgn);
       
  2542     surface->unlock();
       
  2543 }
       
  2544 
       
  2545 struct fill_data {
       
  2546     quint32 color;
       
  2547     uchar *data;
       
  2548     int lineStep;
       
  2549     int x;
       
  2550     int y;
       
  2551     int w;
       
  2552     int h;
       
  2553 };
       
  2554 
       
  2555 /*!
       
  2556     Fills the given \a region of the screen with the specified \a
       
  2557     color.
       
  2558 
       
  2559     This function is called from the exposeRegion() function; it is
       
  2560     not intended to be called explicitly.
       
  2561 
       
  2562     Reimplement this function to make use of \l{Adding an Accelerated
       
  2563     Graphics Driver to Qt for Embedded Linux}{accelerated hardware}. Note that
       
  2564     this function must be reimplemented if the framebuffer format is
       
  2565     not supported by \l{Qt for Embedded Linux} (See the
       
  2566     \l{Qt for Embedded Linux Display Management}{Display Management}
       
  2567     documentation for more details).
       
  2568 
       
  2569     \sa exposeRegion(), blit(), blank()
       
  2570 */
       
  2571 // the base class implementation works in device coordinates, so that transformed drivers can use it
       
  2572 void QScreen::solidFill(const QColor &color, const QRegion &region)
       
  2573 {
       
  2574     QWSDisplay::grab();
       
  2575     d_ptr->solidFill(this, color,
       
  2576                      region.translated(-offset()) & QRect(0, 0, dw, dh));
       
  2577     QWSDisplay::ungrab();
       
  2578 }
       
  2579 
       
  2580 /*!
       
  2581     \since 4.2
       
  2582 
       
  2583     Creates and returns a new window surface matching the given \a
       
  2584     key.
       
  2585 
       
  2586     The server application will call this function whenever it needs
       
  2587     to create a server side representation of a window, e.g. when
       
  2588     copying the content of memory to the screen using the screen
       
  2589     driver.
       
  2590 
       
  2591     Note that this function must be reimplemented when adding an
       
  2592     accelerated graphics driver. See the
       
  2593     \l{Adding an Accelerated Graphics Driver to Qt for Embedded Linux}
       
  2594     {Adding an Accelerated Graphics Driver} documentation for details.
       
  2595 
       
  2596     \sa {Qt for Embedded Linux Architecture}
       
  2597 */
       
  2598 QWSWindowSurface* QScreen::createSurface(const QString &key) const
       
  2599 {
       
  2600 #ifndef QT_NO_PAINTONSCREEN
       
  2601     if (key == QLatin1String("OnScreen"))
       
  2602         return new QWSOnScreenSurface;
       
  2603     else
       
  2604 #endif
       
  2605     if (key == QLatin1String("mem"))
       
  2606         return new QWSLocalMemSurface;
       
  2607 #ifndef QT_NO_QWS_MULTIPROCESS
       
  2608     else if (key == QLatin1String("shm"))
       
  2609         return new QWSSharedMemSurface;
       
  2610 #endif
       
  2611 #ifndef QT_NO_PAINT_DEBUG
       
  2612     else if (key == QLatin1String("Yellow"))
       
  2613         return new QWSYellowSurface;
       
  2614 #endif
       
  2615 #ifndef QT_NO_DIRECTPAINTER
       
  2616     else if (key == QLatin1String("DirectPainter"))
       
  2617         return new QWSDirectPainterSurface;
       
  2618 #endif
       
  2619 
       
  2620     return 0;
       
  2621 }
       
  2622 
       
  2623 #ifndef QT_NO_PAINTONSCREEN
       
  2624 bool QScreen::isWidgetPaintOnScreen(const QWidget *w)
       
  2625 {
       
  2626     static int doOnScreen = -1;
       
  2627     if (doOnScreen == -1) {
       
  2628         const QByteArray env = qgetenv("QT_ONSCREEN_PAINT");
       
  2629         if (env == "force")
       
  2630             doOnScreen = 2;
       
  2631         else
       
  2632             doOnScreen = (env.toInt() > 0 ? 1 : 0);
       
  2633     }
       
  2634 
       
  2635     if (doOnScreen == 2) // force
       
  2636         return true;
       
  2637 
       
  2638     if (doOnScreen == 0 && !w->testAttribute(Qt::WA_PaintOnScreen))
       
  2639         return false;
       
  2640 
       
  2641     return w->d_func()->isOpaque;
       
  2642 }
       
  2643 #endif
       
  2644 
       
  2645 /*!
       
  2646     \overload
       
  2647 
       
  2648     Creates and returns a new window surface for the given \a widget.
       
  2649 */
       
  2650 QWSWindowSurface* QScreen::createSurface(QWidget *widget) const
       
  2651 {
       
  2652 #ifndef QT_NO_PAINTONSCREEN
       
  2653     if (isWidgetPaintOnScreen(widget) && base())
       
  2654         return new QWSOnScreenSurface(widget);
       
  2655     else
       
  2656 #endif
       
  2657     if (QApplication::type() == QApplication::GuiServer)
       
  2658         return new QWSLocalMemSurface(widget);
       
  2659 #ifndef QT_NO_QWS_MULTIPROCESS
       
  2660     else
       
  2661         return new QWSSharedMemSurface(widget);
       
  2662 #endif
       
  2663 
       
  2664     return 0;
       
  2665 }
       
  2666 
       
  2667 void QScreen::compose(int level, const QRegion &exposed, QRegion &blend,
       
  2668                       QImage **blendbuffer, int changing_level)
       
  2669 {
       
  2670     QRect exposed_bounds = exposed.boundingRect();
       
  2671     QWSWindow *win = 0;
       
  2672     do {
       
  2673         win = qwsServer->clientWindows().value(level); // null is background
       
  2674         ++level;
       
  2675     } while (win && !win->paintedRegion().boundingRect().intersects(exposed_bounds));
       
  2676 
       
  2677     QWSWindowSurface *surface = (win ? win->windowSurface() : 0);
       
  2678     bool above_changing = level <= changing_level; // 0 is topmost
       
  2679 
       
  2680     QRegion exposedBelow = exposed;
       
  2681     bool opaque = true;
       
  2682 
       
  2683     if (win) {
       
  2684         opaque = win->isOpaque() || !surface->isBuffered();
       
  2685         if (opaque) {
       
  2686             exposedBelow -= win->paintedRegion();
       
  2687             if (above_changing || !surface->isBuffered())
       
  2688                 blend -= exposed & win->paintedRegion();
       
  2689         } else {
       
  2690             blend += exposed & win->paintedRegion();
       
  2691         }
       
  2692     }
       
  2693     if (win && !exposedBelow.isEmpty()) {
       
  2694         compose(level, exposedBelow, blend, blendbuffer, changing_level);
       
  2695     } else {
       
  2696         QSize blendSize = blend.boundingRect().size();
       
  2697         if (!blendSize.isNull()) {
       
  2698             *blendbuffer = new QImage(blendSize, d_ptr->preferredImageFormat());
       
  2699         }
       
  2700     }
       
  2701 
       
  2702     const QRegion blitRegion = exposed - blend;
       
  2703     if (!win)
       
  2704         paintBackground(blitRegion);
       
  2705     else if (!above_changing && surface->isBuffered())
       
  2706         blit(win, blitRegion);
       
  2707 
       
  2708     QRegion blendRegion = exposed & blend;
       
  2709 
       
  2710     if (win)
       
  2711         blendRegion &= win->paintedRegion();
       
  2712     if (!blendRegion.isEmpty()) {
       
  2713 
       
  2714         QPoint off = blend.boundingRect().topLeft();
       
  2715 
       
  2716         QRasterBuffer rb;
       
  2717         rb.prepare(*blendbuffer);
       
  2718         QSpanData spanData;
       
  2719         spanData.init(&rb, 0);
       
  2720         if (!win) {
       
  2721             const QImage::Format format = (*blendbuffer)->format();
       
  2722             switch (format) {
       
  2723             case QImage::Format_ARGB32_Premultiplied:
       
  2724             case QImage::Format_ARGB32:
       
  2725             case QImage::Format_ARGB8565_Premultiplied:
       
  2726             case QImage::Format_ARGB8555_Premultiplied:
       
  2727             case QImage::Format_ARGB6666_Premultiplied:
       
  2728             case QImage::Format_ARGB4444_Premultiplied:
       
  2729                 spanData.rasterBuffer->compositionMode = QPainter::CompositionMode_Source;
       
  2730                 break;
       
  2731             default:
       
  2732                 break;
       
  2733             }
       
  2734             spanData.setup(qwsServer->backgroundBrush(), 256, QPainter::CompositionMode_SourceOver);
       
  2735             spanData.dx = off.x();
       
  2736             spanData.dy = off.y();
       
  2737         } else if (!surface->isBuffered()) {
       
  2738                 return;
       
  2739         } else {
       
  2740             const QImage &img = surface->image();
       
  2741             QPoint winoff = off - win->requestedRegion().boundingRect().topLeft();
       
  2742             // convert win->opacity() from scale [0..255] to [0..256]
       
  2743             int const_alpha = win->opacity();
       
  2744             const_alpha += (const_alpha >> 7);
       
  2745             spanData.type = QSpanData::Texture;
       
  2746             spanData.initTexture(&img, const_alpha);
       
  2747             spanData.dx = winoff.x();
       
  2748             spanData.dy = winoff.y();
       
  2749         }
       
  2750         if (!spanData.blend)
       
  2751             return;
       
  2752 
       
  2753         if (surface)
       
  2754             surface->lock();
       
  2755         const QVector<QRect> rects = blendRegion.rects();
       
  2756         const int nspans = 256;
       
  2757         QT_FT_Span spans[nspans];
       
  2758         for (int i = 0; i < rects.size(); ++i) {
       
  2759             int y = rects.at(i).y() - off.y();
       
  2760             int ye = y + rects.at(i).height();
       
  2761             int x = rects.at(i).x() - off.x();
       
  2762             int len = rects.at(i).width();
       
  2763             while (y < ye) {
       
  2764                 int n = qMin(nspans, ye - y);
       
  2765                 int i = 0;
       
  2766                 while (i < n) {
       
  2767                     spans[i].x = x;
       
  2768                     spans[i].len = len;
       
  2769                     spans[i].y = y + i;
       
  2770                     spans[i].coverage = 255;
       
  2771                     ++i;
       
  2772                 }
       
  2773                 spanData.blend(n, spans, &spanData);
       
  2774                 y += n;
       
  2775             }
       
  2776         }
       
  2777         if (surface)
       
  2778             surface->unlock();
       
  2779     }
       
  2780 }
       
  2781 
       
  2782 void QScreen::paintBackground(const QRegion &r)
       
  2783 {
       
  2784     const QBrush &bg = qwsServer->backgroundBrush();
       
  2785     Qt::BrushStyle bs = bg.style();
       
  2786     if (bs == Qt::NoBrush || r.isEmpty())
       
  2787         return;
       
  2788 
       
  2789     if (bs == Qt::SolidPattern) {
       
  2790         solidFill(bg.color(), r);
       
  2791     } else {
       
  2792         const QRect br = r.boundingRect();
       
  2793         QImage img(br.size(), d_ptr->preferredImageFormat());
       
  2794         QPoint off = br.topLeft();
       
  2795         QRasterBuffer rb;
       
  2796         rb.prepare(&img);
       
  2797         QSpanData spanData;
       
  2798         spanData.init(&rb, 0);
       
  2799         spanData.setup(bg, 256, QPainter::CompositionMode_Source);
       
  2800         spanData.dx = off.x();
       
  2801         spanData.dy = off.y();
       
  2802         Q_ASSERT(spanData.blend);
       
  2803 
       
  2804         const QVector<QRect> rects = r.rects();
       
  2805         const int nspans = 256;
       
  2806         QT_FT_Span spans[nspans];
       
  2807         for (int i = 0; i < rects.size(); ++i) {
       
  2808             int y = rects.at(i).y() - off.y();
       
  2809             int ye = y + rects.at(i).height();
       
  2810             int x = rects.at(i).x() - off.x();
       
  2811             int len = rects.at(i).width();
       
  2812             while (y < ye) {
       
  2813                 int n = qMin(nspans, ye - y);
       
  2814                 int i = 0;
       
  2815                 while (i < n) {
       
  2816                     spans[i].x = x;
       
  2817                     spans[i].len = len;
       
  2818                     spans[i].y = y + i;
       
  2819                     spans[i].coverage = 255;
       
  2820                     ++i;
       
  2821                 }
       
  2822                 spanData.blend(n, spans, &spanData);
       
  2823                 y += n;
       
  2824             }
       
  2825         }
       
  2826         blit(img, br.topLeft(), r);
       
  2827     }
       
  2828 }
       
  2829 
       
  2830 /*!
       
  2831     \fn virtual int QScreen::sharedRamSize(void *)
       
  2832 
       
  2833     \internal
       
  2834 */
       
  2835 
       
  2836 /*!
       
  2837     \fn QScreen::setDirty(const QRect& rectangle)
       
  2838 
       
  2839     Marks the given \a rectangle as dirty.
       
  2840 
       
  2841     Note that the default implementation does nothing; reimplement
       
  2842     this function to indicate that the given \a rectangle has been
       
  2843     altered.
       
  2844 */
       
  2845 
       
  2846 void QScreen::setDirty(const QRect&)
       
  2847 {
       
  2848 }
       
  2849 
       
  2850 /*!
       
  2851     \fn QScreen::isTransformed() const
       
  2852 
       
  2853     Returns true if the screen is transformed (for instance, rotated
       
  2854     90 degrees); otherwise returns false.
       
  2855 
       
  2856     \sa transformOrientation(), isInterlaced()
       
  2857 */
       
  2858 
       
  2859 bool QScreen::isTransformed() const
       
  2860 {
       
  2861     return false;
       
  2862 }
       
  2863 
       
  2864 /*!
       
  2865     \fn QScreen::isInterlaced() const
       
  2866 
       
  2867     Returns true if the display is interlaced (i.e. is displaying
       
  2868     images progressively like a television screen); otherwise returns
       
  2869     false.
       
  2870 
       
  2871     If the display is interlaced, the drawing is altered to look
       
  2872     better.
       
  2873 
       
  2874     \sa isTransformed(), linestep()
       
  2875 */
       
  2876 
       
  2877 bool QScreen::isInterlaced() const
       
  2878 {
       
  2879     return false;//qws_screen_is_interlaced;;
       
  2880 }
       
  2881 
       
  2882 /*!
       
  2883     \fn QScreen::mapToDevice(const QSize &size) const
       
  2884 
       
  2885     Maps the given \a size from the coordinate space used by the
       
  2886     application to the framebuffer coordinate system. Note that the
       
  2887     default implementation simply returns the given \a size as it is.
       
  2888 
       
  2889     Reimplement this function to use the given device's coordinate
       
  2890     system when mapping.
       
  2891 
       
  2892     \sa mapFromDevice()
       
  2893 */
       
  2894 
       
  2895 QSize QScreen::mapToDevice(const QSize &s) const
       
  2896 {
       
  2897     return s;
       
  2898 }
       
  2899 
       
  2900 /*!
       
  2901     \fn QScreen::mapFromDevice(const QSize &size) const
       
  2902 
       
  2903     Maps the given \a size from the framebuffer coordinate system to
       
  2904     the coordinate space used by the application. Note that the
       
  2905     default implementation simply returns the given \a size as it is.
       
  2906 
       
  2907     Reimplement this function to use the given device's coordinate
       
  2908     system when mapping.
       
  2909 
       
  2910     \sa mapToDevice()
       
  2911 */
       
  2912 
       
  2913 QSize QScreen::mapFromDevice(const QSize &s) const
       
  2914 {
       
  2915     return s;
       
  2916 }
       
  2917 
       
  2918 /*!
       
  2919     \fn QScreen::mapToDevice(const QPoint &point, const QSize &screenSize) const
       
  2920     \overload
       
  2921 
       
  2922     Maps the given \a point from the coordinate space used by the
       
  2923     application to the framebuffer coordinate system, passing the
       
  2924     device's \a screenSize as argument. Note that the default
       
  2925     implementation returns the given \a point as it is.
       
  2926 */
       
  2927 
       
  2928 QPoint QScreen::mapToDevice(const QPoint &p, const QSize &) const
       
  2929 {
       
  2930     return p;
       
  2931 }
       
  2932 
       
  2933 /*!
       
  2934     \fn QScreen::mapFromDevice(const QPoint &point, const QSize &screenSize) const
       
  2935     \overload
       
  2936 
       
  2937     Maps the given \a point from the framebuffer coordinate system to
       
  2938     the coordinate space used by the application, passing the device's
       
  2939     \a screenSize as argument. Note that the default implementation
       
  2940     simply returns the given \a point as it is.
       
  2941 */
       
  2942 
       
  2943 QPoint QScreen::mapFromDevice(const QPoint &p, const QSize &) const
       
  2944 {
       
  2945     return p;
       
  2946 }
       
  2947 
       
  2948 /*!
       
  2949     \fn QScreen::mapToDevice(const QRect &rectangle, const QSize &screenSize) const
       
  2950     \overload
       
  2951 
       
  2952     Maps the given \a rectangle from the coordinate space used by the
       
  2953     application to the framebuffer coordinate system, passing the
       
  2954     device's \a screenSize as argument. Note that the default
       
  2955     implementation returns the given \a rectangle as it is.
       
  2956 */
       
  2957 
       
  2958 QRect QScreen::mapToDevice(const QRect &r, const QSize &) const
       
  2959 {
       
  2960     return r;
       
  2961 }
       
  2962 
       
  2963 /*!
       
  2964     \fn QScreen::mapFromDevice(const QRect &rectangle, const QSize &screenSize) const
       
  2965     \overload
       
  2966 
       
  2967     Maps the given \a rectangle from the framebuffer coordinate system to
       
  2968     the coordinate space used by the application, passing the device's
       
  2969     \a screenSize as argument. Note that the default implementation
       
  2970     simply returns the given \a rectangle as it is.
       
  2971 */
       
  2972 
       
  2973 QRect QScreen::mapFromDevice(const QRect &r, const QSize &) const
       
  2974 {
       
  2975     return r;
       
  2976 }
       
  2977 
       
  2978 /*!
       
  2979     \fn QScreen::mapToDevice(const QImage &image) const
       
  2980     \overload
       
  2981 
       
  2982     Maps the given \a image from the coordinate space used by the
       
  2983     application to the framebuffer coordinate system. Note that the
       
  2984     default implementation returns the given \a image as it is.
       
  2985 */
       
  2986 
       
  2987 QImage QScreen::mapToDevice(const QImage &i) const
       
  2988 {
       
  2989     return i;
       
  2990 }
       
  2991 
       
  2992 /*!
       
  2993     \fn QScreen::mapFromDevice(const QImage &image) const
       
  2994     \overload
       
  2995 
       
  2996     Maps the given \a image from the framebuffer coordinate system to
       
  2997     the coordinate space used by the application. Note that the
       
  2998     default implementation simply returns the given \a image as it is.
       
  2999 */
       
  3000 
       
  3001 QImage QScreen::mapFromDevice(const QImage &i) const
       
  3002 {
       
  3003     return i;
       
  3004 }
       
  3005 
       
  3006 /*!
       
  3007     \fn QScreen::mapToDevice(const QRegion &region, const QSize &screenSize) const
       
  3008     \overload
       
  3009 
       
  3010     Maps the given \a region from the coordinate space used by the
       
  3011     application to the framebuffer coordinate system, passing the
       
  3012     device's \a screenSize as argument. Note that the default
       
  3013     implementation returns the given \a region as it is.
       
  3014 */
       
  3015 
       
  3016 QRegion QScreen::mapToDevice(const QRegion &r, const QSize &) const
       
  3017 {
       
  3018     return r;
       
  3019 }
       
  3020 
       
  3021 /*!
       
  3022     \fn QScreen::mapFromDevice(const QRegion &region, const QSize &screenSize) const
       
  3023     \overload
       
  3024 
       
  3025     Maps the given \a region from the framebuffer coordinate system to
       
  3026     the coordinate space used by the application, passing the device's
       
  3027     \a screenSize as argument. Note that the default implementation
       
  3028     simply returns the given \a region as it is.
       
  3029 */
       
  3030 
       
  3031 QRegion QScreen::mapFromDevice(const QRegion &r, const QSize &) const
       
  3032 {
       
  3033     return r;
       
  3034 }
       
  3035 
       
  3036 /*!
       
  3037     \fn QScreen::transformOrientation() const
       
  3038 
       
  3039     Returns the current rotation as an integer value.
       
  3040 
       
  3041     Note that the default implementation returns 0; reimplement this
       
  3042     function to override this value.
       
  3043 
       
  3044     \sa isTransformed()
       
  3045 */
       
  3046 
       
  3047 int QScreen::transformOrientation() const
       
  3048 {
       
  3049     return 0;
       
  3050 }
       
  3051 
       
  3052 int QScreen::pixmapDepth() const
       
  3053 {
       
  3054     return depth();
       
  3055 }
       
  3056 
       
  3057 /*!
       
  3058     \internal
       
  3059 */
       
  3060 int QScreen::memoryNeeded(const QString&)
       
  3061 {
       
  3062     return 0;
       
  3063 }
       
  3064 
       
  3065 /*!
       
  3066     \internal
       
  3067 */
       
  3068 void QScreen::haltUpdates()
       
  3069 {
       
  3070 }
       
  3071 
       
  3072 /*!
       
  3073     \internal
       
  3074 */
       
  3075 void QScreen::resumeUpdates()
       
  3076 {
       
  3077 }
       
  3078 
       
  3079 /*!
       
  3080     \fn QRegion QScreen::region() const
       
  3081     \since 4.2
       
  3082 
       
  3083     Returns the region covered by this screen driver.
       
  3084 
       
  3085     \sa base(), screenSize()
       
  3086 */
       
  3087 
       
  3088 /*!
       
  3089     \internal
       
  3090 */
       
  3091 void QScreen::setOffset(const QPoint &p)
       
  3092 {
       
  3093     d_ptr->offset = p;
       
  3094 }
       
  3095 
       
  3096 /*!
       
  3097     \since 4.2
       
  3098 
       
  3099     Returns the logical offset of the screen, i.e., the offset between
       
  3100     (0,0) in screen coordinates and the application coordinate system.
       
  3101 */
       
  3102 QPoint QScreen::offset() const
       
  3103 {
       
  3104     return d_ptr->offset;
       
  3105 }
       
  3106 
       
  3107 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
       
  3108 void QScreen::setFrameBufferLittleEndian(bool littleEndian)
       
  3109 {
       
  3110     d_ptr->fb_is_littleEndian = littleEndian;
       
  3111 }
       
  3112 
       
  3113 bool QScreen::frameBufferLittleEndian() const
       
  3114 {
       
  3115     return d_ptr->fb_is_littleEndian;
       
  3116 }
       
  3117 #endif
       
  3118 
       
  3119 /*!
       
  3120     \fn int QScreen::subScreenIndexAt(const QPoint &position) const
       
  3121     \since 4.2
       
  3122 
       
  3123     Returns the index of the subscreen at the given \a position;
       
  3124     returns -1 if no screen is found.
       
  3125 
       
  3126     The index identifies the subscreen in the list of pointers
       
  3127     returned by the subScreens() function.
       
  3128 
       
  3129     \sa instance(), subScreens()
       
  3130 */
       
  3131 int QScreen::subScreenIndexAt(const QPoint &p) const
       
  3132 {
       
  3133     const QList<QScreen*> screens = subScreens();
       
  3134     const int n = screens.count();
       
  3135     for (int i = 0; i < n; ++i) {
       
  3136         if (screens.at(i)->region().contains(p))
       
  3137             return i;
       
  3138     }
       
  3139 
       
  3140     return -1;
       
  3141 }
       
  3142 
       
  3143 #if 0
       
  3144 #ifdef QT_LOADABLE_MODULES
       
  3145 
       
  3146 // ### needs update after driver init changes
       
  3147 
       
  3148 static QScreen * qt_dodriver(char * driver,char * a,unsigned char * b)
       
  3149 
       
  3150 {
       
  3151     char buf[200];
       
  3152     strcpy(buf,"/etc/qws/drivers/");
       
  3153     qstrcpy(buf+17,driver);
       
  3154     qDebug("Attempting driver %s",driver);
       
  3155 
       
  3156     void * handle;
       
  3157     handle=dlopen(buf,RTLD_LAZY);
       
  3158     if(handle==0) {
       
  3159         qFatal("Module load error");
       
  3160     }
       
  3161     QScreen *(*qt_get_screen_func)(char *,unsigned char *);
       
  3162     qt_get_screen_func=dlsym(handle,"qt_get_screen");
       
  3163     if(qt_get_screen_func==0) {
       
  3164         qFatal("Couldn't get symbol");
       
  3165     }
       
  3166     QScreen * ret=qt_get_screen_func(a,b);
       
  3167     return ret;
       
  3168 }
       
  3169 
       
  3170 static QScreen * qt_do_entry(char * entry)
       
  3171 {
       
  3172     unsigned char config[256];
       
  3173 
       
  3174     FILE * f=fopen(entry,"r");
       
  3175     if(!f) {
       
  3176         return 0;
       
  3177     }
       
  3178 
       
  3179     int r=fread(config,256,1,f);
       
  3180     if(r<1)
       
  3181         return 0;
       
  3182 
       
  3183     fclose(f);
       
  3184 
       
  3185     unsigned short vendorid=*((unsigned short int *)config);
       
  3186     unsigned short deviceid=*(((unsigned short int *)config)+1);
       
  3187     if(config[0xb]!=3)
       
  3188         return 0;
       
  3189 
       
  3190     if(vendorid==0x1002) {
       
  3191         if(deviceid==0x4c4d) {
       
  3192             qDebug("Compaq Armada/IBM Thinkpad's Mach64 card");
       
  3193             return qt_dodriver("mach64.so",entry,config);
       
  3194         } else if(deviceid==0x4742) {
       
  3195             qDebug("Desktop Rage Pro Mach64 card");
       
  3196             return qt_dodriver("mach64.so",entry,config);
       
  3197         } else {
       
  3198             qDebug("Unrecognised ATI card id %x",deviceid);
       
  3199             return 0;
       
  3200         }
       
  3201     } else {
       
  3202         qDebug("Unrecognised vendor");
       
  3203     }
       
  3204     return 0;
       
  3205 }
       
  3206 
       
  3207 extern bool qws_accel;
       
  3208 
       
  3209 /// ** NOT SUPPPORTED **
       
  3210 
       
  3211 QScreen * qt_probe_bus()
       
  3212 {
       
  3213     if(!qws_accel) {
       
  3214         return qt_dodriver("unaccel.so",0,0);
       
  3215     }
       
  3216 
       
  3217     DIR * dirptr=opendir("/proc/bus/pci");
       
  3218     if(!dirptr)
       
  3219         return qt_dodriver("unaccel.so",0,0);
       
  3220     DIR * dirptr2;
       
  3221     dirent * cards;
       
  3222 
       
  3223     dirent * busses=readdir(dirptr);
       
  3224 
       
  3225     while(busses) {
       
  3226         if(busses->d_name[0]!='.') {
       
  3227             char buf[100];
       
  3228             strcpy(buf,"/proc/bus/pci/");
       
  3229             qstrcpy(buf+14,busses->d_name);
       
  3230             int p=strlen(buf);
       
  3231             dirptr2=opendir(buf);
       
  3232             if(dirptr2) {
       
  3233                 cards=readdir(dirptr2);
       
  3234                 while(cards) {
       
  3235                     if(cards->d_name[0]!='.') {
       
  3236                         buf[p]='/';
       
  3237                         qstrcpy(buf+p+1,cards->d_name);
       
  3238                         QScreen * ret=qt_do_entry(buf);
       
  3239                         if(ret)
       
  3240                             return ret;
       
  3241                     }
       
  3242                     cards=readdir(dirptr2);
       
  3243                 }
       
  3244                 closedir(dirptr2);
       
  3245             }
       
  3246         }
       
  3247         busses=readdir(dirptr);
       
  3248     }
       
  3249     closedir(dirptr);
       
  3250 
       
  3251     return qt_dodriver("unaccel.so",0,0);
       
  3252 }
       
  3253 
       
  3254 #else
       
  3255 
       
  3256 char *qt_qws_hardcoded_slot = "/proc/bus/pci/01/00.0";
       
  3257 
       
  3258 const unsigned char* qt_probe_bus()
       
  3259 {
       
  3260     const char * slot;
       
  3261     slot=::getenv("QWS_CARD_SLOT");
       
  3262     if(!slot)
       
  3263         slot=qt_qws_hardcoded_slot;
       
  3264     if (slot) {
       
  3265         static unsigned char config[256];
       
  3266         FILE * f=fopen(slot,"r");
       
  3267         if(!f) {
       
  3268             qDebug("Open failure for %s",slot);
       
  3269             slot=0;
       
  3270         } else {
       
  3271             int r=fread((char*)config,256,1,f);
       
  3272             fclose(f);
       
  3273             if(r<1) {
       
  3274                 qDebug("Read failure");
       
  3275                 return 0;
       
  3276             } else {
       
  3277                 return config;
       
  3278             }
       
  3279         }
       
  3280     }
       
  3281     return 0;
       
  3282 }
       
  3283 
       
  3284 #endif
       
  3285 
       
  3286 #endif // 0
       
  3287 
       
  3288 /*!
       
  3289     \internal
       
  3290     \since 4.4
       
  3291 */
       
  3292 void QScreen::setPixmapDataFactory(QPixmapDataFactory *factory)
       
  3293 {
       
  3294     static bool shownWarning = false;
       
  3295     if (!shownWarning) {
       
  3296         qWarning("QScreen::setPixmapDataFactory() is deprecated - use setGraphicsSystem() instead");
       
  3297         shownWarning = true;
       
  3298     }
       
  3299 
       
  3300     d_ptr->pixmapFactory = factory;
       
  3301 }
       
  3302 
       
  3303 /*!
       
  3304     \internal
       
  3305     \since 4.4
       
  3306 */
       
  3307 QPixmapDataFactory* QScreen::pixmapDataFactory() const
       
  3308 {
       
  3309     return d_ptr->pixmapFactory;
       
  3310 }
       
  3311 
       
  3312 /*!
       
  3313     \internal
       
  3314     \since 4.5
       
  3315 */
       
  3316 void QScreen::setGraphicsSystem(QGraphicsSystem* system)
       
  3317 {
       
  3318     d_ptr->graphicsSystem = system;
       
  3319 }
       
  3320 
       
  3321 /*!
       
  3322     \internal
       
  3323     \since 4.5
       
  3324 */
       
  3325 QGraphicsSystem* QScreen::graphicsSystem() const
       
  3326 {
       
  3327     return d_ptr->graphicsSystem;
       
  3328 }
       
  3329 
       
  3330 /*!
       
  3331     \since 4.4
       
  3332 
       
  3333     Returns the class identifier for the screen object.
       
  3334 */
       
  3335 QScreen::ClassId QScreen::classId() const
       
  3336 {
       
  3337     return static_cast<ClassId>(d_ptr->classId);
       
  3338 }
       
  3339 
       
  3340 QT_END_NAMESPACE