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

Last change on this file since 811 was 769, checked in by Dmitry A. Kuminov, 15 years ago

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

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