~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/embedded/qscreen_qws.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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