1
/****************************************************************************
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
7
** This file is part of the QtGui module of the Qt Toolkit.
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
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.
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.
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
40
****************************************************************************/
42
#include "qscreen_qws.h"
44
#include "qcolormap.h"
45
#include "qscreendriverfactory_qws.h"
46
#include "qwindowsystem_qws.h"
50
#include "qvarlengtharray.h"
51
#include "qwsdisplay_qws.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>
63
// #define QT_USE_MEMCPY_DUFF
65
#ifndef QT_NO_QWS_CURSOR
66
bool qt_sw_cursor=false;
67
Q_GUI_EXPORT QScreenCursor * qt_screencursor = 0;
69
Q_GUI_EXPORT QScreen * qt_screen = 0;
71
ClearCacheFunc QScreen::clearCacheFunc = 0;
73
#ifndef QT_NO_QWS_CURSOR
78
\brief The QScreenCursor class is a base class for screen cursors
79
in Qt for Embedded Linux.
81
Note that this class is non-portable, and that it is only
82
available in \l{Qt for Embedded Linux}.
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
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
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.
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()
111
\sa QScreen, QWSServer
115
\fn static QScreenCursor* QScreenCursor::instance()
118
Returns a pointer to the application's unique screen cursor.
121
extern bool qws_sw_cursor;
124
Constructs a screen cursor
126
QScreenCursor::QScreenCursor()
128
pos = QPoint(qt_screen->deviceWidth()/2, qt_screen->deviceHeight()/2);
132
supportsAlpha = true;
136
Destroys the screen cursor.
138
QScreenCursor::~QScreenCursor()
143
Hides the cursor from the screen.
147
void QScreenCursor::hide()
152
qt_screen->exposeRegion(boundingRect(), 0);
157
Shows the mouse cursor.
161
void QScreenCursor::show()
166
qt_screen->exposeRegion(boundingRect(), 0);
171
Sets the cursor's image to be the given \a image.
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.
179
void QScreenCursor::set(const QImage &image, int hotx, int hoty)
181
const QRect r = boundingRect();
183
hotspot = QPoint(hotx, hoty);
184
// These are in almost all cases the fastest formats to blend
186
switch (qt_screen->depth()) {
188
f = QImage::Format_ARGB4444_Premultiplied;
191
f = QImage::Format_ARGB8555_Premultiplied;
194
f = QImage::Format_ARGB8565_Premultiplied;
197
f = QImage::Format_ARGB6666_Premultiplied;
200
f = QImage::Format_ARGB32_Premultiplied;
203
cursor = image.convertToFormat(f);
207
if (enable && !hwaccel)
208
qt_screen->exposeRegion(r | boundingRect(), 0);
212
Moves the mouse cursor to the given position, i.e., (\a x, \a y).
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).
220
void QScreenCursor::move(int x, int y)
222
QRegion r = boundingRect();
224
if (enable && !hwaccel) {
226
qt_screen->exposeRegion(r, 0);
232
\fn void QScreenCursor::initSoftwareCursor ()
234
Initializes the screen cursor.
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()
241
\sa QScreen::initDevice()
243
void QScreenCursor::initSoftwareCursor()
245
qt_screencursor = new QScreenCursor;
249
#endif // QT_NO_QWS_CURSOR
253
\fn QRect QScreenCursor::boundingRect () const
255
Returns the cursor's bounding rectangle.
260
\fn bool QScreenCursor::enabled ()
264
\fn QImage QScreenCursor::image () const
266
Returns the cursor's image.
271
\fn bool QScreenCursor::isAccelerated () const
273
Returns true if the cursor is accelerated; otherwise false.
277
\fn bool QScreenCursor::isVisible () const
279
Returns true if the cursor is visible; otherwise false.
284
\fn bool QScreenCursor::supportsAlphaCursor () const
288
\variable QScreenCursor::cursor
290
\brief the cursor's image.
296
\variable QScreenCursor::size
298
\brief the cursor's size
302
\variable QScreenCursor::pos
304
\brief the cursor's position, i.e., the position of the top-left
305
corner of the crsor's image
311
\variable QScreenCursor::hotspot
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.
320
\variable QScreenCursor::enable
322
\brief whether the cursor is visible or not
328
\variable QScreenCursor::hwaccel
330
\brief holds whether the cursor is accelerated or not
332
If the cursor is not accelerated, its image will be included by
333
the screen when it composites the window surfaces.
340
\variable QScreenCursor::supportsAlpha
345
\macro qt_screencursor
346
\relates QScreenCursor
348
A global pointer referring to the unique screen cursor. It is
349
equivalent to the pointer returned by the
350
QScreenCursor::instance() function.
358
QScreenPrivate(QScreen *parent, QScreen::ClassId id = QScreen::CustomClass);
361
inline QImage::Format preferredImageFormat() const;
363
typedef void (*SolidFillFunc)(QScreen*, const QColor&, const QRegion&);
364
typedef void (*BlitFunc)(QScreen*, const QImage&, const QPoint&, const QRegion&);
366
SolidFillFunc solidFill;
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;
378
#ifdef QT_QWS_CLIENTBLIT
379
bool supportsBlitInClients;
385
template <typename T>
386
static void solidFill_template(QScreen *screen, const QColor &color,
387
const QRegion ®ion)
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();
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);
400
#ifdef QT_QWS_DEPTH_GENERIC
401
static void solidFill_rgb_32bpp(QScreen *screen, const QColor &color,
402
const QRegion ®ion)
404
quint32 *dest = reinterpret_cast<quint32*>(screen->base());
405
const quint32 c = qt_convertToRgb<quint32>(color.rgba());
407
const int stride = screen->linestep();
408
const QVector<QRect> rects = region.rects();
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);
416
static void solidFill_rgb_16bpp(QScreen *screen, const QColor &color,
417
const QRegion ®ion)
419
quint16 *dest = reinterpret_cast<quint16*>(screen->base());
420
const quint16 c = qt_convertToRgb<quint32>(color.rgba());
422
const int stride = screen->linestep();
423
const QVector<QRect> rects = region.rects();
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);
430
#endif // QT_QWS_DEPTH_GENERIC
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,
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;
443
for (int j = 0; j < height; ++j) {
445
*dest = (*dest & 0xf0) | (value & 0x0f);
447
qt_memfill<quint8>(dest + doAlign, value, width8);
449
quint8 *d = dest + doAlign + width8;
450
*d = (*d & 0x0f) | (value & 0xf0);
456
static void solidFill_gray4(QScreen *screen, const QColor &color,
457
const QRegion ®ion)
459
quint8 *dest = reinterpret_cast<quint8*>(screen->base());
460
const quint8 c = qGray(color.rgba()) >> 4;
461
const quint8 c8 = (c << 4) | c;
463
const int stride = screen->linestep();
464
const QVector<QRect> rects = region.rects();
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(),
472
#endif // QT_QWS_DEPTH_4
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,
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;
490
dest += y * stride + x / pixelsPerByte;
491
stride -= (doAlign + width8);
493
for (int j = 0; j < height; ++j) {
495
*dest = (*dest & ~alignMask) | (value & alignMask);
499
qt_memfill<quint8>(dest, value, width8);
503
*dest = (*dest & tailMask) | (value & ~tailMask);
508
static void solidFill_mono(QScreen *screen, const QColor &color,
509
const QRegion ®ion)
511
quint8 *dest = reinterpret_cast<quint8*>(screen->base());
512
const quint8 c8 = (qGray(color.rgba()) >> 7) * 0xff;
514
const int stride = screen->linestep();
515
const QVector<QRect> rects = region.rects();
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(),
523
#endif // QT_QWS_DEPTH_1
525
void qt_solidFill_setup(QScreen *screen, const QColor &color,
526
const QRegion ®ion)
528
switch (screen->depth()) {
529
#ifdef QT_QWS_DEPTH_32
531
if (screen->pixelType() == QScreen::NormalPixel)
532
screen->d_ptr->solidFill = solidFill_template<quint32>;
534
screen->d_ptr->solidFill = solidFill_template<qabgr8888>;
537
#ifdef QT_QWS_DEPTH_24
539
if (screen->pixelType() == QScreen::NormalPixel)
540
screen->d_ptr->solidFill = solidFill_template<qrgb888>;
542
screen->d_ptr->solidFill = solidFill_template<quint24>;
545
#ifdef QT_QWS_DEPTH_18
547
screen->d_ptr->solidFill = solidFill_template<quint18>;
550
#ifdef QT_QWS_DEPTH_16
552
if (screen->pixelType() == QScreen::NormalPixel)
553
screen->d_ptr->solidFill = solidFill_template<quint16>;
555
screen->d_ptr->solidFill = solidFill_template<qbgr565>;
558
#ifdef QT_QWS_DEPTH_15
560
if (screen->pixelType() == QScreen::NormalPixel)
561
screen->d_ptr->solidFill = solidFill_template<qrgb555>;
563
screen->d_ptr->solidFill = solidFill_template<qbgr555>;
566
#ifdef QT_QWS_DEPTH_12
568
screen->d_ptr->solidFill = solidFill_template<qrgb444>;
571
#ifdef QT_QWS_DEPTH_8
573
screen->d_ptr->solidFill = solidFill_template<quint8>;
576
#ifdef QT_QWS_DEPTH_4
578
screen->d_ptr->solidFill = solidFill_gray4;
581
#ifdef QT_QWS_DEPTH_1
583
screen->d_ptr->solidFill = solidFill_mono;
587
qFatal("solidFill_setup(): Screen depth %d not supported!",
589
screen->d_ptr->solidFill = 0;
592
screen->d_ptr->solidFill(screen, color, region);
595
template <typename DST, typename SRC>
596
static void blit_template(QScreen *screen, const QImage &image,
597
const QPoint &topLeft, const QRegion ®ion)
599
DST *dest = reinterpret_cast<DST*>(screen->base());
600
const int screenStride = screen->linestep();
601
const int imageStride = image.bytesPerLine();
603
if (region.numRects() == 1) {
604
const QRect r = region.boundingRect();
605
const SRC *src = reinterpret_cast<const SRC*>(image.scanLine(r.y()))
607
qt_rectconvert<DST, SRC>(dest, src,
608
r.x() + topLeft.x(), r.y() + topLeft.y(),
609
r.width(), r.height(),
610
screenStride, imageStride);
612
const QVector<QRect> rects = region.rects();
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()))
618
qt_rectconvert<DST, SRC>(dest, src,
619
r.x() + topLeft.x(), r.y() + topLeft.y(),
620
r.width(), r.height(),
621
screenStride, imageStride);
626
#ifdef QT_QWS_DEPTH_32
627
static void blit_32(QScreen *screen, const QImage &image,
628
const QPoint &topLeft, const QRegion ®ion)
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);
636
#ifdef QT_QWS_DEPTH_16
637
case QImage::Format_RGB16:
638
blit_template<quint32, quint16>(screen, image, topLeft, region);
642
qCritical("blit_32(): Image format %d not supported!", image.format());
645
#endif // QT_QWS_DEPTH_32
647
#ifdef QT_QWS_DEPTH_24
648
static void blit_24(QScreen *screen, const QImage &image,
649
const QPoint &topLeft, const QRegion ®ion)
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);
657
case QImage::Format_RGB888:
658
blit_template<quint24, qrgb888>(screen, image, topLeft, region);
660
#ifdef QT_QWS_DEPTH_16
661
case QImage::Format_RGB16:
662
blit_template<quint24, quint16>(screen, image, topLeft, region);
666
qCritical("blit_24(): Image format %d not supported!", image.format());
670
static void blit_qrgb888(QScreen *screen, const QImage &image,
671
const QPoint &topLeft, const QRegion ®ion)
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);
679
case QImage::Format_RGB888:
680
blit_template<qrgb888, qrgb888>(screen, image, topLeft, region);
682
#ifdef QT_QWS_DEPTH_16
683
case QImage::Format_RGB16:
684
blit_template<qrgb888, quint16>(screen, image, topLeft, region);
688
qCritical("blit_24(): Image format %d not supported!", image.format());
692
#endif // QT_QWS_DEPTH_24
694
#ifdef QT_QWS_DEPTH_18
695
static void blit_18(QScreen *screen, const QImage &image,
696
const QPoint &topLeft, const QRegion ®ion)
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);
704
case QImage::Format_RGB666:
705
blit_template<qrgb666, qrgb666>(screen, image, topLeft, region);
707
#ifdef QT_QWS_DEPTH_16
708
case QImage::Format_RGB16:
709
blit_template<qrgb666, quint16>(screen, image, topLeft, region);
713
qCritical("blit_18(): Image format %d not supported!", image.format());
716
#endif // QT_QWS_DEPTH_18
718
#if (Q_BYTE_ORDER == Q_BIG_ENDIAN) && (defined(QT_QWS_DEPTH_16) || defined(QT_QWS_DEPTH_15))
722
inline quint16LE(quint32 v) {
723
data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
726
inline quint16LE(int v) {
727
data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
730
inline quint16LE(quint16 v) {
731
data = ((v & 0xff00) >> 8) | ((v & 0x00ff) << 8);
734
inline quint16LE(qrgb555 v) {
735
data = (( (quint16)v & 0xff00) >> 8) |
736
(( (quint16)v & 0x00ff) << 8);
739
inline bool operator==(const quint16LE &v) const
741
return data == v.data;
749
#ifdef QT_QWS_DEPTH_16
750
static void blit_16(QScreen *screen, const QImage &image,
751
const QPoint &topLeft, const QRegion ®ion)
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);
760
case QImage::Format_RGB16:
761
blit_template<quint16, quint16>(screen, image, topLeft, region);
764
qCritical("blit_16(): Image format %d not supported!", image.format());
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 ®ion)
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);
779
case QImage::Format_RGB16:
780
blit_template<quint16LE, quint16>(screen, image, topLeft, region);
783
qCritical("blit_16_bigToLittleEndian(): Image format %d not supported!", image.format());
787
#endif // Q_BIG_ENDIAN
788
#endif // QT_QWS_DEPTH_16
790
#ifdef QT_QWS_DEPTH_15
791
static void blit_15(QScreen *screen, const QImage &image,
792
const QPoint &topLeft, const QRegion ®ion)
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);
800
case QImage::Format_RGB555:
801
blit_template<qrgb555, qrgb555>(screen, image, topLeft, region);
803
case QImage::Format_RGB16:
804
blit_template<qrgb555, quint16>(screen, image, topLeft, region);
807
qCritical("blit_15(): Image format %d not supported!", image.format());
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 ®ion)
816
switch (image.format()) {
817
case QImage::Format_RGB555:
818
blit_template<quint16LE, qrgb555>(screen, image, topLeft, region);
821
qCritical("blit_15_bigToLittleEndian(): Image format %d not supported!", image.format());
824
#endif // Q_BIG_ENDIAN
825
#endif // QT_QWS_DEPTH_15
828
#ifdef QT_QWS_DEPTH_12
829
static void blit_12(QScreen *screen, const QImage &image,
830
const QPoint &topLeft, const QRegion ®ion)
832
switch (image.format()) {
833
case QImage::Format_ARGB4444_Premultiplied:
834
blit_template<qrgb444, qargb4444>(screen, image, topLeft, region);
836
case QImage::Format_RGB444:
837
blit_template<qrgb444, qrgb444>(screen, image, topLeft, region);
840
qCritical("blit_12(): Image format %d not supported!", image.format());
843
#endif // QT_QWS_DEPTH_12
845
#ifdef QT_QWS_DEPTH_8
846
static void blit_8(QScreen *screen, const QImage &image,
847
const QPoint &topLeft, const QRegion ®ion)
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);
855
case QImage::Format_RGB16:
856
blit_template<quint8, quint16>(screen, image, topLeft, region);
858
case QImage::Format_ARGB4444_Premultiplied:
859
blit_template<quint8, qargb4444>(screen, image, topLeft, region);
861
case QImage::Format_RGB444:
862
blit_template<quint8, qrgb444>(screen, image, topLeft, region);
865
qCritical("blit_8(): Image format %d not supported!", image.format());
868
#endif // QT_QWS_DEPTH_8
870
#ifdef QT_QWS_DEPTH_4
872
struct qgray4 { quint8 dummy; } Q_PACKED;
874
template <typename SRC>
875
Q_STATIC_TEMPLATE_FUNCTION inline quint8 qt_convertToGray4(SRC color);
878
inline quint8 qt_convertToGray4(quint32 color)
880
return qGray(color) >> 4;
884
inline quint8 qt_convertToGray4(quint16 color)
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;
893
inline quint8 qt_convertToGray4(qrgb444 color)
895
return qt_convertToGray4(quint32(color));
899
inline quint8 qt_convertToGray4(qargb4444 color)
901
return qt_convertToGray4(quint32(color));
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)
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;
917
srcStride = srcStride / sizeof(SRC) - width;
918
dstStride -= (width8 + doAlign);
920
for (int i = 0; i < height; ++i) {
922
*dest8 = (*dest8 & 0xf0) | qt_convertToGray4<SRC>(*src++);
927
switch (width8 & 0x03) // duff's device
929
case 0: do { *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
930
| qt_convertToGray4<SRC>(src[1]);
932
case 3: *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
933
| qt_convertToGray4<SRC>(src[1]);
935
case 2: *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
936
| qt_convertToGray4<SRC>(src[1]);
938
case 1: *dest8++ = qt_convertToGray4<SRC>(src[0]) << 4
939
| qt_convertToGray4<SRC>(src[1]);
946
*dest8 = qt_convertToGray4<SRC>(*src++) << 4 | (*dest8 & 0x0f);
954
void qt_rectconvert(qgray4 *dest, const quint32 *src,
955
int x, int y, int width, int height,
956
int dstStride, int srcStride)
958
qt_rectconvert_gray4<quint32>(dest, src, x, y, width, height,
959
dstStride, srcStride);
963
void qt_rectconvert(qgray4 *dest, const quint16 *src,
964
int x, int y, int width, int height,
965
int dstStride, int srcStride)
967
qt_rectconvert_gray4<quint16>(dest, src, x, y, width, height,
968
dstStride, srcStride);
972
void qt_rectconvert(qgray4 *dest, const qrgb444 *src,
973
int x, int y, int width, int height,
974
int dstStride, int srcStride)
976
qt_rectconvert_gray4<qrgb444>(dest, src, x, y, width, height,
977
dstStride, srcStride);
981
void qt_rectconvert(qgray4 *dest, const qargb4444 *src,
982
int x, int y, int width, int height,
983
int dstStride, int srcStride)
985
qt_rectconvert_gray4<qargb4444>(dest, src, x, y, width, height,
986
dstStride, srcStride);
989
static void blit_4(QScreen *screen, const QImage &image,
990
const QPoint &topLeft, const QRegion ®ion)
992
switch (image.format()) {
993
case QImage::Format_ARGB32_Premultiplied:
994
blit_template<qgray4, quint32>(screen, image, topLeft, region);
996
case QImage::Format_RGB16:
997
blit_template<qgray4, quint16>(screen, image, topLeft, region);
999
case QImage::Format_RGB444:
1000
blit_template<qgray4, qrgb444>(screen, image, topLeft, region);
1002
case QImage::Format_ARGB4444_Premultiplied:
1003
blit_template<qgray4, qargb4444>(screen, image, topLeft, region);
1006
qCritical("blit_4(): Image format %d not supported!", image.format());
1009
#endif // QT_QWS_DEPTH_4
1011
#ifdef QT_QWS_DEPTH_1
1013
struct qmono { quint8 dummy; } Q_PACKED;
1015
template <typename SRC>
1016
Q_STATIC_TEMPLATE_FUNCTION inline quint8 qt_convertToMono(SRC color);
1019
inline quint8 qt_convertToMono(quint32 color)
1021
return qGray(color) >> 7;
1025
inline quint8 qt_convertToMono(quint16 color)
1027
return (qGray(qt_colorConvert<quint32, quint16>(color, 0)) >> 7);
1031
inline quint8 qt_convertToMono(qargb4444 color)
1033
return (qGray(quint32(color)) >> 7);
1037
inline quint8 qt_convertToMono(qrgb444 color)
1039
return (qGray(quint32(color)) >> 7);
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)
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;
1060
srcStride = srcStride / sizeof(SRC) - (width8 * 8 + alignWidth);
1061
dstStride -= (width8 + doAlign);
1063
for (int j = 0; j < height; ++j) {
1065
quint8 d = *dest8 & ~alignMask;
1066
for (int i = alignStart; i >= alignStop; --i)
1067
d |= qt_convertToMono<SRC>(*src++) << i;
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]));
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;
1102
void qt_rectconvert(qmono *dest, const quint32 *src,
1103
int x, int y, int width, int height,
1104
int dstStride, int srcStride)
1106
qt_rectconvert_mono<quint32>(dest, src, x, y, width, height,
1107
dstStride, srcStride);
1111
void qt_rectconvert(qmono *dest, const quint16 *src,
1112
int x, int y, int width, int height,
1113
int dstStride, int srcStride)
1115
qt_rectconvert_mono<quint16>(dest, src, x, y, width, height,
1116
dstStride, srcStride);
1120
void qt_rectconvert(qmono *dest, const qrgb444 *src,
1121
int x, int y, int width, int height,
1122
int dstStride, int srcStride)
1124
qt_rectconvert_mono<qrgb444>(dest, src, x, y, width, height,
1125
dstStride, srcStride);
1129
void qt_rectconvert(qmono *dest, const qargb4444 *src,
1130
int x, int y, int width, int height,
1131
int dstStride, int srcStride)
1133
qt_rectconvert_mono<qargb4444>(dest, src, x, y, width, height,
1134
dstStride, srcStride);
1137
static void blit_1(QScreen *screen, const QImage &image,
1138
const QPoint &topLeft, const QRegion ®ion)
1140
switch (image.format()) {
1141
case QImage::Format_ARGB32_Premultiplied:
1142
blit_template<qmono, quint32>(screen, image, topLeft, region);
1144
case QImage::Format_RGB16:
1145
blit_template<qmono, quint16>(screen, image, topLeft, region);
1147
case QImage::Format_RGB444:
1148
blit_template<qmono, qrgb444>(screen, image, topLeft, region);
1150
case QImage::Format_ARGB4444_Premultiplied:
1151
blit_template<qmono, qargb4444>(screen, image, topLeft, region);
1154
qCritical("blit_1(): Image format %d not supported!", image.format());
1157
#endif // QT_QWS_DEPTH_1
1159
#ifdef QT_QWS_DEPTH_GENERIC
1161
static void blit_rgb(QScreen *screen, const QImage &image,
1162
const QPoint &topLeft, const QRegion ®ion)
1164
switch (image.format()) {
1165
case QImage::Format_ARGB32_Premultiplied:
1166
blit_template<qrgb, quint32>(screen, image, topLeft, region);
1168
case QImage::Format_RGB16:
1169
blit_template<qrgb, quint16>(screen, image, topLeft, region);
1172
qCritical("blit_rgb(): Image format %d not supported!", image.format());
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)
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;
1191
screen->d_ptr->solidFill = solidFill_rgb_16bpp;
1193
screen->d_ptr->solidFill = solidFill_rgb_32bpp;
1196
#endif // QT_QWS_DEPTH_GENERIC
1198
void qt_blit_setup(QScreen *screen, const QImage &image,
1199
const QPoint &topLeft, const QRegion ®ion)
1201
switch (screen->depth()) {
1202
#ifdef QT_QWS_DEPTH_32
1204
if (screen->pixelType() == QScreen::NormalPixel)
1205
screen->d_ptr->blit = blit_32;
1207
screen->d_ptr->blit = blit_template<qabgr8888, quint32>;
1210
#ifdef QT_QWS_DEPTH_24
1212
if (screen->pixelType() == QScreen::NormalPixel)
1213
screen->d_ptr->blit = blit_qrgb888;
1215
screen->d_ptr->blit = blit_24;
1218
#ifdef QT_QWS_DEPTH_18
1220
screen->d_ptr->blit = blit_18;
1223
#ifdef QT_QWS_DEPTH_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;
1230
if (screen->pixelType() == QScreen::NormalPixel)
1231
screen->d_ptr->blit = blit_16;
1233
screen->d_ptr->blit = blit_template<qbgr565, quint16>;
1236
#ifdef QT_QWS_DEPTH_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;
1242
#endif // Q_BIG_ENDIAN
1243
if (screen->pixelType() == QScreen::NormalPixel)
1244
screen->d_ptr->blit = blit_15;
1246
screen->d_ptr->blit = blit_template<qbgr555, qrgb555>;
1249
#ifdef QT_QWS_DEPTH_12
1251
screen->d_ptr->blit = blit_12;
1254
#ifdef QT_QWS_DEPTH_8
1256
screen->d_ptr->blit = blit_8;
1259
#ifdef QT_QWS_DEPTH_4
1261
screen->d_ptr->blit = blit_4;
1264
#ifdef QT_QWS_DEPTH_1
1266
screen->d_ptr->blit = blit_1;
1270
qFatal("blit_setup(): Screen depth %d not supported!",
1272
screen->d_ptr->blit = 0;
1275
screen->d_ptr->blit(screen, image, topLeft, region);
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),
1284
classId(id), q_ptr(parent)
1286
solidFill = qt_solidFill_setup;
1287
blit = qt_blit_setup;
1288
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
1289
fb_is_littleEndian = false;
1292
graphicsSystem = &defaultGraphicsSystem;
1295
QScreenPrivate::~QScreenPrivate()
1299
QImage::Format QScreenPrivate::preferredImageFormat() const
1301
if (pixelFormat > QImage::Format_Indexed8)
1304
if (q_ptr->depth() <= 16)
1305
return QImage::Format_RGB16;
1307
return QImage::Format_ARGB32_Premultiplied;
1314
\brief The QScreen class is a base class for screen drivers in
1315
Qt for Embedded Linux.
1317
Note that this class is only available in \l{Qt for Embedded Linux}.
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}.
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
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.
1344
\section1 Framebuffer Management
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.
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()
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
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
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
1384
\section1 Palette Management
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.
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.
1397
\section1 Drawing on Screen
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.
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.
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
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
1426
\section1 Properties
1429
\header \o Property \o Functions
1434
The size of the screen can be retrieved using the screenSize()
1435
function. The size is returned in bytes.
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
1451
Reimplement the setMode() function to be able to set the
1452
framebuffer to a new resolution (width and height) and bit depth.
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.
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.
1466
Use the pixmapLinestepAlignment() to retrieve the value to which
1467
the \e {individual scanlines} of pixmaps should be aligned.
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.
1482
Use the linestep() function to retrieve the length of each
1483
scanline of the framebuffer.
1489
The pixelType() function returns the screen's pixel storage format as
1490
described by the PixelType enum.
1494
\section1 Subclassing and Initial Values
1496
You need to set the following members when implementing a subclass of QScreen:
1499
\header \o Member \o Initial Value
1500
\row \o \l{QScreen::}{data} \o A pointer to the framebuffer if possible;
1502
\row \o \l{QScreen::}{lstep} \o The number of bytes between each scanline
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.
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.
1516
See also the \l{Accelerated Graphics Driver Example} for an example that
1517
shows how to initialize these values.
1519
\sa QScreenDriverPlugin, QScreenDriverFactory, {Qt for Embedded Linux Display
1524
\enum QScreen::PixelType
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
1530
\value NormalPixel Red-green-blue (RGB)
1531
\value BGRPixel Blue-green-red (BGR)
1537
\enum QScreen::ClassId
1539
This enum defines the class identifiers for the known screen subclasses.
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
1556
\variable QScreen::screenclut
1557
\brief the color table
1559
Initialize this variable in a subclass using a paletted screen mode,
1560
and initialize its partner, QScreen::screencols.
1566
\variable QScreen::screencols
1567
\brief the number of entries in the color table
1569
Initialize this variable in a subclass using a paletted screen mode,
1570
and initialize its partner, QScreen::screenclut.
1576
\variable QScreen::data
1577
\brief points to the first visible pixel in the frame buffer.
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
1585
\sa QScreen::size, QScreen::mapsize
1589
\variable QScreen::w
1590
\brief the logical width of the screen.
1592
This variable \e{must} be initialized by a subclass.
1596
\variable QScreen::lstep
1597
\brief the number of bytes representing a line in the frame buffer.
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.
1606
\variable QScreen::h
1607
\brief the logical height of the screen.
1609
This variable \e{must} be initialized by a subclass.
1613
\variable QScreen::d
1614
\brief the pixel depth
1616
This is the number of significant bits used to set a pixel
1617
color. This variable \e{must} be initialized by a subclass.
1621
\variable QScreen::pixeltype
1622
\brief set to BGRPixel
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
1632
\variable QScreen::grayscale
1633
\brief the gray scale screen mode flag
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.
1641
\variable QScreen::dw
1642
\brief the device width
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.
1653
\variable QScreen::dh
1654
\brief the device height
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.
1665
\variable QScreen::size
1666
\brief the number of bytes in the visible region of the frame buffer
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.
1672
\sa QScreen::data, QScreen::mapsize
1676
\variable QScreen::mapsize
1677
\brief the total number of bytes in the frame buffer
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.
1683
\sa QScreen::data, QScreen::size
1687
\variable QScreen::physWidth
1688
\brief the physical width of the screen in millimeters.
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
1696
\variable QScreen::physHeight
1697
\brief the physical height of the screen in millimeters.
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
1705
\fn static QScreen* QScreen::instance()
1707
Returns a pointer to the application's QScreen instance.
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
1714
\sa subScreens(), subScreenIndexAt()
1718
\fn QList<QScreen*> QScreen::subScreens() const
1721
Returns a list of this screen's subscreens. Use the
1722
subScreenIndexAt() function to retrieve the index of a screen at a
1725
Note that if \e this screen consists of several subscreens,
1726
operations to \e this instance will affect all subscreens by
1729
\sa instance(), subScreenIndexAt()
1733
\fn int QScreen::physicalWidth() const
1736
Returns the physical width of the screen in millimeters.
1738
\sa width(), deviceWidth(), physicalHeight()
1742
\fn int QScreen::physicalHeight() const
1745
Returns the physical height of the screen in millimeters.
1747
\sa height(), deviceHeight(), physicalWidth()
1751
\fn virtual bool QScreen::initDevice() = 0
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.
1757
Implement this function to make accelerated drivers set up the
1758
graphics card. Return true to indicate success and false to indicate
1761
\sa shutdownDevice(), connect()
1765
\fn virtual bool QScreen::connect(const QString &displaySpec) = 0
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.
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.
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:
1782
\snippet doc/src/snippets/code/src_gui_embedded_qscreen_qws.cpp 0
1784
For example, to use the mach64 driver on fb1 as display 2:
1786
\snippet doc/src/snippets/code/src_gui_embedded_qscreen_qws.cpp 1
1788
See \l{Qt for Embedded Linux Display Management} for more details.
1790
\sa disconnect(), initDevice(), {Running Qt for Embedded Linux Applications}
1794
\fn QScreen::disconnect()
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.
1801
\sa connect(), shutdownDevice(), {Running Qt for Embedded Linux
1806
\fn QScreen::setMode(int width, int height, int depth)
1808
Implement this function to reset the framebuffer's resolution (\a
1809
width and \a height) and bit \a depth.
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.
1818
\fn QScreen::blank(bool on)
1820
Prevents the screen driver form displaying any content on the
1823
Note that the default implementation does nothing.
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.
1833
\fn int QScreen::pixmapOffsetAlignment()
1835
Returns the value (in bits) to which the start address of pixmaps
1836
held in the graphics card's memory, should be aligned.
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).
1844
\sa pixmapLinestepAlignment()
1848
\fn int QScreen::pixmapLinestepAlignment()
1850
Returns the value (in bits) to which individual scanlines of
1851
pixmaps held in the graphics card's memory, should be
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).
1860
\sa pixmapOffsetAlignment()
1864
\fn QScreen::width() const
1866
Returns the logical width of the framebuffer in pixels.
1868
\sa deviceWidth(), physicalWidth(), height()
1872
\fn int QScreen::height() const
1874
Returns the logical height of the framebuffer in pixels.
1876
\sa deviceHeight(), physicalHeight(), width()
1880
\fn QScreen::depth() const
1882
Returns the depth of the framebuffer, in bits per pixel.
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
1889
\sa clut(), pixmapDepth()
1893
\fn int QScreen::pixmapDepth() const
1895
Returns the preferred depth for pixmaps, in bits per pixel.
1901
\fn QScreen::linestep() const
1903
Returns the length of each scanline of the framebuffer in bytes.
1909
\fn QScreen::deviceWidth() const
1911
Returns the physical width of the framebuffer device in pixels.
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.
1917
\sa width(), physicalWidth(), deviceHeight()
1921
\fn QScreen::deviceHeight() const
1923
Returns the full height of the framebuffer device in pixels.
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.
1929
\sa height(), physicalHeight(), deviceWidth()
1933
\fn uchar *QScreen::base() const
1935
Returns a pointer to the beginning of the framebuffer.
1937
\sa onCard(), region(), totalSize()
1941
\fn uchar *QScreen::cache(int)
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.
1951
\fn QScreen::uncache(uchar *)
1955
This function is called on pixmap destruction to remove them from
1956
graphics card memory.
1960
\fn QScreen::screenSize() const
1962
Returns the size of the screen in bytes.
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.
1967
\sa base(), region()
1971
\fn QScreen::totalSize() const
1973
Returns the size of the available graphics card memory (including
1974
the screen) in bytes.
1979
// Unaccelerated screen/driver setup. Can be overridden by accelerated
1983
\fn QScreen::QScreen(int displayId)
1985
Constructs a new screen driver.
1987
The \a displayId identifies the \l{Qt for Embedded Linux} server to connect
1994
Returns a pointer to the screen's color lookup table (i.e. its
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.
2001
\sa alloc(), depth(), numCols()
2005
\fn int QScreen::numCols()
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.
2017
Constructs a new screen driver.
2019
The \a display_id identifies the \l{Qt for Embedded Linux}
2020
server to connect to. The \a classId specifies the class
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))
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))
2042
Destroys this screen driver.
2051
This function is called by the \l{Qt for Embedded Linux} server before it
2052
calls the disconnect() function when exiting.
2054
Note that the default implementation only hides the mouse cursor;
2055
reimplement this function to do the necessary graphics card
2058
\sa initDevice(), disconnect()
2061
void QScreen::shutdownDevice()
2063
#ifndef QT_NO_QWS_CURSOR
2064
if (qt_screencursor)
2065
qt_screencursor->hide();
2069
extern bool qws_accel; //in qapplication_qws.cpp
2072
\fn PixelType QScreen::pixelType() const
2074
Returns the pixel storage format of the screen.
2078
Returns the pixel format of the screen, or \c QImage::Format_Invalid
2079
if the pixel format is not a supported image format.
2082
QImage::Format QScreen::pixelFormat() const
2084
return d_ptr->pixelFormat;
2088
Sets the screen's pixel format to \a format.
2090
void QScreen::setPixelFormat(QImage::Format format)
2092
d_ptr->pixelFormat = format;
2097
\fn int QScreen::alloc(unsigned int red, unsigned int green, unsigned int blue)
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).
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.
2106
\sa clut(), numCols()
2109
int QScreen::alloc(unsigned int r,unsigned int g,unsigned int b)
2114
return qGray(r, g, b);
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)) {
2122
// search for nearest color
2123
unsigned int mindiff = 0xffffffff;
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;
2133
if (diff < mindiff) {
2140
} else if (d == 4) {
2141
ret = qGray(r, g, b) >> 4;
2142
} else if (d == 1) {
2143
ret = qGray(r, g, b) >= 128;
2145
qFatal("cannot alloc %dbpp color", d);
2152
Saves the current state of the graphics card.
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.
2158
Note that the default implementation does nothing.
2163
void QScreen::save()
2168
Restores the previously saved state of the graphics card.
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.
2174
Note that the default implementation does nothing.
2179
void QScreen::restore()
2183
void QScreen::blank(bool)
2191
void QScreen::set(unsigned int, unsigned int, unsigned int, unsigned int)
2196
\fn bool QScreen::supportsDepth(int depth) const
2198
Returns true if the screen supports the specified color \a depth;
2199
otherwise returns false.
2204
bool QScreen::supportsDepth(int d) const
2207
//Just to simplify the ifdeffery
2208
#ifdef QT_QWS_DEPTH_1
2212
#ifdef QT_QWS_DEPTH_4
2216
#ifdef QT_QWS_DEPTH_8
2220
#ifdef QT_QWS_DEPTH_16
2224
#ifdef QT_QWS_DEPTH_15
2225
} else if (d == 15) {
2228
#ifdef QT_QWS_DEPTH_18
2229
} else if(d==18 || d==19) {
2232
#ifdef QT_QWS_DEPTH_24
2236
#ifdef QT_QWS_DEPTH_32
2245
\fn bool QScreen::onCard(const unsigned char *buffer) const
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).
2250
\sa base(), totalSize()
2253
bool QScreen::onCard(const unsigned char * p) const
2255
long t=(unsigned long)p;
2256
long bmin=(unsigned long)data;
2259
if(t >= bmin+mapsize)
2265
\fn bool QScreen::onCard(const unsigned char * buffer, ulong& offset) const
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
2274
bool QScreen::onCard(const unsigned char * p, ulong& offset) const
2276
long t=(unsigned long)p;
2277
long bmin=(unsigned long)data;
2288
#if !defined(QT_NO_QWS_REPEATER)
2289
{ "Repeater", qt_get_screen_repeater, 0 },
2291
#if defined(QT_QWS_EE)
2292
{ "EE", qt_get_screen_ee, 0 },
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.
2307
Q_GUI_EXPORT QScreen* qt_get_screen(int display_id, const char *spec)
2309
QString displaySpec = QString::fromAscii(spec);
2310
QString driver = displaySpec;
2311
int colon = displaySpec.indexOf(QLatin1Char(':'));
2313
driver.truncate(colon);
2314
driver = driver.trimmed();
2316
bool foundDriver = false;
2317
QString driverName = driver;
2319
QStringList driverList;
2320
if (!driver.isEmpty())
2321
driverList << driver;
2323
driverList = QScreenDriverFactory::keys();
2325
for (int i = 0; i < driverList.size(); ++i) {
2326
const QString driverName = driverList.at(i);
2327
qt_screen = QScreenDriverFactory::create(driverName, display_id);
2330
if (qt_screen->connect(displaySpec)) {
2339
if (driver.isNull())
2340
qFatal("No suitable driver found");
2341
else if (foundDriver)
2342
qFatal("%s: driver cannot connect", driver.toLatin1().constData());
2344
qFatal("%s: driver not found", driver.toLatin1().constData());
2349
#ifndef QT_NO_QWS_CURSOR
2350
static void blendCursor(QImage *dest, const QImage &cursor, const QPoint &offset)
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)
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();
2369
QVarLengthArray<QT_FT_Span, 32> spans(h);
2370
for (int i = 0; i < h; ++i) {
2371
spans[i].x = rect.x();
2373
spans[i].y = rect.y() + i;
2374
spans[i].coverage = 255;
2376
spanData.blend(h, spans.constData(), &spanData);
2378
#endif // QT_NO_QWS_CURSOR
2381
\fn void QScreen::exposeRegion(QRegion region, int windowIndex)
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.
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
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.
2399
Note that there is no need to call this function explicitly.
2401
\sa blit(), solidFill(), blank()
2403
void QScreen::exposeRegion(QRegion r, int windowIndex)
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)
2414
#ifdef QTOPIA_PERFTEST
2415
static enum { PerfTestUnknown, PerfTestOn, PerfTestOff } perfTestState = PerfTestUnknown;
2416
if(PerfTestUnknown == perfTestState) {
2417
if(::getenv("QTOPIA_PERFTEST"))
2418
perfTestState = PerfTestOn;
2420
perfTestState = PerfTestOff;
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" ) );
2432
const QRect bounds = r.boundingRect();
2433
QRegion blendRegion;
2434
QImage *blendBuffer = 0;
2436
#ifndef QT_NO_QWS_CURSOR
2437
if (qt_screencursor && !qt_screencursor->isAccelerated()) {
2438
blendRegion = r & qt_screencursor->boundingRect();
2441
compose(0, r, blendRegion, &blendBuffer, changing);
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);
2453
#endif // QT_NO_QWS_CURSOR
2454
blit(*blendBuffer, offset, blendRegion);
2458
if (r.numRects() == 1) {
2459
setDirty(r.boundingRect());
2461
const QVector<QRect> rects = r.rects();
2462
for (int i = 0; i < rects.size(); ++i)
2463
setDirty(rects.at(i));
2468
\fn void QScreen::blit(const QImage &image, const QPoint &topLeft, const QRegion ®ion)
2470
Copies the given \a region in the given \a image to the point
2471
specified by \a topLeft using device coordinates.
2473
This function is called from the exposeRegion() function; it is
2474
not intended to be called explicitly.
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).
2483
\sa exposeRegion(), solidFill(), blank()
2485
void QScreen::blit(const QImage &img, const QPoint &topLeft, const QRegion ®)
2487
const QRect bound = (region() & QRect(topLeft, img.size())).boundingRect();
2489
d_ptr->blit(this, img, topLeft - offset(),
2490
(reg & bound).translated(-topLeft));
2491
QWSDisplay::ungrab();
2494
#ifdef QT_QWS_CLIENTBLIT
2496
Returns true if this screen driver supports calling QScreen::blit() and
2497
QScreen::setDirty() directly from non-server applications, otherwise returns
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.
2503
\sa setSupportsBlitInClients()
2505
bool QScreen::supportsBlitInClients() const
2507
return d_ptr->supportsBlitInClients;
2511
If \a supported, the screen driver is marked as supporting blitting directly
2512
from non-server applications.
2514
\sa supportsBlitInClients()
2516
void QScreen::setSupportsBlitInClients(bool supported)
2518
d_ptr->supportsBlitInClients = supported;
2526
void QScreen::blit(QWSWindow *win, const QRegion &clip)
2528
QWSWindowSurface *surface = win->windowSurface();
2532
const QImage &img = surface->image();
2536
const QRegion rgn = clip & win->paintedRegion();
2541
blit(img, win->requestedRegion().boundingRect().topLeft(), rgn);
2556
Fills the given \a region of the screen with the specified \a
2559
This function is called from the exposeRegion() function; it is
2560
not intended to be called explicitly.
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).
2569
\sa exposeRegion(), blit(), blank()
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 ®ion)
2575
d_ptr->solidFill(this, color,
2576
region.translated(-offset()) & QRect(0, 0, dw, dh));
2577
QWSDisplay::ungrab();
2583
Creates and returns a new window surface matching the given \a
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
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.
2596
\sa {Qt for Embedded Linux Architecture}
2598
QWSWindowSurface* QScreen::createSurface(const QString &key) const
2600
#ifndef QT_NO_PAINTONSCREEN
2601
if (key == QLatin1String("OnScreen"))
2602
return new QWSOnScreenSurface;
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;
2611
#ifndef QT_NO_PAINT_DEBUG
2612
else if (key == QLatin1String("Yellow"))
2613
return new QWSYellowSurface;
2615
#ifndef QT_NO_DIRECTPAINTER
2616
else if (key == QLatin1String("DirectPainter"))
2617
return new QWSDirectPainterSurface;
2623
#ifndef QT_NO_PAINTONSCREEN
2624
bool QScreen::isWidgetPaintOnScreen(const QWidget *w)
2626
static int doOnScreen = -1;
2627
if (doOnScreen == -1) {
2628
const QByteArray env = qgetenv("QT_ONSCREEN_PAINT");
2632
doOnScreen = (env.toInt() > 0 ? 1 : 0);
2635
if (doOnScreen == 2) // force
2638
if (doOnScreen == 0 && !w->testAttribute(Qt::WA_PaintOnScreen))
2641
return w->d_func()->isOpaque;
2648
Creates and returns a new window surface for the given \a widget.
2650
QWSWindowSurface* QScreen::createSurface(QWidget *widget) const
2652
#ifndef QT_NO_PAINTONSCREEN
2653
if (isWidgetPaintOnScreen(widget) && base())
2654
return new QWSOnScreenSurface(widget);
2657
if (QApplication::type() == QApplication::GuiServer)
2658
return new QWSLocalMemSurface(widget);
2659
#ifndef QT_NO_QWS_MULTIPROCESS
2661
return new QWSSharedMemSurface(widget);
2667
void QScreen::compose(int level, const QRegion &exposed, QRegion &blend,
2668
QImage **blendbuffer, int changing_level)
2670
QRect exposed_bounds = exposed.boundingRect();
2673
win = qwsServer->clientWindows().value(level); // null is background
2675
} while (win && !win->paintedRegion().boundingRect().intersects(exposed_bounds));
2677
QWSWindowSurface *surface = (win ? win->windowSurface() : 0);
2678
bool above_changing = level <= changing_level; // 0 is topmost
2680
QRegion exposedBelow = exposed;
2684
opaque = win->isOpaque() || !surface->isBuffered();
2686
exposedBelow -= win->paintedRegion();
2687
if (above_changing || !surface->isBuffered())
2688
blend -= exposed & win->paintedRegion();
2690
blend += exposed & win->paintedRegion();
2693
if (win && !exposedBelow.isEmpty()) {
2694
compose(level, exposedBelow, blend, blendbuffer, changing_level);
2696
QSize blendSize = blend.boundingRect().size();
2697
if (!blendSize.isNull()) {
2698
*blendbuffer = new QImage(blendSize, d_ptr->preferredImageFormat());
2702
const QRegion blitRegion = exposed - blend;
2704
paintBackground(blitRegion);
2705
else if (!above_changing && surface->isBuffered())
2706
blit(win, blitRegion);
2708
QRegion blendRegion = exposed & blend;
2711
blendRegion &= win->paintedRegion();
2712
if (!blendRegion.isEmpty()) {
2714
QPoint off = blend.boundingRect().topLeft();
2717
rb.prepare(*blendbuffer);
2719
spanData.init(&rb, 0);
2721
const QImage::Format format = (*blendbuffer)->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;
2734
spanData.setup(qwsServer->backgroundBrush(), 256, QPainter::CompositionMode_SourceOver);
2735
spanData.dx = off.x();
2736
spanData.dy = off.y();
2737
} else if (!surface->isBuffered()) {
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();
2750
if (!spanData.blend)
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();
2764
int n = qMin(nspans, ye - y);
2770
spans[i].coverage = 255;
2773
spanData.blend(n, spans, &spanData);
2782
void QScreen::paintBackground(const QRegion &r)
2784
const QBrush &bg = qwsServer->backgroundBrush();
2785
Qt::BrushStyle bs = bg.style();
2786
if (bs == Qt::NoBrush || r.isEmpty())
2789
if (bs == Qt::SolidPattern) {
2790
solidFill(bg.color(), r);
2792
const QRect br = r.boundingRect();
2793
QImage img(br.size(), d_ptr->preferredImageFormat());
2794
QPoint off = br.topLeft();
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);
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();
2813
int n = qMin(nspans, ye - y);
2819
spans[i].coverage = 255;
2822
spanData.blend(n, spans, &spanData);
2826
blit(img, br.topLeft(), r);
2831
\fn virtual int QScreen::sharedRamSize(void *)
2837
\fn QScreen::setDirty(const QRect& rectangle)
2839
Marks the given \a rectangle as dirty.
2841
Note that the default implementation does nothing; reimplement
2842
this function to indicate that the given \a rectangle has been
2846
void QScreen::setDirty(const QRect&)
2851
\fn QScreen::isTransformed() const
2853
Returns true if the screen is transformed (for instance, rotated
2854
90 degrees); otherwise returns false.
2856
\sa transformOrientation(), isInterlaced()
2859
bool QScreen::isTransformed() const
2865
\fn QScreen::isInterlaced() const
2867
Returns true if the display is interlaced (i.e. is displaying
2868
images progressively like a television screen); otherwise returns
2871
If the display is interlaced, the drawing is altered to look
2874
\sa isTransformed(), linestep()
2877
bool QScreen::isInterlaced() const
2879
return false;//qws_screen_is_interlaced;;
2883
\fn QScreen::mapToDevice(const QSize &size) const
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.
2889
Reimplement this function to use the given device's coordinate
2890
system when mapping.
2895
QSize QScreen::mapToDevice(const QSize &s) const
2901
\fn QScreen::mapFromDevice(const QSize &size) const
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.
2907
Reimplement this function to use the given device's coordinate
2908
system when mapping.
2913
QSize QScreen::mapFromDevice(const QSize &s) const
2919
\fn QScreen::mapToDevice(const QPoint &point, const QSize &screenSize) const
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.
2928
QPoint QScreen::mapToDevice(const QPoint &p, const QSize &) const
2934
\fn QScreen::mapFromDevice(const QPoint &point, const QSize &screenSize) const
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.
2943
QPoint QScreen::mapFromDevice(const QPoint &p, const QSize &) const
2949
\fn QScreen::mapToDevice(const QRect &rectangle, const QSize &screenSize) const
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.
2958
QRect QScreen::mapToDevice(const QRect &r, const QSize &) const
2964
\fn QScreen::mapFromDevice(const QRect &rectangle, const QSize &screenSize) const
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.
2973
QRect QScreen::mapFromDevice(const QRect &r, const QSize &) const
2979
\fn QScreen::mapToDevice(const QImage &image) const
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.
2987
QImage QScreen::mapToDevice(const QImage &i) const
2993
\fn QScreen::mapFromDevice(const QImage &image) const
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.
3001
QImage QScreen::mapFromDevice(const QImage &i) const
3007
\fn QScreen::mapToDevice(const QRegion ®ion, const QSize &screenSize) const
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.
3016
QRegion QScreen::mapToDevice(const QRegion &r, const QSize &) const
3022
\fn QScreen::mapFromDevice(const QRegion ®ion, const QSize &screenSize) const
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.
3031
QRegion QScreen::mapFromDevice(const QRegion &r, const QSize &) const
3037
\fn QScreen::transformOrientation() const
3039
Returns the current rotation as an integer value.
3041
Note that the default implementation returns 0; reimplement this
3042
function to override this value.
3047
int QScreen::transformOrientation() const
3052
int QScreen::pixmapDepth() const
3060
int QScreen::memoryNeeded(const QString&)
3068
void QScreen::haltUpdates()
3075
void QScreen::resumeUpdates()
3080
\fn QRegion QScreen::region() const
3083
Returns the region covered by this screen driver.
3085
\sa base(), screenSize()
3091
void QScreen::setOffset(const QPoint &p)
3099
Returns the logical offset of the screen, i.e., the offset between
3100
(0,0) in screen coordinates and the application coordinate system.
3102
QPoint QScreen::offset() const
3104
return d_ptr->offset;
3107
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
3108
void QScreen::setFrameBufferLittleEndian(bool littleEndian)
3110
d_ptr->fb_is_littleEndian = littleEndian;
3113
bool QScreen::frameBufferLittleEndian() const
3115
return d_ptr->fb_is_littleEndian;
3120
\fn int QScreen::subScreenIndexAt(const QPoint &position) const
3123
Returns the index of the subscreen at the given \a position;
3124
returns -1 if no screen is found.
3126
The index identifies the subscreen in the list of pointers
3127
returned by the subScreens() function.
3129
\sa instance(), subScreens()
3131
int QScreen::subScreenIndexAt(const QPoint &p) const
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))
3144
#ifdef QT_LOADABLE_MODULES
3146
// ### needs update after driver init changes
3148
static QScreen * qt_dodriver(char * driver,char * a,unsigned char * b)
3152
strcpy(buf,"/etc/qws/drivers/");
3153
qstrcpy(buf+17,driver);
3154
qDebug("Attempting driver %s",driver);
3157
handle=dlopen(buf,RTLD_LAZY);
3159
qFatal("Module load error");
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");
3166
QScreen * ret=qt_get_screen_func(a,b);
3170
static QScreen * qt_do_entry(char * entry)
3172
unsigned char config[256];
3174
FILE * f=fopen(entry,"r");
3179
int r=fread(config,256,1,f);
3185
unsigned short vendorid=*((unsigned short int *)config);
3186
unsigned short deviceid=*(((unsigned short int *)config)+1);
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);
3198
qDebug("Unrecognised ATI card id %x",deviceid);
3202
qDebug("Unrecognised vendor");
3207
extern bool qws_accel;
3209
/// ** NOT SUPPPORTED **
3211
QScreen * qt_probe_bus()
3214
return qt_dodriver("unaccel.so",0,0);
3217
DIR * dirptr=opendir("/proc/bus/pci");
3219
return qt_dodriver("unaccel.so",0,0);
3223
dirent * busses=readdir(dirptr);
3226
if(busses->d_name[0]!='.') {
3228
strcpy(buf,"/proc/bus/pci/");
3229
qstrcpy(buf+14,busses->d_name);
3231
dirptr2=opendir(buf);
3233
cards=readdir(dirptr2);
3235
if(cards->d_name[0]!='.') {
3237
qstrcpy(buf+p+1,cards->d_name);
3238
QScreen * ret=qt_do_entry(buf);
3242
cards=readdir(dirptr2);
3247
busses=readdir(dirptr);
3251
return qt_dodriver("unaccel.so",0,0);
3256
char *qt_qws_hardcoded_slot = "/proc/bus/pci/01/00.0";
3258
const unsigned char* qt_probe_bus()
3261
slot=::getenv("QWS_CARD_SLOT");
3263
slot=qt_qws_hardcoded_slot;
3265
static unsigned char config[256];
3266
FILE * f=fopen(slot,"r");
3268
qDebug("Open failure for %s",slot);
3271
int r=fread((char*)config,256,1,f);
3274
qDebug("Read failure");
3292
void QScreen::setPixmapDataFactory(QPixmapDataFactory *factory)
3294
static bool shownWarning = false;
3295
if (!shownWarning) {
3296
qWarning("QScreen::setPixmapDataFactory() is deprecated - use setGraphicsSystem() instead");
3297
shownWarning = true;
3300
d_ptr->pixmapFactory = factory;
3307
QPixmapDataFactory* QScreen::pixmapDataFactory() const
3309
return d_ptr->pixmapFactory;
3316
void QScreen::setGraphicsSystem(QGraphicsSystem* system)
3318
d_ptr->graphicsSystem = system;
3325
QGraphicsSystem* QScreen::graphicsSystem() const
3327
return d_ptr->graphicsSystem;
3333
Returns the class identifier for the screen object.
3335
QScreen::ClassId QScreen::classId() const
3337
return static_cast<ClassId>(d_ptr->classId);