source: trunk/src/gui/embedded/qscreen_qws.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

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