source: trunk/src/plugins/gfxdrivers/ahi/qscreenahi_qws.cpp@ 561

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

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 16.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the plugins of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qscreenahi_qws.h"
43
44#ifndef QT_NO_QWS_AHI
45
46#include <QtGui/qcolor.h>
47#include <QtGui/qapplication.h>
48#include <QtCore/qvector.h>
49#include <QtCore/qvarlengtharray.h>
50#include <private/qwssignalhandler_p.h>
51
52#include <ahi.h>
53
54//#define QAHISCREEN_DEBUG
55
56static int depthForPixelFormat(const AhiPixelFormat_t format)
57{
58 switch (format) {
59 case AhiPix1bpp:
60 return 1;
61 case AhiPix2bpp:
62 return 2;
63 case AhiPix4bpp:
64 return 4;
65 case AhiPix8bpp_332RGB:
66 case AhiPix8bpp:
67 return 8;
68 case AhiPix16bpp_444RGB:
69 return 12;
70 case AhiPix16bpp_555RGB:
71 return 15;
72 case AhiPix16bpp_565RGB:
73 return 16;
74 case AhiPix32bpp_8888ARGB:
75 case AhiPix32bpp_8888BGRA:
76 return 32;
77 default:
78 return 0;
79 }
80}
81
82static AhiPixelFormat_t pixelFormatForImageFormat(const QImage::Format format)
83{
84 switch (format) {
85 case QImage::Format_Mono:
86 case QImage::Format_MonoLSB:
87 return AhiPix1bpp;
88 case QImage::Format_Indexed8:
89 return AhiPix8bpp;
90 case QImage::Format_RGB32:
91 case QImage::Format_ARGB32:
92 case QImage::Format_ARGB32_Premultiplied:
93 return AhiPix32bpp_8888ARGB;
94 case QImage::Format_RGB16:
95 return AhiPix16bpp_565RGB;
96 case QImage::Format_RGB555:
97 return AhiPix16bpp_555RGB;
98 case QImage::Format_ARGB4444_Premultiplied:
99 case QImage::Format_RGB444:
100 return AhiPix16bpp_444RGB;
101 default:
102 return AhiPixelFormatMax;
103 }
104}
105
106class QAhiScreenCursor : public QScreenCursor
107{
108public:
109 QAhiScreenCursor(QScreen *screen, AhiDevCtx_t context);
110
111 void set(const QImage &image, int hotx, int hoty);
112 void move(int x, int y);
113 void show();
114 void hide();
115
116private:
117 QScreen *screen;
118 AhiDevCtx_t context;
119};
120
121QAhiScreenCursor::QAhiScreenCursor(QScreen *s, AhiDevCtx_t c)
122 : QScreenCursor(), screen(s), context(c)
123{
124 hwaccel = true;
125 supportsAlpha = true;
126
127 if (enable)
128 show();
129 else
130 hide();
131}
132
133void QAhiScreenCursor::set(const QImage &image, int hotx, int hoty)
134{
135 if (image.isNull()) {
136 QScreenCursor::set(image, hotx, hoty);
137 return;
138 }
139
140 if (image.format() != QImage::Format_MonoLSB) {
141 set(image.convertToFormat(QImage::Format_MonoLSB), hotx, hoty);
142 return;
143 }
144
145 AhiPixelFormat_t pixFmt = pixelFormatForImageFormat(image.format());
146
147 if (pixFmt >= AhiPixelFormatMax) { // generic fallback
148 QImage::Format toFormat = screen->pixelFormat();
149 if (toFormat == QImage::Format_Invalid)
150 toFormat = QImage::Format_ARGB32;
151 set(image.convertToFormat(toFormat), hotx, hoty);
152 return;
153 }
154
155 AhiPoint_t hotSpot = { hotx, hoty };
156 AhiSize_t bitmapSize = { image.width(), image.height() };
157 AhiBitmap_t bitmap = { bitmapSize, (void*)(image.bits()),
158 image.bytesPerLine(), pixFmt };
159
160 AhiSts_t status;
161 status = AhiDispCursorSet(context, AhiCursor1, &bitmap, &hotSpot,
162 image.serialNumber(), 0);
163 if (status != AhiStsOk)
164 qWarning("QAhiScreenCursor::set(): AhiDispCursorSet failed: %x",
165 status);
166
167 QScreenCursor::set(image, hotx, hoty);
168}
169
170void QAhiScreenCursor::move(int x, int y)
171{
172 AhiPoint_t pos = { x, y };
173 AhiSts_t status = AhiDispCursorPos(context, AhiCursor1, &pos, 0);
174 if (status != AhiStsOk)
175 qWarning("QAhiScreenCursor::move(): error setting mouse position: %x",
176 status);
177 QScreenCursor::move(x, y);
178}
179
180void QAhiScreenCursor::show()
181{
182 AhiSts_t status;
183 status = AhiDispCursorState(context, AhiCursor1, AhiCursorStateOn, 0);
184 if (status != AhiStsOk)
185 qWarning("QAhiScreenCursor::show(): error setting state: %x", status);
186 QScreenCursor::show();
187}
188
189void QAhiScreenCursor::hide()
190{
191 AhiDispCursorState(context, AhiCursor1, AhiCursorStateOff, 0);
192 QScreenCursor::hide();
193}
194
195class QAhiScreenPrivate : public QObject
196{
197public:
198 QAhiScreenPrivate();
199 ~QAhiScreenPrivate();
200
201 bool setMode(AhiDispMode_t mode);
202
203 AhiDevCtx_t context;
204 AhiSurf_t surface;
205 QAhiScreenCursor *cursor;
206};
207
208QT_BEGIN_NAMESPACE
209
210QAhiScreenPrivate::QAhiScreenPrivate()
211 : context(0), surface(0), cursor(0)
212{
213#ifndef QT_NO_QWS_SIGNALHANDLER
214 QWSSignalHandler::instance()->addObject(this);
215#endif
216}
217
218QAhiScreenPrivate::~QAhiScreenPrivate()
219{
220 delete cursor;
221
222 if (surface) {
223 AhiSurfFree(context, surface);
224 surface = 0;
225 }
226 if (context) {
227 AhiDevClose(context);
228 context = 0;
229 }
230 AhiTerm();
231}
232
233bool QAhiScreenPrivate::setMode(AhiDispMode_t mode)
234{
235 AhiSts_t status;
236
237 status = AhiDispModeSet(context, &mode, 0);
238 if (status != AhiStsOk) {
239 qCritical("QAhiScreenPrivate::setMode(): AhiDispModeSet failed: %x",
240 status);
241 return false;
242 }
243
244 if (surface) {
245 AhiSurfFree(context, surface);
246 surface = 0;
247 }
248 status = AhiSurfAlloc(context, &surface, &mode.size, mode.pixFmt,
249 AHIFLAG_SURFFIXED);
250 if (status != AhiStsOk) {
251 qCritical("QAhiScreenPrivate::setMode(): AhisurfAlloc failed: %x",
252 status);
253 return false;
254 }
255
256 status = AhiDispSurfSet(context, surface, 0);
257 if (status != AhiStsOk) {
258 qCritical("QAhiScreenPrivate::setMode(): AhiDispSurfSet failed: %x",
259 status);
260 return false;
261 }
262
263 return true;
264}
265
266QAhiScreen::QAhiScreen(int displayId)
267 : QScreen(displayId), d_ptr(new QAhiScreenPrivate)
268{
269}
270
271QAhiScreen::~QAhiScreen()
272{
273 delete d_ptr;
274}
275
276bool QAhiScreen::configure()
277{
278 AhiSurfInfo_t surfaceInfo;
279 AhiSts_t status;
280
281 status = AhiSurfInfo(d_ptr->context, d_ptr->surface, &surfaceInfo);
282 if (status != AhiStsOk) {
283 qCritical("QAhiScreen::configure(): AhiSurfInfo failed: %x", status);
284 return false;
285 }
286
287 QScreen::data = 0;
288 QScreen::w = QScreen::dw = surfaceInfo.size.cx;
289 QScreen::h = QScreen::dh = surfaceInfo.size.cy;
290 QScreen::lstep = surfaceInfo.stride;
291 QScreen::size = surfaceInfo.sizeInBytes;
292
293 switch (surfaceInfo.pixFmt) {
294 case AhiPix1bpp:
295 setPixelFormat(QImage::Format_Mono);
296 QScreen::d = 1;
297 break;
298 case AhiPix4bpp:
299 QScreen::d = 4;
300 break;
301 case AhiPix8bpp_332RGB:
302 case AhiPix8bpp:
303 QScreen::d = 8;
304 break;
305 case AhiPix16bpp_444RGB:
306 setPixelFormat(QImage::Format_RGB444);
307 QScreen::d = 12;
308 break;
309 case AhiPix16bpp_555RGB:
310 setPixelFormat(QImage::Format_RGB555);
311 QScreen::d = 15;
312 break;
313 case AhiPix16bpp_565RGB:
314 setPixelFormat(QImage::Format_RGB16);
315 QScreen::d = 16;
316 break;
317 case AhiPix2bpp:
318 QScreen::d = 2;
319 break;
320 case AhiPix32bpp_8888ARGB:
321 setPixelFormat(QImage::Format_ARGB32);
322 // fallthrough
323 case AhiPix32bpp_8888BGRA:
324 QScreen::d = 32;
325 break;
326 default:
327 qCritical("QAhiScreen::configure(): Unknown pixel format: %x",
328 surfaceInfo.pixFmt);
329 return false;
330 }
331
332 const int dpi = 72;
333 QScreen::physWidth = qRound(QScreen::dw * 25.4 / dpi);
334 QScreen::physHeight = qRound(QScreen::dh * 25.4 / dpi);
335
336 return true;
337}
338
339bool QAhiScreen::connect(const QString &displaySpec)
340{
341 Q_UNUSED(displaySpec);
342
343 AhiSts_t status;
344
345 status = AhiInit(0);
346 if (status != AhiStsOk) {
347 qCritical("QAhiScreen::connect(): AhiInit failed: %x", status);
348 return false;
349 }
350
351 AhiDev_t device;
352 AhiDevInfo_t info;
353
354 status = AhiDevEnum(&device, &info, 0);
355 if (status != AhiStsOk) {
356 qCritical("QAhiScreen::connect(): AhiDevEnum failed: %x", status);
357 return false;
358 }
359#ifdef QAHISCREEN_DEBUG
360 {
361 int displayNo = 0;
362 AhiDevInfo_t dispInfo = info;
363 qDebug("AHI supported devices:");
364 do {
365 qDebug(" %2i: %s, sw version: %s (rev %u)\n"
366 " chip: 0x%x (rev %u), mem: %i (%i/%i), bus: 0x%x",
367 displayNo, dispInfo.name,
368 dispInfo.swVersion, uint(dispInfo.swRevision),
369 uint(dispInfo.chipId), uint(dispInfo.revisionId),
370 uint(dispInfo.totalMemory),
371 uint(dispInfo.internalMemSize),
372 uint(dispInfo.externalMemSize),
373 uint(dispInfo.cpuBusInterfaceMode));
374 status = AhiDevEnum(&device, &info, ++displayNo);
375 } while (status == AhiStsOk);
376 }
377#endif
378
379 status = AhiDevOpen(&d_ptr->context, device, "qscreenahi",
380 AHIFLAG_USERLEVEL);
381 if (status != AhiStsOk) {
382 qCritical("QAhiScreen::connect(): AhiDevOpen failed: %x", status);
383 return false;
384 }
385
386 AhiDispMode_t mode;
387
388 status = AhiDispModeEnum(d_ptr->context, &mode, 0);
389 if (status != AhiStsOk) {
390 qCritical("QAhiScreen::connect(): AhiDispModeEnum failed: %x", status);
391 return false;
392 }
393
394#ifdef QAHISCREEN_DEBUG
395 {
396 int modeNo = 0;
397 AhiDispMode_t modeInfo = mode;
398 qDebug("AHI supported modes:");
399 do {
400 qDebug(" %2i: %ux%u, fmt: %i, %u Hz, rot: %i, mirror: %i",
401 modeNo, uint(modeInfo.size.cx), uint(modeInfo.size.cy),
402 modeInfo.pixFmt, uint(modeInfo.frequency),
403 modeInfo.rotation, modeInfo.mirror);
404 status = AhiDispModeEnum(d_ptr->context, &modeInfo, ++modeNo);
405 } while (status == AhiStsOk);
406 }
407#endif
408
409 if (QApplication::type() == QApplication::GuiServer) {
410 if (!d_ptr->setMode(mode))
411 return false;
412 } else {
413 status = AhiDispSurfGet(d_ptr->context, &d_ptr->surface);
414 if (status != AhiStsOk) {
415 qCritical("QAhiScreen::connect(): AhiDispSurfGet failed: %x",
416 status);
417 return false;
418 }
419
420 status = AhiDispModeGet(d_ptr->context, &mode);
421 if (status != AhiStsOk) {
422 qCritical("QAhiScreen::context(): AhiDispModeGet failed: %x",
423 status);
424 return false;
425 }
426 }
427
428 return configure();
429}
430
431void QAhiScreen::disconnect()
432{
433 AhiSurfFree(d_ptr->context, d_ptr->surface);
434 d_ptr->surface = 0;
435 AhiDevClose(d_ptr->context);
436 d_ptr->context = 0;
437 AhiTerm();
438}
439
440bool QAhiScreen::initDevice()
441{
442 QScreenCursor::initSoftwareCursor();
443
444 AhiSts_t status = AhiDispState(d_ptr->context, AhiDispStateOn, 0);
445 if (status != AhiStsOk) {
446 qCritical("QAhiScreen::connect(): AhiDispState failed: %x", status);
447 return false;
448 }
449
450 return true;
451}
452
453void QAhiScreen::shutdownDevice()
454{
455 AhiDispState(d_ptr->context, AhiDispStateOff, 0);
456}
457
458void QAhiScreen::setMode(int width, int height, int depth)
459{
460 int modeNo = 0;
461 AhiDispMode_t mode;
462 AhiSts_t status = AhiStsOk;
463
464 while (status == AhiStsOk) {
465 status = AhiDispModeEnum(d_ptr->context, &mode, modeNo);
466 if (mode.size.cx == uint(width) &&
467 mode.size.cy == uint(height) &&
468 depthForPixelFormat(mode.pixFmt) == depth)
469 {
470 d_ptr->setMode(mode);
471 configure();
472 return;
473 }
474 }
475}
476
477void QAhiScreen::blit(const QImage &image, const QPoint &topLeft,
478 const QRegion &reg)
479{
480 AhiPixelFormat_t pixFmt = pixelFormatForImageFormat(image.format());
481
482 if (pixFmt >= AhiPixelFormatMax) { // generic fallback
483 QImage::Format toFormat = pixelFormat();
484 if (toFormat == QImage::Format_Invalid)
485 toFormat = QImage::Format_ARGB32;
486 blit(image.convertToFormat(toFormat), topLeft, reg);
487 return;
488 }
489
490 AhiSts_t status;
491
492 status = AhiDrawSurfDstSet(d_ptr->context, d_ptr->surface, 0);
493 if (status != AhiStsOk) {
494 qWarning("QAhiScreen::blit(): AhiDrawSurfDstSet failed: %x", status);
495 return;
496 }
497
498 const QVector<QRect> rects = (reg & region()).rects();
499 const int numRects = rects.size();
500 QVarLengthArray<AhiPoint_t, 8> src(numRects);
501 QVarLengthArray<AhiRect_t, 8> dest(numRects);
502
503 for (int i = 0; i < numRects; ++i) {
504 const QRect rect = rects.at(i);
505
506 src[i].x = rect.x() - topLeft.x();
507 src[i].y = rect.y() - topLeft.y();
508 dest[i].left = rect.left();
509 dest[i].top = rect.top();
510 dest[i].right = rect.x() + rect.width();
511 dest[i].bottom = rect.y() + rect.height();
512 }
513
514 AhiSize_t bitmapSize = { image.width(), image.height() };
515 AhiBitmap_t bitmap = { bitmapSize, (void*)(image.bits()),
516 image.bytesPerLine(), pixFmt };
517
518 status = AhiDrawRopSet(d_ptr->context, AHIMAKEROP3(AHIROPSRCCOPY));
519 if (status != AhiStsOk) {
520 qWarning("QAhiScreen::blit(): AhiDrawRopSet failed: %x", status);
521 return;
522 }
523
524 for (int i = 0; i < numRects; ++i) {
525 status = AhiDrawBitmapBlt(d_ptr->context, &dest[i], &src[i],
526 &bitmap, 0, 0);
527 if (status != AhiStsOk) {
528 qWarning("QAhiScreen::blit(): AhiDrawBitmapBlt failed: %x",
529 status);
530 break;
531 }
532 }
533}
534
535void QAhiScreen::solidFill(const QColor &color, const QRegion &reg)
536{
537 AhiSts_t status = AhiStsOk;
538
539 switch (pixelFormat()) {
540 case QImage::Format_ARGB32_Premultiplied:
541 case QImage::Format_ARGB32:
542 case QImage::Format_RGB32:
543 status = AhiDrawBrushFgColorSet(d_ptr->context, color.rgba());
544 break;
545 case QImage::Format_RGB16:
546 status = AhiDrawBrushFgColorSet(d_ptr->context, qt_convRgbTo16(color.rgb()));
547 break;
548 default:
549 qFatal("QAhiScreen::solidFill(): Not implemented for pixel format %d",
550 int(pixelFormat()));
551 break;
552 }
553
554 if (status != AhiStsOk) {
555 qWarning("QAhiScreen::solidFill(): AhiDrawBrushFgColorSet failed: %x",
556 status);
557 return;
558 }
559
560 status = AhiDrawBrushSet(d_ptr->context, 0, 0, 0, AHIFLAG_BRUSHSOLID);
561 if (status != AhiStsOk) {
562 qWarning("QAhiScreen::solidFill(): AhiDrawBrushSet failed: %x",
563 status);
564 return;
565 }
566
567 status = AhiDrawRopSet(d_ptr->context, AHIMAKEROP3(AHIROPPATCOPY));
568 if (status != AhiStsOk) {
569 qWarning("QAhiScreen::solidFill(): AhiDrawRopSet failed: %x", status);
570 return;
571 }
572
573 status = AhiDrawSurfDstSet(d_ptr->context, d_ptr->surface, 0);
574 if (status != AhiStsOk) {
575 qWarning("QAhiScreen::solidFill(): AhiDrawSurfDst failed: %x", status);
576 return;
577 }
578
579 const QVector<QRect> rects = (reg & region()).rects();
580 QVarLengthArray<AhiRect_t> ahiRects(rects.size());
581
582 for (int i = 0; i < rects.size(); ++i) {
583 const QRect rect = rects.at(i);
584 ahiRects[i].left = rect.left();
585 ahiRects[i].top = rect.top();
586 ahiRects[i].right = rect.x() + rect.width();
587 ahiRects[i].bottom = rect.y() + rect.height();
588 }
589
590 status = AhiDrawBitBltMulti(d_ptr->context, ahiRects.data(),
591 0, ahiRects.size());
592 if (status != AhiStsOk)
593 qWarning("QAhiScreen::solidFill(): AhiDrawBitBlt failed: %x", status);
594}
595
596QT_END_NAMESPACE
597
598#endif // QT_NO_QWS_AHI
Note: See TracBrowser for help on using the repository browser.