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