author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Tue, 02 Feb 2010 00:43:10 +0200 | |
changeset 3 | 41300fa6a67c |
parent 0 | 1918ee327afb |
child 4 | 3b1da2848fc7 |
permissions | -rw-r--r-- |
0 | 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 plugins 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 "qdirectfbscreen.h" |
|
43 |
#include "qdirectfbwindowsurface.h" |
|
44 |
#include "qdirectfbpixmap.h" |
|
45 |
#include "qdirectfbmouse.h" |
|
46 |
#include "qdirectfbkeyboard.h" |
|
47 |
#include <QtGui/qwsdisplay_qws.h> |
|
48 |
#include <QtGui/qcolor.h> |
|
49 |
#include <QtGui/qapplication.h> |
|
50 |
#include <QtGui/qwindowsystem_qws.h> |
|
51 |
#include <QtGui/private/qgraphicssystem_qws_p.h> |
|
52 |
#include <QtGui/private/qwssignalhandler_p.h> |
|
53 |
#include <QtCore/qvarlengtharray.h> |
|
54 |
#include <QtCore/qvector.h> |
|
55 |
#include <QtCore/qrect.h> |
|
56 |
||
57 |
#ifndef QT_NO_QWS_DIRECTFB |
|
58 |
||
59 |
QT_BEGIN_NAMESPACE |
|
60 |
||
61 |
class QDirectFBScreenPrivate : public QObject, public QWSGraphicsSystem |
|
62 |
{ |
|
63 |
Q_OBJECT |
|
64 |
public: |
|
65 |
QDirectFBScreenPrivate(QDirectFBScreen *qptr); |
|
66 |
~QDirectFBScreenPrivate(); |
|
67 |
||
68 |
void setFlipFlags(const QStringList &args); |
|
69 |
QPixmapData *createPixmapData(QPixmapData::PixelType type) const; |
|
70 |
public slots: |
|
71 |
#ifdef QT_DIRECTFB_WM |
|
72 |
void onWindowEvent(QWSWindow *window, QWSServer::WindowEvent event); |
|
73 |
#endif |
|
74 |
public: |
|
75 |
IDirectFB *dfb; |
|
76 |
DFBSurfaceFlipFlags flipFlags; |
|
77 |
QDirectFBScreen::DirectFBFlags directFBFlags; |
|
78 |
QImage::Format alphaPixmapFormat; |
|
79 |
IDirectFBScreen *dfbScreen; |
|
80 |
#ifdef QT_NO_DIRECTFB_WM |
|
81 |
IDirectFBSurface *primarySurface; |
|
82 |
QColor backgroundColor; |
|
83 |
#endif |
|
84 |
#ifndef QT_NO_DIRECTFB_LAYER |
|
85 |
IDirectFBDisplayLayer *dfbLayer; |
|
86 |
#endif |
|
87 |
QSet<IDirectFBSurface*> allocatedSurfaces; |
|
88 |
||
89 |
#ifndef QT_NO_DIRECTFB_MOUSE |
|
90 |
QDirectFBMouseHandler *mouse; |
|
91 |
#endif |
|
92 |
#ifndef QT_NO_DIRECTFB_KEYBOARD |
|
93 |
QDirectFBKeyboardHandler *keyboard; |
|
94 |
#endif |
|
95 |
#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE |
|
96 |
IDirectFBImageProvider *imageProvider; |
|
97 |
#endif |
|
98 |
IDirectFBSurface *cursorSurface; |
|
99 |
qint64 cursorImageKey; |
|
100 |
||
101 |
QDirectFBScreen *q; |
|
102 |
static QDirectFBScreen *instance; |
|
103 |
}; |
|
104 |
||
105 |
QDirectFBScreen *QDirectFBScreenPrivate::instance = 0; |
|
106 |
||
107 |
QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *qptr) |
|
108 |
: QWSGraphicsSystem(qptr), dfb(0), flipFlags(DSFLIP_NONE), |
|
109 |
directFBFlags(QDirectFBScreen::NoFlags), alphaPixmapFormat(QImage::Format_Invalid), |
|
110 |
dfbScreen(0) |
|
111 |
#ifdef QT_NO_DIRECTFB_WM |
|
112 |
, primarySurface(0) |
|
113 |
#endif |
|
114 |
#ifndef QT_NO_DIRECTFB_LAYER |
|
115 |
, dfbLayer(0) |
|
116 |
#endif |
|
117 |
#ifndef QT_NO_DIRECTFB_MOUSE |
|
118 |
, mouse(0) |
|
119 |
#endif |
|
120 |
#ifndef QT_NO_DIRECTFB_KEYBOARD |
|
121 |
, keyboard(0) |
|
122 |
#endif |
|
123 |
#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE |
|
124 |
, imageProvider(0) |
|
125 |
#endif |
|
126 |
, cursorSurface(0) |
|
127 |
, cursorImageKey(0) |
|
128 |
, q(qptr) |
|
129 |
{ |
|
130 |
#ifndef QT_NO_QWS_SIGNALHANDLER |
|
131 |
QWSSignalHandler::instance()->addObject(this); |
|
132 |
#endif |
|
133 |
#ifdef QT_DIRECTFB_WM |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
134 |
connect(QWSServer::instance(), SIGNAL(windowEvent(QWSWindow*,QWSServer::WindowEvent)), |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
135 |
this, SLOT(onWindowEvent(QWSWindow*,QWSServer::WindowEvent))); |
0 | 136 |
#endif |
137 |
} |
|
138 |
||
139 |
QDirectFBScreenPrivate::~QDirectFBScreenPrivate() |
|
140 |
{ |
|
141 |
#ifndef QT_NO_DIRECTFB_MOUSE |
|
142 |
delete mouse; |
|
143 |
#endif |
|
144 |
#ifndef QT_NO_DIRECTFB_KEYBOARD |
|
145 |
delete keyboard; |
|
146 |
#endif |
|
147 |
#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE |
|
148 |
if (imageProvider) |
|
149 |
imageProvider->Release(imageProvider); |
|
150 |
#endif |
|
151 |
||
152 |
for (QSet<IDirectFBSurface*>::const_iterator it = allocatedSurfaces.begin(); it != allocatedSurfaces.end(); ++it) { |
|
153 |
(*it)->Release(*it); |
|
154 |
} |
|
155 |
||
156 |
#ifdef QT_NO_DIRECTFB_WM |
|
157 |
if (primarySurface) |
|
158 |
primarySurface->Release(primarySurface); |
|
159 |
#endif |
|
160 |
||
161 |
#ifndef QT_NO_DIRECTFB_LAYER |
|
162 |
if (dfbLayer) |
|
163 |
dfbLayer->Release(dfbLayer); |
|
164 |
#endif |
|
165 |
||
166 |
if (dfbScreen) |
|
167 |
dfbScreen->Release(dfbScreen); |
|
168 |
||
169 |
if (dfb) |
|
170 |
dfb->Release(dfb); |
|
171 |
} |
|
172 |
||
173 |
IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QImage &image, QImage::Format format, SurfaceCreationOptions options, DFBResult *resultPtr) |
|
174 |
{ |
|
175 |
if (image.isNull()) // assert? |
|
176 |
return 0; |
|
177 |
||
178 |
if (QDirectFBScreen::getSurfacePixelFormat(format) == DSPF_UNKNOWN) { |
|
179 |
format = QDirectFBPixmapData::hasAlphaChannel(image) ? d_ptr->alphaPixmapFormat : pixelFormat(); |
|
180 |
} |
|
181 |
if (image.format() != format) { |
|
182 |
return createDFBSurface(image.convertToFormat(format), format, options | NoPreallocated, resultPtr); |
|
183 |
} |
|
184 |
||
185 |
DFBSurfaceDescription description; |
|
186 |
memset(&description, 0, sizeof(DFBSurfaceDescription)); |
|
187 |
description.width = image.width(); |
|
188 |
description.height = image.height(); |
|
189 |
description.flags = DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT; |
|
190 |
initSurfaceDescriptionPixelFormat(&description, format); |
|
191 |
bool doMemCopy = true; |
|
192 |
#ifdef QT_DIRECTFB_PREALLOCATED |
|
193 |
if (!(options & NoPreallocated)) { |
|
194 |
doMemCopy = false; |
|
195 |
description.flags |= DSDESC_PREALLOCATED; |
|
196 |
description.preallocated[0].data = const_cast<uchar*>(image.bits()); |
|
197 |
description.preallocated[0].pitch = image.bytesPerLine(); |
|
198 |
description.preallocated[1].data = 0; |
|
199 |
description.preallocated[1].pitch = 0; |
|
200 |
} |
|
201 |
#endif |
|
202 |
DFBResult result; |
|
203 |
IDirectFBSurface *surface = createDFBSurface(description, options, &result); |
|
204 |
if (resultPtr) |
|
205 |
*resultPtr = result; |
|
206 |
if (!surface) { |
|
207 |
DirectFBError("Couldn't create surface createDFBSurface(QImage, QImage::Format, SurfaceCreationOptions)", result); |
|
208 |
return 0; |
|
209 |
} |
|
210 |
if (doMemCopy) { |
|
211 |
int bplDFB; |
|
212 |
uchar *mem = QDirectFBScreen::lockSurface(surface, DSLF_WRITE, &bplDFB); |
|
213 |
if (mem) { |
|
214 |
const int height = image.height(); |
|
215 |
const int bplQt = image.bytesPerLine(); |
|
216 |
if (bplQt == bplDFB && bplQt == (image.width() * image.depth() / 8)) { |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
217 |
memcpy(mem, image.bits(), image.byteCount()); |
0 | 218 |
} else { |
219 |
for (int i=0; i<height; ++i) { |
|
220 |
memcpy(mem, image.scanLine(i), bplQt); |
|
221 |
mem += bplDFB; |
|
222 |
} |
|
223 |
} |
|
224 |
surface->Unlock(surface); |
|
225 |
} |
|
226 |
} |
|
227 |
#ifdef QT_DIRECTFB_PALETTE |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
228 |
if (image.colorCount() != 0 && surface) |
0 | 229 |
QDirectFBScreen::setSurfaceColorTable(surface, image); |
230 |
#endif |
|
231 |
return surface; |
|
232 |
} |
|
233 |
||
234 |
IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src, |
|
235 |
QImage::Format format, |
|
236 |
SurfaceCreationOptions options, |
|
237 |
DFBResult *result) |
|
238 |
{ |
|
239 |
Q_ASSERT(src); |
|
240 |
QSize size; |
|
241 |
src->GetSize(src, &size.rwidth(), &size.rheight()); |
|
242 |
IDirectFBSurface *surface = createDFBSurface(size, format, options, result); |
|
243 |
DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlphaChannel(surface) |
|
244 |
? DSBLIT_BLEND_ALPHACHANNEL |
|
245 |
: DSBLIT_NOFX; |
|
246 |
if (flags & DSBLIT_BLEND_ALPHACHANNEL) |
|
247 |
surface->Clear(surface, 0, 0, 0, 0); |
|
248 |
||
249 |
surface->SetBlittingFlags(surface, flags); |
|
250 |
surface->Blit(surface, src, 0, 0, 0); |
|
251 |
#if (Q_DIRECTFB_VERSION >= 0x010000) |
|
252 |
surface->ReleaseSource(surface); |
|
253 |
#endif |
|
254 |
return surface; |
|
255 |
} |
|
256 |
||
257 |
IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size, |
|
258 |
QImage::Format format, |
|
259 |
SurfaceCreationOptions options, |
|
260 |
DFBResult *result) |
|
261 |
{ |
|
262 |
DFBSurfaceDescription desc; |
|
263 |
memset(&desc, 0, sizeof(DFBSurfaceDescription)); |
|
264 |
desc.flags |= DSDESC_WIDTH|DSDESC_HEIGHT; |
|
265 |
if (!QDirectFBScreen::initSurfaceDescriptionPixelFormat(&desc, format)) |
|
266 |
return 0; |
|
267 |
desc.width = size.width(); |
|
268 |
desc.height = size.height(); |
|
269 |
return createDFBSurface(desc, options, result); |
|
270 |
} |
|
271 |
||
272 |
IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc, SurfaceCreationOptions options, DFBResult *resultPtr) |
|
273 |
{ |
|
274 |
DFBResult tmp; |
|
275 |
DFBResult &result = (resultPtr ? *resultPtr : tmp); |
|
276 |
result = DFB_OK; |
|
277 |
IDirectFBSurface *newSurface = 0; |
|
278 |
||
279 |
if (!d_ptr->dfb) { |
|
280 |
qWarning("QDirectFBScreen::createDFBSurface() - not connected"); |
|
281 |
return 0; |
|
282 |
} |
|
283 |
||
284 |
if (d_ptr->directFBFlags & VideoOnly |
|
285 |
&& !(desc.flags & DSDESC_PREALLOCATED) |
|
286 |
&& (!(desc.flags & DSDESC_CAPS) || !(desc.caps & DSCAPS_SYSTEMONLY))) { |
|
287 |
// Add the video only capability. This means the surface will be created in video ram |
|
288 |
if (!(desc.flags & DSDESC_CAPS)) { |
|
289 |
desc.caps = DSCAPS_VIDEOONLY; |
|
290 |
desc.flags |= DSDESC_CAPS; |
|
291 |
} else { |
|
292 |
desc.caps |= DSCAPS_VIDEOONLY; |
|
293 |
} |
|
294 |
result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface); |
|
295 |
if (result != DFB_OK |
|
296 |
#ifdef QT_NO_DEBUG |
|
297 |
&& (desc.flags & DSDESC_CAPS) && (desc.caps & DSCAPS_PRIMARY) |
|
298 |
#endif |
|
299 |
) { |
|
300 |
qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n" |
|
301 |
" Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s", |
|
302 |
desc.flags, desc.caps, desc.width, desc.height, |
|
303 |
desc.pixelformat, DFB_PIXELFORMAT_INDEX(desc.pixelformat), |
|
304 |
desc.preallocated[0].data, desc.preallocated[0].pitch, |
|
305 |
DirectFBErrorString(result)); |
|
306 |
} |
|
307 |
desc.caps &= ~DSCAPS_VIDEOONLY; |
|
308 |
} |
|
309 |
||
310 |
if (d_ptr->directFBFlags & SystemOnly) |
|
311 |
desc.caps |= DSCAPS_SYSTEMONLY; |
|
312 |
||
313 |
if (!newSurface) |
|
314 |
result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface); |
|
315 |
||
316 |
if (result != DFB_OK) { |
|
317 |
qWarning("QDirectFBScreen::createDFBSurface() Failed!\n" |
|
318 |
" Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s", |
|
319 |
desc.flags, desc.caps, desc.width, desc.height, |
|
320 |
desc.pixelformat, DFB_PIXELFORMAT_INDEX(desc.pixelformat), |
|
321 |
desc.preallocated[0].data, desc.preallocated[0].pitch, |
|
322 |
DirectFBErrorString(result)); |
|
323 |
return 0; |
|
324 |
} |
|
325 |
||
326 |
Q_ASSERT(newSurface); |
|
327 |
||
328 |
if (options & TrackSurface) { |
|
329 |
d_ptr->allocatedSurfaces.insert(newSurface); |
|
330 |
} |
|
331 |
||
332 |
return newSurface; |
|
333 |
} |
|
334 |
||
335 |
#ifdef QT_DIRECTFB_SUBSURFACE |
|
336 |
IDirectFBSurface *QDirectFBScreen::getSubSurface(IDirectFBSurface *surface, |
|
337 |
const QRect &rect, |
|
338 |
SurfaceCreationOptions options, |
|
339 |
DFBResult *resultPtr) |
|
340 |
{ |
|
341 |
Q_ASSERT(!(options & NoPreallocated)); |
|
342 |
Q_ASSERT(surface); |
|
343 |
DFBResult res; |
|
344 |
DFBResult &result = (resultPtr ? *resultPtr : res); |
|
345 |
IDirectFBSurface *subSurface = 0; |
|
346 |
if (rect.isNull()) { |
|
347 |
result = surface->GetSubSurface(surface, 0, &subSurface); |
|
348 |
} else { |
|
349 |
const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() }; |
|
350 |
result = surface->GetSubSurface(surface, &subRect, &subSurface); |
|
351 |
} |
|
352 |
if (result != DFB_OK) { |
|
353 |
DirectFBError("Can't get sub surface", result); |
|
354 |
} else if (options & TrackSurface) { |
|
355 |
d_ptr->allocatedSurfaces.insert(subSurface); |
|
356 |
} |
|
357 |
return subSurface; |
|
358 |
} |
|
359 |
#endif |
|
360 |
||
361 |
||
362 |
void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface) |
|
363 |
{ |
|
364 |
Q_ASSERT(QDirectFBScreen::instance()); |
|
365 |
Q_ASSERT(surface); |
|
366 |
surface->Release(surface); |
|
367 |
if (!d_ptr->allocatedSurfaces.remove(surface)) |
|
368 |
qWarning("QDirectFBScreen::releaseDFBSurface() - %p not in list", surface); |
|
369 |
||
370 |
//qDebug("Released surface at %p. New count = %d", surface, d_ptr->allocatedSurfaces.count()); |
|
371 |
} |
|
372 |
||
373 |
QDirectFBScreen::DirectFBFlags QDirectFBScreen::directFBFlags() const |
|
374 |
{ |
|
375 |
return d_ptr->directFBFlags; |
|
376 |
} |
|
377 |
||
378 |
IDirectFB *QDirectFBScreen::dfb() |
|
379 |
{ |
|
380 |
return d_ptr->dfb; |
|
381 |
} |
|
382 |
||
383 |
#ifdef QT_NO_DIRECTFB_WM |
|
384 |
IDirectFBSurface *QDirectFBScreen::primarySurface() |
|
385 |
{ |
|
386 |
return d_ptr->primarySurface; |
|
387 |
} |
|
388 |
#endif |
|
389 |
||
390 |
#ifndef QT_NO_DIRECTFB_LAYER |
|
391 |
IDirectFBDisplayLayer *QDirectFBScreen::dfbDisplayLayer() |
|
392 |
{ |
|
393 |
return d_ptr->dfbLayer; |
|
394 |
} |
|
395 |
#endif |
|
396 |
||
397 |
DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format format) |
|
398 |
{ |
|
399 |
switch (format) { |
|
400 |
#ifndef QT_NO_DIRECTFB_PALETTE |
|
401 |
case QImage::Format_Indexed8: |
|
402 |
return DSPF_LUT8; |
|
403 |
#endif |
|
404 |
case QImage::Format_RGB888: |
|
405 |
return DSPF_RGB24; |
|
406 |
case QImage::Format_ARGB4444_Premultiplied: |
|
407 |
return DSPF_ARGB4444; |
|
408 |
#if (Q_DIRECTFB_VERSION >= 0x010100) |
|
409 |
case QImage::Format_RGB444: |
|
410 |
return DSPF_RGB444; |
|
411 |
case QImage::Format_RGB555: |
|
412 |
return DSPF_RGB555; |
|
413 |
#endif |
|
414 |
case QImage::Format_RGB16: |
|
415 |
return DSPF_RGB16; |
|
416 |
#if (Q_DIRECTFB_VERSION >= 0x010000) |
|
417 |
case QImage::Format_ARGB6666_Premultiplied: |
|
418 |
return DSPF_ARGB6666; |
|
419 |
case QImage::Format_RGB666: |
|
420 |
return DSPF_RGB18; |
|
421 |
#endif |
|
422 |
case QImage::Format_RGB32: |
|
423 |
return DSPF_RGB32; |
|
424 |
case QImage::Format_ARGB32_Premultiplied: |
|
425 |
case QImage::Format_ARGB32: |
|
426 |
return DSPF_ARGB; |
|
427 |
default: |
|
428 |
return DSPF_UNKNOWN; |
|
429 |
}; |
|
430 |
} |
|
431 |
||
432 |
QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface) |
|
433 |
{ |
|
434 |
DFBSurfacePixelFormat format; |
|
435 |
surface->GetPixelFormat(surface, &format); |
|
436 |
||
437 |
switch (format) { |
|
438 |
case DSPF_LUT8: |
|
439 |
return QImage::Format_Indexed8; |
|
440 |
case DSPF_RGB24: |
|
441 |
return QImage::Format_RGB888; |
|
442 |
case DSPF_ARGB4444: |
|
443 |
return QImage::Format_ARGB4444_Premultiplied; |
|
444 |
#if (Q_DIRECTFB_VERSION >= 0x010100) |
|
445 |
case DSPF_RGB444: |
|
446 |
return QImage::Format_RGB444; |
|
447 |
case DSPF_RGB555: |
|
448 |
#endif |
|
449 |
case DSPF_ARGB1555: |
|
450 |
return QImage::Format_RGB555; |
|
451 |
case DSPF_RGB16: |
|
452 |
return QImage::Format_RGB16; |
|
453 |
#if (Q_DIRECTFB_VERSION >= 0x010000) |
|
454 |
case DSPF_ARGB6666: |
|
455 |
return QImage::Format_ARGB6666_Premultiplied; |
|
456 |
case DSPF_RGB18: |
|
457 |
return QImage::Format_RGB666; |
|
458 |
#endif |
|
459 |
case DSPF_RGB32: |
|
460 |
return QImage::Format_RGB32; |
|
461 |
case DSPF_ARGB: { |
|
462 |
DFBSurfaceCapabilities caps; |
|
463 |
const DFBResult result = surface->GetCapabilities(surface, &caps); |
|
464 |
Q_ASSERT(result == DFB_OK); |
|
465 |
Q_UNUSED(result); |
|
466 |
return (caps & DSCAPS_PREMULTIPLIED |
|
467 |
? QImage::Format_ARGB32_Premultiplied |
|
468 |
: QImage::Format_ARGB32); } |
|
469 |
default: |
|
470 |
break; |
|
471 |
} |
|
472 |
return QImage::Format_Invalid; |
|
473 |
} |
|
474 |
||
475 |
DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const uint *buffer, |
|
476 |
int length) |
|
477 |
{ |
|
478 |
DFBSurfaceDescription description; |
|
479 |
memset(&description, 0, sizeof(DFBSurfaceDescription)); |
|
480 |
||
481 |
description.flags = DSDESC_CAPS|DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT|DSDESC_PREALLOCATED; |
|
482 |
description.caps = DSCAPS_PREMULTIPLIED; |
|
483 |
description.width = length; |
|
484 |
description.height = 1; |
|
485 |
description.pixelformat = DSPF_ARGB; |
|
486 |
description.preallocated[0].data = (void*)buffer; |
|
487 |
description.preallocated[0].pitch = length * sizeof(uint); |
|
488 |
description.preallocated[1].data = 0; |
|
489 |
description.preallocated[1].pitch = 0; |
|
490 |
return description; |
|
491 |
} |
|
492 |
||
493 |
#ifndef QT_NO_DIRECTFB_PALETTE |
|
494 |
void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface, |
|
495 |
const QImage &image) |
|
496 |
{ |
|
497 |
if (!surface) |
|
498 |
return; |
|
499 |
||
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
500 |
const int numColors = image.colorCount(); |
0 | 501 |
if (numColors == 0) |
502 |
return; |
|
503 |
||
504 |
QVarLengthArray<DFBColor, 256> colors(numColors); |
|
505 |
for (int i = 0; i < numColors; ++i) { |
|
506 |
QRgb c = image.color(i); |
|
507 |
colors[i].a = qAlpha(c); |
|
508 |
colors[i].r = qRed(c); |
|
509 |
colors[i].g = qGreen(c); |
|
510 |
colors[i].b = qBlue(c); |
|
511 |
} |
|
512 |
||
513 |
IDirectFBPalette *palette; |
|
514 |
DFBResult result; |
|
515 |
result = surface->GetPalette(surface, &palette); |
|
516 |
if (result != DFB_OK) { |
|
517 |
DirectFBError("QDirectFBScreen::setSurfaceColorTable GetPalette", |
|
518 |
result); |
|
519 |
return; |
|
520 |
} |
|
521 |
result = palette->SetEntries(palette, colors.data(), numColors, 0); |
|
522 |
if (result != DFB_OK) { |
|
523 |
DirectFBError("QDirectFBScreen::setSurfaceColorTable SetEntries", |
|
524 |
result); |
|
525 |
} |
|
526 |
palette->Release(palette); |
|
527 |
} |
|
528 |
||
529 |
#endif // QT_NO_DIRECTFB_PALETTE |
|
530 |
||
531 |
#if defined QT_DIRECTFB_CURSOR |
|
532 |
class Q_GUI_EXPORT QDirectFBScreenCursor : public QScreenCursor |
|
533 |
{ |
|
534 |
public: |
|
535 |
QDirectFBScreenCursor(); |
|
536 |
virtual void set(const QImage &image, int hotx, int hoty); |
|
537 |
virtual void move(int x, int y); |
|
538 |
virtual void show(); |
|
539 |
virtual void hide(); |
|
540 |
private: |
|
541 |
#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR |
|
542 |
~QDirectFBScreenCursor(); |
|
543 |
bool createWindow(); |
|
544 |
IDirectFBWindow *window; |
|
545 |
#endif |
|
546 |
IDirectFBDisplayLayer *layer; |
|
547 |
}; |
|
548 |
||
549 |
QDirectFBScreenCursor::QDirectFBScreenCursor() |
|
550 |
{ |
|
551 |
IDirectFB *fb = QDirectFBScreen::instance()->dfb(); |
|
552 |
if (!fb) |
|
553 |
qFatal("QDirectFBScreenCursor: DirectFB not initialized"); |
|
554 |
||
555 |
layer = QDirectFBScreen::instance()->dfbDisplayLayer(); |
|
556 |
Q_ASSERT(layer); |
|
557 |
||
558 |
enable = false; |
|
559 |
hwaccel = true; |
|
560 |
supportsAlpha = true; |
|
561 |
#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR |
|
562 |
window = 0; |
|
563 |
DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE); |
|
564 |
if (result != DFB_OK) { |
|
565 |
DirectFBError("QDirectFBScreenCursor::hide: " |
|
566 |
"Unable to set cooperative level", result); |
|
567 |
} |
|
568 |
result = layer->SetCursorOpacity(layer, 0); |
|
569 |
if (result != DFB_OK) { |
|
570 |
DirectFBError("QDirectFBScreenCursor::hide: " |
|
571 |
"Unable to set cursor opacity", result); |
|
572 |
} |
|
573 |
||
574 |
result = layer->SetCooperativeLevel(layer, DLSCL_SHARED); |
|
575 |
if (result != DFB_OK) { |
|
576 |
DirectFBError("QDirectFBScreenCursor::hide: " |
|
577 |
"Unable to set cooperative level", result); |
|
578 |
} |
|
579 |
#endif |
|
580 |
} |
|
581 |
||
582 |
#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR |
|
583 |
QDirectFBScreenCursor::~QDirectFBScreenCursor() |
|
584 |
{ |
|
585 |
if (window) { |
|
586 |
window->Release(window); |
|
587 |
window = 0; |
|
588 |
} |
|
589 |
} |
|
590 |
||
591 |
bool QDirectFBScreenCursor::createWindow() |
|
592 |
{ |
|
593 |
Q_ASSERT(!window); |
|
594 |
Q_ASSERT(!cursor.isNull()); |
|
595 |
DFBWindowDescription description; |
|
596 |
memset(&description, 0, sizeof(DFBWindowDescription)); |
|
597 |
description.flags = DWDESC_POSX|DWDESC_POSY|DWDESC_WIDTH|DWDESC_HEIGHT|DWDESC_CAPS|DWDESC_PIXELFORMAT|DWDESC_SURFACE_CAPS; |
|
598 |
description.width = cursor.width(); |
|
599 |
description.height = cursor.height(); |
|
600 |
description.posx = pos.x() - hotspot.x(); |
|
601 |
description.posy = pos.y() - hotspot.y(); |
|
602 |
#if (Q_DIRECTFB_VERSION >= 0x010100) |
|
603 |
description.flags |= DWDESC_OPTIONS; |
|
604 |
description.options = DWOP_GHOST|DWOP_ALPHACHANNEL; |
|
605 |
#endif |
|
606 |
description.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER; |
|
607 |
const QImage::Format format = QDirectFBScreen::instance()->alphaPixmapFormat(); |
|
608 |
description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); |
|
609 |
if (QDirectFBScreen::isPremultiplied(format)) |
|
610 |
description.surface_caps = DSCAPS_PREMULTIPLIED; |
|
611 |
||
612 |
DFBResult result = layer->CreateWindow(layer, &description, &window); |
|
613 |
if (result != DFB_OK) { |
|
614 |
DirectFBError("QDirectFBScreenCursor::createWindow: Unable to create window", result); |
|
615 |
return false; |
|
616 |
} |
|
617 |
result = window->SetOpacity(window, 255); |
|
618 |
if (result != DFB_OK) { |
|
619 |
DirectFBError("QDirectFBScreenCursor::createWindow: Unable to set opacity ", result); |
|
620 |
return false; |
|
621 |
} |
|
622 |
||
623 |
result = window->SetStackingClass(window, DWSC_UPPER); |
|
624 |
if (result != DFB_OK) { |
|
625 |
DirectFBError("QDirectFBScreenCursor::createWindow: Unable to set stacking class ", result); |
|
626 |
return false; |
|
627 |
} |
|
628 |
||
629 |
result = window->RaiseToTop(window); |
|
630 |
if (result != DFB_OK) { |
|
631 |
DirectFBError("QDirectFBScreenCursor::createWindow: Unable to raise window ", result); |
|
632 |
return false; |
|
633 |
} |
|
634 |
||
635 |
return true; |
|
636 |
} |
|
637 |
#endif |
|
638 |
||
639 |
void QDirectFBScreenCursor::move(int x, int y) |
|
640 |
{ |
|
641 |
pos = QPoint(x, y); |
|
642 |
#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR |
|
643 |
if (window) { |
|
644 |
const QPoint p = pos - hotspot; |
|
645 |
DFBResult result = window->MoveTo(window, p.x(), p.y()); |
|
646 |
if (result != DFB_OK) { |
|
647 |
DirectFBError("QDirectFBScreenCursor::move: Unable to move window", result); |
|
648 |
} |
|
649 |
} |
|
650 |
#else |
|
651 |
layer->WarpCursor(layer, x, y); |
|
652 |
#endif |
|
653 |
} |
|
654 |
||
655 |
void QDirectFBScreenCursor::hide() |
|
656 |
{ |
|
657 |
if (enable) { |
|
658 |
enable = false; |
|
659 |
DFBResult result; |
|
660 |
#ifndef QT_DIRECTFB_WINDOW_AS_CURSOR |
|
661 |
result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE); |
|
662 |
if (result != DFB_OK) { |
|
663 |
DirectFBError("QDirectFBScreenCursor::hide: " |
|
664 |
"Unable to set cooperative level", result); |
|
665 |
} |
|
666 |
result = layer->SetCursorOpacity(layer, 0); |
|
667 |
if (result != DFB_OK) { |
|
668 |
DirectFBError("QDirectFBScreenCursor::hide: " |
|
669 |
"Unable to set cursor opacity", result); |
|
670 |
} |
|
671 |
result = layer->SetCooperativeLevel(layer, DLSCL_SHARED); |
|
672 |
if (result != DFB_OK) { |
|
673 |
DirectFBError("QDirectFBScreenCursor::hide: " |
|
674 |
"Unable to set cooperative level", result); |
|
675 |
} |
|
676 |
#else |
|
677 |
if (window) { |
|
678 |
result = window->SetOpacity(window, 0); |
|
679 |
if (result != DFB_OK) { |
|
680 |
DirectFBError("QDirectFBScreenCursor::hide: " |
|
681 |
"Unable to set window opacity", result); |
|
682 |
} |
|
683 |
} |
|
684 |
#endif |
|
685 |
} |
|
686 |
} |
|
687 |
||
688 |
void QDirectFBScreenCursor::show() |
|
689 |
{ |
|
690 |
if (!enable) { |
|
691 |
enable = true; |
|
692 |
DFBResult result; |
|
693 |
result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE); |
|
694 |
if (result != DFB_OK) { |
|
695 |
DirectFBError("QDirectFBScreenCursor::show: " |
|
696 |
"Unable to set cooperative level", result); |
|
697 |
} |
|
698 |
result = layer->SetCursorOpacity(layer, |
|
699 |
#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR |
|
700 |
0 |
|
701 |
#else |
|
702 |
255 |
|
703 |
#endif |
|
704 |
); |
|
705 |
if (result != DFB_OK) { |
|
706 |
DirectFBError("QDirectFBScreenCursor::show: " |
|
707 |
"Unable to set cursor shape", result); |
|
708 |
} |
|
709 |
result = layer->SetCooperativeLevel(layer, DLSCL_SHARED); |
|
710 |
if (result != DFB_OK) { |
|
711 |
DirectFBError("QDirectFBScreenCursor::show: " |
|
712 |
"Unable to set cooperative level", result); |
|
713 |
} |
|
714 |
#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR |
|
715 |
if (window) { |
|
716 |
DFBResult result = window->SetOpacity(window, 255); |
|
717 |
if (result != DFB_OK) { |
|
718 |
DirectFBError("QDirectFBScreenCursor::show: " |
|
719 |
"Unable to set window opacity", result); |
|
720 |
} |
|
721 |
} |
|
722 |
#endif |
|
723 |
} |
|
724 |
} |
|
725 |
||
726 |
void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty) |
|
727 |
{ |
|
728 |
QDirectFBScreen *screen = QDirectFBScreen::instance(); |
|
729 |
if (!screen) |
|
730 |
return; |
|
731 |
||
732 |
if (image.isNull()) { |
|
733 |
cursor = QImage(); |
|
734 |
hide(); |
|
735 |
} else { |
|
736 |
cursor = image.convertToFormat(screen->alphaPixmapFormat()); |
|
737 |
size = cursor.size(); |
|
738 |
hotspot = QPoint(hotx, hoty); |
|
739 |
DFBResult result = DFB_OK; |
|
740 |
IDirectFBSurface *surface = screen->createDFBSurface(cursor, screen->alphaPixmapFormat(), |
|
741 |
QDirectFBScreen::DontTrackSurface, &result); |
|
742 |
if (!surface) { |
|
743 |
DirectFBError("QDirectFBScreenCursor::set: Unable to create surface", result); |
|
744 |
return; |
|
745 |
} |
|
746 |
#ifndef QT_DIRECTFB_WINDOW_AS_CURSOR |
|
747 |
result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE); |
|
748 |
if (result != DFB_OK) { |
|
749 |
DirectFBError("QDirectFBScreenCursor::show: " |
|
750 |
"Unable to set cooperative level", result); |
|
751 |
} |
|
752 |
result = layer->SetCursorShape(layer, surface, hotx, hoty); |
|
753 |
if (result != DFB_OK) { |
|
754 |
DirectFBError("QDirectFBScreenCursor::show: " |
|
755 |
"Unable to set cursor shape", result); |
|
756 |
} |
|
757 |
result = layer->SetCooperativeLevel(layer, DLSCL_SHARED); |
|
758 |
if (result != DFB_OK) { |
|
759 |
DirectFBError("QDirectFBScreenCursor::show: " |
|
760 |
"Unable to set cooperative level", result); |
|
761 |
} |
|
762 |
#else |
|
763 |
if (window || createWindow()) { |
|
764 |
QSize windowSize; |
|
765 |
result = window->GetSize(window, &windowSize.rwidth(), &windowSize.rheight()); |
|
766 |
if (result != DFB_OK) { |
|
767 |
DirectFBError("QDirectFBScreenCursor::set: " |
|
768 |
"Unable to get window size", result); |
|
769 |
} |
|
770 |
result = window->Resize(window, size.width(), size.height()); |
|
771 |
if (result != DFB_OK) { |
|
772 |
DirectFBError("QDirectFBScreenCursor::set: Unable to resize window", result); |
|
773 |
} |
|
774 |
||
775 |
IDirectFBSurface *windowSurface; |
|
776 |
result = window->GetSurface(window, &windowSurface); |
|
777 |
if (result != DFB_OK) { |
|
778 |
DirectFBError("QDirectFBScreenCursor::set: Unable to get window surface", result); |
|
779 |
} else { |
|
780 |
result = windowSurface->Clear(windowSurface, 0, 0, 0, 0); |
|
781 |
if (result != DFB_OK) { |
|
782 |
DirectFBError("QDirectFBScreenCursor::set: Unable to clear surface", result); |
|
783 |
} |
|
784 |
||
785 |
result = windowSurface->Blit(windowSurface, surface, 0, 0, 0); |
|
786 |
if (result != DFB_OK) { |
|
787 |
DirectFBError("QDirectFBScreenCursor::set: Unable to blit to surface", result); |
|
788 |
} |
|
789 |
} |
|
790 |
result = windowSurface->Flip(windowSurface, 0, DSFLIP_NONE); |
|
791 |
if (result != DFB_OK) { |
|
792 |
DirectFBError("QDirectFBScreenCursor::set: Unable to flip window", result); |
|
793 |
} |
|
794 |
||
795 |
windowSurface->Release(windowSurface); |
|
796 |
} |
|
797 |
#endif |
|
798 |
surface->Release(surface); |
|
799 |
show(); |
|
800 |
} |
|
801 |
||
802 |
} |
|
803 |
#endif // QT_DIRECTFB_CURSOR |
|
804 |
||
805 |
QDirectFBScreen::QDirectFBScreen(int display_id) |
|
806 |
: QScreen(display_id, DirectFBClass), d_ptr(new QDirectFBScreenPrivate(this)) |
|
807 |
{ |
|
808 |
QDirectFBScreenPrivate::instance = this; |
|
809 |
} |
|
810 |
||
811 |
QDirectFBScreen::~QDirectFBScreen() |
|
812 |
{ |
|
813 |
if (QDirectFBScreenPrivate::instance == this) |
|
814 |
QDirectFBScreenPrivate::instance = 0; |
|
815 |
delete d_ptr; |
|
816 |
} |
|
817 |
||
818 |
QDirectFBScreen *QDirectFBScreen::instance() |
|
819 |
{ |
|
820 |
return QDirectFBScreenPrivate::instance; |
|
821 |
} |
|
822 |
||
823 |
int QDirectFBScreen::depth(DFBSurfacePixelFormat format) |
|
824 |
{ |
|
825 |
switch (format) { |
|
826 |
case DSPF_A1: |
|
827 |
return 1; |
|
828 |
case DSPF_A8: |
|
829 |
case DSPF_RGB332: |
|
830 |
case DSPF_LUT8: |
|
831 |
case DSPF_ALUT44: |
|
832 |
return 8; |
|
833 |
case DSPF_I420: |
|
834 |
case DSPF_YV12: |
|
835 |
case DSPF_NV12: |
|
836 |
case DSPF_NV21: |
|
837 |
#if (Q_DIRECTFB_VERSION >= 0x010100) |
|
838 |
case DSPF_RGB444: |
|
839 |
#endif |
|
840 |
return 12; |
|
841 |
#if (Q_DIRECTFB_VERSION >= 0x010100) |
|
842 |
case DSPF_RGB555: |
|
843 |
return 15; |
|
844 |
#endif |
|
845 |
case DSPF_ARGB1555: |
|
846 |
case DSPF_RGB16: |
|
847 |
case DSPF_YUY2: |
|
848 |
case DSPF_UYVY: |
|
849 |
case DSPF_NV16: |
|
850 |
case DSPF_ARGB2554: |
|
851 |
case DSPF_ARGB4444: |
|
852 |
return 16; |
|
853 |
case DSPF_RGB24: |
|
854 |
return 24; |
|
855 |
case DSPF_RGB32: |
|
856 |
case DSPF_ARGB: |
|
857 |
case DSPF_AiRGB: |
|
858 |
return 32; |
|
859 |
case DSPF_UNKNOWN: |
|
860 |
default: |
|
861 |
return 0; |
|
862 |
}; |
|
863 |
return 0; |
|
864 |
} |
|
865 |
||
866 |
int QDirectFBScreen::depth(QImage::Format format) |
|
867 |
{ |
|
868 |
int depth = 0; |
|
869 |
switch(format) { |
|
870 |
case QImage::Format_Invalid: |
|
871 |
case QImage::NImageFormats: |
|
872 |
Q_ASSERT(false); |
|
873 |
case QImage::Format_Mono: |
|
874 |
case QImage::Format_MonoLSB: |
|
875 |
depth = 1; |
|
876 |
break; |
|
877 |
case QImage::Format_Indexed8: |
|
878 |
depth = 8; |
|
879 |
break; |
|
880 |
case QImage::Format_RGB32: |
|
881 |
case QImage::Format_ARGB32: |
|
882 |
case QImage::Format_ARGB32_Premultiplied: |
|
883 |
depth = 32; |
|
884 |
break; |
|
885 |
case QImage::Format_RGB555: |
|
886 |
case QImage::Format_RGB16: |
|
887 |
case QImage::Format_RGB444: |
|
888 |
case QImage::Format_ARGB4444_Premultiplied: |
|
889 |
depth = 16; |
|
890 |
break; |
|
891 |
case QImage::Format_RGB666: |
|
892 |
case QImage::Format_ARGB6666_Premultiplied: |
|
893 |
case QImage::Format_ARGB8565_Premultiplied: |
|
894 |
case QImage::Format_ARGB8555_Premultiplied: |
|
895 |
case QImage::Format_RGB888: |
|
896 |
depth = 24; |
|
897 |
break; |
|
898 |
} |
|
899 |
return depth; |
|
900 |
} |
|
901 |
||
902 |
void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args) |
|
903 |
{ |
|
904 |
QRegExp flipRegexp(QLatin1String("^flip=([\\w,]*)$")); |
|
905 |
int index = args.indexOf(flipRegexp); |
|
906 |
if (index >= 0) { |
|
907 |
const QStringList flips = flipRegexp.cap(1).split(QLatin1Char(','), |
|
908 |
QString::SkipEmptyParts); |
|
909 |
flipFlags = DSFLIP_NONE; |
|
910 |
foreach(const QString &flip, flips) { |
|
911 |
if (flip == QLatin1String("wait")) |
|
912 |
flipFlags |= DSFLIP_WAIT; |
|
913 |
else if (flip == QLatin1String("blit")) |
|
914 |
flipFlags |= DSFLIP_BLIT; |
|
915 |
else if (flip == QLatin1String("onsync")) |
|
916 |
flipFlags |= DSFLIP_ONSYNC; |
|
917 |
else if (flip == QLatin1String("pipeline")) |
|
918 |
flipFlags |= DSFLIP_PIPELINE; |
|
919 |
else |
|
920 |
qWarning("QDirectFBScreen: Unknown flip argument: %s", |
|
921 |
qPrintable(flip)); |
|
922 |
} |
|
923 |
} else { |
|
924 |
flipFlags = DSFLIP_BLIT; |
|
925 |
} |
|
926 |
} |
|
927 |
||
928 |
#ifdef QT_DIRECTFB_WM |
|
929 |
void QDirectFBScreenPrivate::onWindowEvent(QWSWindow *window, QWSServer::WindowEvent event) |
|
930 |
{ |
|
931 |
if (event == QWSServer::Raise) { |
|
932 |
QWSWindowSurface *windowSurface = window->windowSurface(); |
|
933 |
if (windowSurface && windowSurface->key() == QLatin1String("directfb")) { |
|
934 |
static_cast<QDirectFBWindowSurface*>(windowSurface)->raise(); |
|
935 |
} |
|
936 |
} |
|
937 |
} |
|
938 |
#endif |
|
939 |
||
940 |
QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType type) const |
|
941 |
{ |
|
942 |
if (type == QPixmapData::BitmapType) |
|
943 |
return QWSGraphicsSystem::createPixmapData(type); |
|
944 |
||
945 |
return new QDirectFBPixmapData(q, type); |
|
946 |
} |
|
947 |
||
948 |
#if (Q_DIRECTFB_VERSION >= 0x000923) |
|
949 |
#ifdef QT_NO_DEBUG |
|
950 |
struct FlagDescription; |
|
951 |
static const FlagDescription *accelerationDescriptions = 0; |
|
952 |
static const FlagDescription *blitDescriptions = 0; |
|
953 |
static const FlagDescription *drawDescriptions = 0; |
|
954 |
#else |
|
955 |
struct FlagDescription { |
|
956 |
const char *name; |
|
957 |
uint flag; |
|
958 |
}; |
|
959 |
||
960 |
static const FlagDescription accelerationDescriptions[] = { |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
961 |
{ "DFXL_NONE", DFXL_NONE }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
962 |
{ "DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
963 |
{ "DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
964 |
{ "DFXL_DRAWLINE", DFXL_DRAWLINE }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
965 |
{ "DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
966 |
{ "DFXL_BLIT", DFXL_BLIT }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
967 |
{ "DFXL_STRETCHBLIT", DFXL_STRETCHBLIT }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
968 |
{ "DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
969 |
{ "DFXL_DRAWSTRING", DFXL_DRAWSTRING }, |
0 | 970 |
{ 0, 0 } |
971 |
}; |
|
972 |
||
973 |
static const FlagDescription blitDescriptions[] = { |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
974 |
{ "DSBLIT_NOFX", DSBLIT_NOFX }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
975 |
{ "DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
976 |
{ "DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
977 |
{ "DSBLIT_COLORIZE", DSBLIT_COLORIZE }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
978 |
{ "DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
979 |
{ "DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
980 |
{ "DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
981 |
{ "DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
982 |
{ "DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
983 |
{ "DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE }, |
0 | 984 |
#if (Q_DIRECTFB_VERSION >= 0x000923) |
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
985 |
{ "DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
986 |
{ "DSBLIT_XOR", DSBLIT_XOR }, |
0 | 987 |
#endif |
988 |
#if (Q_DIRECTFB_VERSION >= 0x010000) |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
989 |
{ "DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION }, |
0 | 990 |
#endif |
991 |
{ 0, 0 } |
|
992 |
}; |
|
993 |
||
994 |
static const FlagDescription drawDescriptions[] = { |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
995 |
{ "DSDRAW_NOFX", DSDRAW_NOFX }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
996 |
{ "DSDRAW_BLEND", DSDRAW_BLEND }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
997 |
{ "DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
998 |
{ "DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
999 |
{ "DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1000 |
{ "DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY }, |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1001 |
{ "DSDRAW_XOR", DSDRAW_XOR }, |
0 | 1002 |
{ 0, 0 } |
1003 |
}; |
|
1004 |
#endif |
|
1005 |
||
1006 |
static const QByteArray flagDescriptions(uint mask, const FlagDescription *flags) |
|
1007 |
{ |
|
1008 |
#ifdef QT_NO_DEBUG |
|
1009 |
Q_UNUSED(mask); |
|
1010 |
Q_UNUSED(flags); |
|
1011 |
return QByteArray(""); |
|
1012 |
#else |
|
1013 |
if (!mask) |
|
1014 |
return flags[0].name; |
|
1015 |
||
1016 |
QStringList list; |
|
1017 |
for (int i=1; flags[i].name; ++i) { |
|
1018 |
if (mask & flags[i].flag) { |
|
1019 |
list.append(QString::fromLatin1(flags[i].name)); |
|
1020 |
} |
|
1021 |
} |
|
1022 |
Q_ASSERT(!list.isEmpty()); |
|
1023 |
return (QLatin1Char(' ') + list.join(QLatin1String("|"))).toLatin1(); |
|
1024 |
#endif |
|
1025 |
} |
|
1026 |
static void printDirectFBInfo(IDirectFB *fb, IDirectFBSurface *primarySurface) |
|
1027 |
{ |
|
1028 |
DFBResult result; |
|
1029 |
DFBGraphicsDeviceDescription dev; |
|
1030 |
||
1031 |
result = fb->GetDeviceDescription(fb, &dev); |
|
1032 |
if (result != DFB_OK) { |
|
1033 |
DirectFBError("Error reading graphics device description", result); |
|
1034 |
return; |
|
1035 |
} |
|
1036 |
||
1037 |
DFBSurfacePixelFormat pixelFormat; |
|
1038 |
primarySurface->GetPixelFormat(primarySurface, &pixelFormat); |
|
1039 |
||
1040 |
qDebug("Device: %s (%s), Driver: %s v%i.%i (%s) Pixelformat: %d (%d)\n" |
|
1041 |
"acceleration: 0x%x%s\nblit: 0x%x%s\ndraw: 0x%0x%s\nvideo: %iKB\n", |
|
1042 |
dev.name, dev.vendor, dev.driver.name, dev.driver.major, |
|
1043 |
dev.driver.minor, dev.driver.vendor, DFB_PIXELFORMAT_INDEX(pixelFormat), |
|
1044 |
QDirectFBScreen::getImageFormat(primarySurface), dev.acceleration_mask, |
|
1045 |
flagDescriptions(dev.acceleration_mask, accelerationDescriptions).constData(), |
|
1046 |
dev.blitting_flags, flagDescriptions(dev.blitting_flags, blitDescriptions).constData(), |
|
1047 |
dev.drawing_flags, flagDescriptions(dev.drawing_flags, drawDescriptions).constData(), |
|
1048 |
(dev.video_memory >> 10)); |
|
1049 |
} |
|
1050 |
#endif |
|
1051 |
||
1052 |
static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value) |
|
1053 |
{ |
|
1054 |
Q_ASSERT(value); |
|
1055 |
QRegExp rx(QString::fromLatin1("%1=?(\\d+)").arg(variable)); |
|
1056 |
rx.setCaseSensitivity(Qt::CaseInsensitive); |
|
1057 |
if (arguments.indexOf(rx) != -1) { |
|
1058 |
*value = rx.cap(1).toInt(); |
|
1059 |
return true; |
|
1060 |
} |
|
1061 |
return false; |
|
1062 |
} |
|
1063 |
||
1064 |
static inline QColor colorFromName(const QString &name) |
|
1065 |
{ |
|
1066 |
QRegExp rx("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])"); |
|
1067 |
rx.setCaseSensitivity(Qt::CaseInsensitive); |
|
1068 |
if (rx.exactMatch(name)) { |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1069 |
Q_ASSERT(rx.captureCount() == 4); |
0 | 1070 |
int ints[4]; |
1071 |
int i; |
|
1072 |
for (i=0; i<4; ++i) { |
|
1073 |
bool ok; |
|
1074 |
ints[i] = rx.cap(i + 1).toUInt(&ok, 16); |
|
1075 |
if (!ok || ints[i] > 255) |
|
1076 |
break; |
|
1077 |
} |
|
1078 |
if (i == 4) |
|
1079 |
return QColor(ints[0], ints[1], ints[2], ints[3]); |
|
1080 |
} |
|
1081 |
return QColor(name); |
|
1082 |
} |
|
1083 |
||
1084 |
bool QDirectFBScreen::connect(const QString &displaySpec) |
|
1085 |
{ |
|
1086 |
DFBResult result = DFB_OK; |
|
1087 |
||
1088 |
{ // pass command line arguments to DirectFB |
|
1089 |
const QStringList args = QCoreApplication::arguments(); |
|
1090 |
int argc = args.size(); |
|
1091 |
char **argv = new char*[argc]; |
|
1092 |
||
1093 |
for (int i = 0; i < argc; ++i) |
|
1094 |
argv[i] = qstrdup(args.at(i).toLocal8Bit().constData()); |
|
1095 |
||
1096 |
result = DirectFBInit(&argc, &argv); |
|
1097 |
if (result != DFB_OK) { |
|
1098 |
DirectFBError("QDirectFBScreen: error initializing DirectFB", |
|
1099 |
result); |
|
1100 |
} |
|
1101 |
delete[] argv; |
|
1102 |
} |
|
1103 |
||
1104 |
const QStringList displayArgs = displaySpec.split(QLatin1Char(':'), |
|
1105 |
QString::SkipEmptyParts); |
|
1106 |
||
1107 |
d_ptr->setFlipFlags(displayArgs); |
|
1108 |
||
1109 |
result = DirectFBCreate(&d_ptr->dfb); |
|
1110 |
if (result != DFB_OK) { |
|
1111 |
DirectFBError("QDirectFBScreen: error creating DirectFB interface", |
|
1112 |
result); |
|
1113 |
return false; |
|
1114 |
} |
|
1115 |
||
1116 |
if (displayArgs.contains(QLatin1String("videoonly"), Qt::CaseInsensitive)) |
|
1117 |
d_ptr->directFBFlags |= VideoOnly; |
|
1118 |
||
1119 |
if (displayArgs.contains(QLatin1String("systemonly"), Qt::CaseInsensitive)) { |
|
1120 |
if (d_ptr->directFBFlags & VideoOnly) { |
|
1121 |
qWarning("QDirectFBScreen: error. videoonly and systemonly are mutually exclusive"); |
|
1122 |
} else { |
|
1123 |
d_ptr->directFBFlags |= SystemOnly; |
|
1124 |
} |
|
1125 |
} |
|
1126 |
||
1127 |
if (displayArgs.contains(QLatin1String("boundingrectflip"), Qt::CaseInsensitive)) { |
|
1128 |
d_ptr->directFBFlags |= BoundingRectFlip; |
|
1129 |
} |
|
1130 |
||
1131 |
#ifdef QT_DIRECTFB_IMAGECACHE |
|
1132 |
int imageCacheSize = 4 * 1024 * 1024; // 4 MB |
|
1133 |
setIntOption(displayArgs, QLatin1String("imagecachesize"), &imageCacheSize); |
|
1134 |
QDirectFBPaintEngine::initImageCache(imageCacheSize); |
|
1135 |
#endif |
|
1136 |
||
1137 |
#ifndef QT_NO_DIRECTFB_WM |
|
1138 |
if (displayArgs.contains(QLatin1String("fullscreen"))) |
|
1139 |
#endif |
|
1140 |
d_ptr->dfb->SetCooperativeLevel(d_ptr->dfb, DFSCL_FULLSCREEN); |
|
1141 |
||
1142 |
DFBSurfaceDescription description; |
|
1143 |
memset(&description, 0, sizeof(DFBSurfaceDescription)); |
|
1144 |
IDirectFBSurface *surface; |
|
1145 |
||
1146 |
#ifdef QT_NO_DIRECTFB_WM |
|
1147 |
description.flags = DSDESC_CAPS; |
|
1148 |
if (::setIntOption(displayArgs, QLatin1String("width"), &description.width)) |
|
1149 |
description.flags |= DSDESC_WIDTH; |
|
1150 |
if (::setIntOption(displayArgs, QLatin1String("height"), &description.height)) |
|
1151 |
description.flags |= DSDESC_HEIGHT; |
|
1152 |
||
1153 |
description.caps = DSCAPS_PRIMARY|DSCAPS_DOUBLE; |
|
1154 |
struct { |
|
1155 |
const char *name; |
|
1156 |
const DFBSurfaceCapabilities cap; |
|
1157 |
} const capabilities[] = { |
|
1158 |
{ "static_alloc", DSCAPS_STATIC_ALLOC }, |
|
1159 |
{ "triplebuffer", DSCAPS_TRIPLE }, |
|
1160 |
{ "interlaced", DSCAPS_INTERLACED }, |
|
1161 |
{ "separated", DSCAPS_SEPARATED }, |
|
1162 |
// { "depthbuffer", DSCAPS_DEPTH }, // only makes sense with TextureTriangles which are not supported |
|
1163 |
{ 0, DSCAPS_NONE } |
|
1164 |
}; |
|
1165 |
for (int i=0; capabilities[i].name; ++i) { |
|
1166 |
if (displayArgs.contains(QString::fromLatin1(capabilities[i].name), Qt::CaseInsensitive)) |
|
1167 |
description.caps |= capabilities[i].cap; |
|
1168 |
} |
|
1169 |
||
1170 |
if (displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive)) { |
|
1171 |
description.caps |= DSCAPS_PREMULTIPLIED; |
|
1172 |
} |
|
1173 |
||
1174 |
// We don't track the primary surface as it's released in disconnect |
|
1175 |
d_ptr->primarySurface = createDFBSurface(description, DontTrackSurface, &result); |
|
1176 |
if (!d_ptr->primarySurface) { |
|
1177 |
DirectFBError("QDirectFBScreen: error creating primary surface", |
|
1178 |
result); |
|
1179 |
return false; |
|
1180 |
} |
|
1181 |
||
1182 |
surface = d_ptr->primarySurface; |
|
1183 |
#else |
|
1184 |
description.flags = DSDESC_WIDTH|DSDESC_HEIGHT; |
|
1185 |
description.width = description.height = 1; |
|
1186 |
surface = createDFBSurface(description, DontTrackSurface, &result); |
|
1187 |
if (!surface) { |
|
1188 |
DirectFBError("QDirectFBScreen: error creating surface", result); |
|
1189 |
return false; |
|
1190 |
} |
|
1191 |
#endif |
|
1192 |
// Work out what format we're going to use for surfaces with an alpha channel |
|
1193 |
QImage::Format pixelFormat = QDirectFBScreen::getImageFormat(surface); |
|
1194 |
d_ptr->alphaPixmapFormat = pixelFormat; |
|
1195 |
||
1196 |
switch (pixelFormat) { |
|
1197 |
case QImage::Format_RGB666: |
|
1198 |
d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied; |
|
1199 |
break; |
|
1200 |
case QImage::Format_RGB444: |
|
1201 |
d_ptr->alphaPixmapFormat = QImage::Format_ARGB4444_Premultiplied; |
|
1202 |
break; |
|
1203 |
case QImage::Format_RGB32: |
|
1204 |
pixelFormat = d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied; |
|
1205 |
// ### Format_RGB32 doesn't work so well with Qt. Force ARGB32 for windows/pixmaps |
|
1206 |
break; |
|
1207 |
case QImage::Format_Indexed8: |
|
1208 |
qWarning("QDirectFBScreen::connect(). Qt/DirectFB does not work with the LUT8 pixelformat."); |
|
1209 |
return false; |
|
1210 |
case QImage::NImageFormats: |
|
1211 |
case QImage::Format_Invalid: |
|
1212 |
case QImage::Format_Mono: |
|
1213 |
case QImage::Format_MonoLSB: |
|
1214 |
case QImage::Format_RGB888: |
|
1215 |
case QImage::Format_RGB16: |
|
1216 |
case QImage::Format_RGB555: |
|
1217 |
d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied; |
|
1218 |
break; |
|
1219 |
case QImage::Format_ARGB32: |
|
1220 |
case QImage::Format_ARGB32_Premultiplied: |
|
1221 |
case QImage::Format_ARGB4444_Premultiplied: |
|
1222 |
case QImage::Format_ARGB8555_Premultiplied: |
|
1223 |
case QImage::Format_ARGB8565_Premultiplied: |
|
1224 |
case QImage::Format_ARGB6666_Premultiplied: |
|
1225 |
// works already |
|
1226 |
break; |
|
1227 |
} |
|
1228 |
setPixelFormat(pixelFormat); |
|
1229 |
QScreen::d = QDirectFBScreen::depth(pixelFormat); |
|
1230 |
data = 0; |
|
1231 |
lstep = 0; |
|
1232 |
size = 0; |
|
1233 |
||
1234 |
if (result != DFB_OK) { |
|
1235 |
DirectFBError("QDirectFBScreen::connect: " |
|
1236 |
"Unable to get screen!", result); |
|
1237 |
return false; |
|
1238 |
} |
|
1239 |
const QString qws_size = QString::fromLatin1(qgetenv("QWS_SIZE")); |
|
1240 |
if (!qws_size.isEmpty()) { |
|
1241 |
QRegExp rx(QLatin1String("(\\d+)x(\\d+)")); |
|
1242 |
if (!rx.exactMatch(qws_size)) { |
|
1243 |
qWarning("QDirectFBScreen::connect: Can't parse QWS_SIZE=\"%s\"", qPrintable(qws_size)); |
|
1244 |
} else { |
|
1245 |
int *ints[2] = { &w, &h }; |
|
1246 |
for (int i=0; i<2; ++i) { |
|
1247 |
*ints[i] = rx.cap(i + 1).toInt(); |
|
1248 |
if (*ints[i] <= 0) { |
|
1249 |
qWarning("QDirectFBScreen::connect: %s is not a positive integer", |
|
1250 |
qPrintable(rx.cap(i + 1))); |
|
1251 |
w = h = 0; |
|
1252 |
break; |
|
1253 |
} |
|
1254 |
} |
|
1255 |
} |
|
1256 |
} |
|
1257 |
||
1258 |
setIntOption(displayArgs, QLatin1String("width"), &w); |
|
1259 |
setIntOption(displayArgs, QLatin1String("height"), &h); |
|
1260 |
||
1261 |
#ifndef QT_NO_DIRECTFB_LAYER |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1262 |
int layerId = DLID_PRIMARY; |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1263 |
setIntOption(displayArgs, QLatin1String("layerid"), &layerId); |
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1264 |
|
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1265 |
result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, static_cast<DFBDisplayLayerID>(layerId), |
0 | 1266 |
&d_ptr->dfbLayer); |
1267 |
if (result != DFB_OK) { |
|
1268 |
DirectFBError("QDirectFBScreen::connect: " |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1269 |
"Unable to get display layer!", result); |
0 | 1270 |
return false; |
1271 |
} |
|
1272 |
result = d_ptr->dfbLayer->GetScreen(d_ptr->dfbLayer, &d_ptr->dfbScreen); |
|
1273 |
#else |
|
1274 |
result = d_ptr->dfb->GetScreen(d_ptr->dfb, 0, &d_ptr->dfbScreen); |
|
1275 |
#endif |
|
1276 |
||
1277 |
if (w <= 0 || h <= 0) { |
|
1278 |
#ifdef QT_NO_DIRECTFB_WM |
|
1279 |
result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h); |
|
1280 |
#elif (Q_DIRECTFB_VERSION >= 0x010000) |
|
1281 |
result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h); |
|
1282 |
#else |
|
1283 |
qWarning("QDirectFBScreen::connect: DirectFB versions prior to 1.0 do not offer a way\n" |
|
1284 |
"query the size of the primary surface in windowed mode. You have to specify\n" |
|
1285 |
"the size of the display using QWS_SIZE=[0-9]x[0-9] or\n" |
|
1286 |
"QWS_DISPLAY=directfb:width=[0-9]:height=[0-9]"); |
|
1287 |
return false; |
|
1288 |
#endif |
|
1289 |
if (result != DFB_OK) { |
|
1290 |
DirectFBError("QDirectFBScreen::connect: " |
|
1291 |
"Unable to get screen size!", result); |
|
1292 |
return false; |
|
1293 |
} |
|
1294 |
} |
|
1295 |
||
1296 |
||
1297 |
dw = w; |
|
1298 |
dh = h; |
|
1299 |
||
1300 |
Q_ASSERT(dw != 0 && dh != 0); |
|
1301 |
||
1302 |
physWidth = physHeight = -1; |
|
1303 |
setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth); |
|
1304 |
setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight); |
|
1305 |
const int dpi = 72; |
|
1306 |
if (physWidth < 0) |
|
1307 |
physWidth = qRound(dw * 25.4 / dpi); |
|
1308 |
if (physHeight < 0) |
|
1309 |
physHeight = qRound(dh * 25.4 / dpi); |
|
1310 |
||
1311 |
setGraphicsSystem(d_ptr); |
|
1312 |
||
1313 |
#if (Q_DIRECTFB_VERSION >= 0x000923) |
|
1314 |
if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive)) |
|
1315 |
printDirectFBInfo(d_ptr->dfb, surface); |
|
1316 |
#endif |
|
1317 |
#ifdef QT_DIRECTFB_WM |
|
1318 |
surface->Release(surface); |
|
1319 |
QColor backgroundColor; |
|
1320 |
#else |
|
1321 |
QColor &backgroundColor = d_ptr->backgroundColor; |
|
1322 |
#endif |
|
1323 |
||
1324 |
QRegExp backgroundColorRegExp(QLatin1String("bgcolor=(.+)")); |
|
1325 |
backgroundColorRegExp.setCaseSensitivity(Qt::CaseInsensitive); |
|
1326 |
if (displayArgs.indexOf(backgroundColorRegExp) != -1) { |
|
1327 |
backgroundColor = colorFromName(backgroundColorRegExp.cap(1)); |
|
1328 |
} |
|
1329 |
#ifdef QT_NO_DIRECTFB_WM |
|
1330 |
if (!backgroundColor.isValid()) |
|
1331 |
backgroundColor = Qt::green; |
|
1332 |
d_ptr->primarySurface->Clear(d_ptr->primarySurface, backgroundColor.red(), |
|
1333 |
backgroundColor.green(), backgroundColor.blue(), |
|
1334 |
backgroundColor.alpha()); |
|
1335 |
d_ptr->primarySurface->Flip(d_ptr->primarySurface, 0, d_ptr->flipFlags); |
|
1336 |
#else |
|
1337 |
if (backgroundColor.isValid()) { |
|
1338 |
DFBResult result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_ADMINISTRATIVE); |
|
1339 |
if (result != DFB_OK) { |
|
1340 |
DirectFBError("QDirectFBScreen::connect " |
|
1341 |
"Unable to set cooperative level", result); |
|
1342 |
} |
|
1343 |
result = d_ptr->dfbLayer->SetBackgroundColor(d_ptr->dfbLayer, backgroundColor.red(), backgroundColor.green(), |
|
1344 |
backgroundColor.blue(), backgroundColor.alpha()); |
|
1345 |
if (result != DFB_OK) { |
|
1346 |
DirectFBError("QDirectFBScreenCursor::connect: " |
|
1347 |
"Unable to set background color", result); |
|
1348 |
} |
|
1349 |
||
1350 |
result = d_ptr->dfbLayer->SetBackgroundMode(d_ptr->dfbLayer, DLBM_COLOR); |
|
1351 |
if (result != DFB_OK) { |
|
1352 |
DirectFBError("QDirectFBScreenCursor::connect: " |
|
1353 |
"Unable to set background mode", result); |
|
1354 |
} |
|
1355 |
||
1356 |
result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_SHARED); |
|
1357 |
if (result != DFB_OK) { |
|
1358 |
DirectFBError("QDirectFBScreen::connect " |
|
1359 |
"Unable to set cooperative level", result); |
|
1360 |
} |
|
1361 |
||
1362 |
} |
|
1363 |
#endif |
|
1364 |
||
1365 |
return true; |
|
1366 |
} |
|
1367 |
||
1368 |
void QDirectFBScreen::disconnect() |
|
1369 |
{ |
|
1370 |
#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE |
|
1371 |
if (d_ptr->imageProvider) |
|
1372 |
d_ptr->imageProvider->Release(d_ptr->imageProvider); |
|
1373 |
#endif |
|
1374 |
#ifdef QT_NO_DIRECTFB_WM |
|
1375 |
d_ptr->primarySurface->Release(d_ptr->primarySurface); |
|
1376 |
d_ptr->primarySurface = 0; |
|
1377 |
#endif |
|
1378 |
||
1379 |
foreach (IDirectFBSurface *surf, d_ptr->allocatedSurfaces) |
|
1380 |
surf->Release(surf); |
|
1381 |
d_ptr->allocatedSurfaces.clear(); |
|
1382 |
||
1383 |
#ifndef QT_NO_DIRECTFB_LAYER |
|
1384 |
d_ptr->dfbLayer->Release(d_ptr->dfbLayer); |
|
1385 |
d_ptr->dfbLayer = 0; |
|
1386 |
#endif |
|
1387 |
||
1388 |
d_ptr->dfbScreen->Release(d_ptr->dfbScreen); |
|
1389 |
d_ptr->dfbScreen = 0; |
|
1390 |
||
1391 |
d_ptr->dfb->Release(d_ptr->dfb); |
|
1392 |
d_ptr->dfb = 0; |
|
1393 |
} |
|
1394 |
||
1395 |
bool QDirectFBScreen::initDevice() |
|
1396 |
{ |
|
1397 |
#ifndef QT_NO_DIRECTFB_MOUSE |
|
1398 |
if (qgetenv("QWS_MOUSE_PROTO").isEmpty()) { |
|
1399 |
QWSServer::instance()->setDefaultMouse("None"); |
|
1400 |
d_ptr->mouse = new QDirectFBMouseHandler; |
|
1401 |
} |
|
1402 |
#endif |
|
1403 |
#ifndef QT_NO_DIRECTFB_KEYBOARD |
|
1404 |
if (qgetenv("QWS_KEYBOARD").isEmpty()) { |
|
1405 |
QWSServer::instance()->setDefaultKeyboard("None"); |
|
1406 |
d_ptr->keyboard = new QDirectFBKeyboardHandler(QString()); |
|
1407 |
} |
|
1408 |
#endif |
|
1409 |
||
1410 |
#ifdef QT_DIRECTFB_CURSOR |
|
1411 |
qt_screencursor = new QDirectFBScreenCursor; |
|
1412 |
#elif !defined QT_NO_QWS_CURSOR |
|
1413 |
QScreenCursor::initSoftwareCursor(); |
|
1414 |
#endif |
|
1415 |
return true; |
|
1416 |
} |
|
1417 |
||
1418 |
void QDirectFBScreen::shutdownDevice() |
|
1419 |
{ |
|
1420 |
#ifndef QT_NO_DIRECTFB_MOUSE |
|
1421 |
delete d_ptr->mouse; |
|
1422 |
d_ptr->mouse = 0; |
|
1423 |
#endif |
|
1424 |
#ifndef QT_NO_DIRECTFB_KEYBOARD |
|
1425 |
delete d_ptr->keyboard; |
|
1426 |
d_ptr->keyboard = 0; |
|
1427 |
#endif |
|
1428 |
||
1429 |
#ifndef QT_NO_QWS_CURSOR |
|
1430 |
delete qt_screencursor; |
|
1431 |
qt_screencursor = 0; |
|
1432 |
#endif |
|
1433 |
} |
|
1434 |
||
1435 |
void QDirectFBScreen::setMode(int width, int height, int depth) |
|
1436 |
{ |
|
1437 |
d_ptr->dfb->SetVideoMode(d_ptr->dfb, width, height, depth); |
|
1438 |
} |
|
1439 |
||
1440 |
void QDirectFBScreen::blank(bool on) |
|
1441 |
{ |
|
1442 |
d_ptr->dfbScreen->SetPowerMode(d_ptr->dfbScreen, |
|
1443 |
(on ? DSPM_ON : DSPM_SUSPEND)); |
|
1444 |
} |
|
1445 |
||
1446 |
QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const |
|
1447 |
{ |
|
1448 |
#ifdef QT_NO_DIRECTFB_WM |
|
1449 |
if (QApplication::type() == QApplication::GuiServer) { |
|
1450 |
return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget); |
|
1451 |
} else { |
|
1452 |
return QScreen::createSurface(widget); |
|
1453 |
} |
|
1454 |
#else |
|
1455 |
return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget); |
|
1456 |
#endif |
|
1457 |
} |
|
1458 |
||
1459 |
QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const |
|
1460 |
{ |
|
1461 |
if (key == QLatin1String("directfb")) { |
|
1462 |
return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this)); |
|
1463 |
} |
|
1464 |
return QScreen::createSurface(key); |
|
1465 |
} |
|
1466 |
||
1467 |
#if defined QT_NO_DIRECTFB_WM |
|
1468 |
struct PaintCommand { |
|
1469 |
PaintCommand() : dfbSurface(0), windowOpacity(255), blittingFlags(DSBLIT_NOFX) {} |
|
1470 |
IDirectFBSurface *dfbSurface; |
|
1471 |
QImage image; |
|
1472 |
QPoint windowPosition; |
|
1473 |
QRegion source; |
|
1474 |
quint8 windowOpacity; |
|
1475 |
DFBSurfaceBlittingFlags blittingFlags; |
|
1476 |
}; |
|
1477 |
||
1478 |
static inline void initParameters(DFBRectangle &source, const QRect &sourceGlobal, const QPoint &pos) |
|
1479 |
{ |
|
1480 |
source.x = sourceGlobal.x() - pos.x(); |
|
1481 |
source.y = sourceGlobal.y() - pos.y(); |
|
1482 |
source.w = sourceGlobal.width(); |
|
1483 |
source.h = sourceGlobal.height(); |
|
1484 |
} |
|
1485 |
#endif |
|
1486 |
||
1487 |
void QDirectFBScreen::exposeRegion(QRegion r, int) |
|
1488 |
{ |
|
1489 |
Q_UNUSED(r); |
|
1490 |
#if defined QT_NO_DIRECTFB_WM |
|
1491 |
||
1492 |
r &= region(); |
|
1493 |
if (r.isEmpty()) { |
|
1494 |
return; |
|
1495 |
} |
|
1496 |
r = r.boundingRect(); |
|
1497 |
||
1498 |
IDirectFBSurface *primary = d_ptr->primarySurface; |
|
1499 |
const QList<QWSWindow*> windows = QWSServer::instance()->clientWindows(); |
|
1500 |
QVarLengthArray<PaintCommand, 4> commands(windows.size()); |
|
1501 |
QRegion region = r; |
|
1502 |
int idx = 0; |
|
1503 |
for (int i=0; i<windows.size(); ++i) { |
|
1504 |
QWSWindowSurface *surface = windows.at(i)->windowSurface(); |
|
1505 |
if (!surface) |
|
1506 |
continue; |
|
1507 |
||
1508 |
const QRect windowGeometry = surface->geometry(); |
|
1509 |
const QRegion intersection = region & windowGeometry; |
|
1510 |
if (intersection.isEmpty()) { |
|
1511 |
continue; |
|
1512 |
} |
|
1513 |
||
1514 |
PaintCommand &cmd = commands[idx]; |
|
1515 |
||
1516 |
if (surface->key() == QLatin1String("directfb")) { |
|
1517 |
const QDirectFBWindowSurface *ws = static_cast<QDirectFBWindowSurface*>(surface); |
|
1518 |
cmd.dfbSurface = ws->directFBSurface(); |
|
1519 |
||
1520 |
if (!cmd.dfbSurface) { |
|
1521 |
continue; |
|
1522 |
} |
|
1523 |
} else { |
|
1524 |
cmd.image = surface->image(); |
|
1525 |
if (cmd.image.isNull()) { |
|
1526 |
continue; |
|
1527 |
} |
|
1528 |
} |
|
1529 |
++idx; |
|
1530 |
||
1531 |
cmd.windowPosition = windowGeometry.topLeft(); |
|
1532 |
cmd.source = intersection; |
|
1533 |
if (windows.at(i)->isOpaque()) { |
|
1534 |
region -= intersection; |
|
1535 |
if (region.isEmpty()) |
|
1536 |
break; |
|
1537 |
} else { |
|
1538 |
cmd.windowOpacity = windows.at(i)->opacity(); |
|
1539 |
cmd.blittingFlags = cmd.windowOpacity == 255 |
|
1540 |
? DSBLIT_BLEND_ALPHACHANNEL |
|
1541 |
: (DSBLIT_BLEND_ALPHACHANNEL|DSBLIT_BLEND_COLORALPHA); |
|
1542 |
} |
|
1543 |
} |
|
1544 |
if (!region.isEmpty()) { |
|
1545 |
solidFill(d_ptr->backgroundColor, region); |
|
1546 |
} |
|
1547 |
||
1548 |
while (idx > 0) { |
|
1549 |
const PaintCommand &cmd = commands[--idx]; |
|
1550 |
Q_ASSERT(cmd.dfbSurface || !cmd.image.isNull()); |
|
1551 |
IDirectFBSurface *surface; |
|
1552 |
if (cmd.dfbSurface) { |
|
1553 |
surface = cmd.dfbSurface; |
|
1554 |
} else { |
|
1555 |
Q_ASSERT(!cmd.image.isNull()); |
|
1556 |
DFBResult result; |
|
1557 |
surface = createDFBSurface(cmd.image, cmd.image.format(), DontTrackSurface, &result); |
|
1558 |
Q_ASSERT((result != DFB_OK) == !surface); |
|
1559 |
if (result != DFB_OK) { |
|
1560 |
DirectFBError("QDirectFBScreen::exposeRegion: Can't create surface from image", result); |
|
1561 |
continue; |
|
1562 |
} |
|
1563 |
} |
|
1564 |
||
1565 |
primary->SetBlittingFlags(primary, cmd.blittingFlags); |
|
1566 |
if (cmd.blittingFlags & DSBLIT_BLEND_COLORALPHA) { |
|
1567 |
primary->SetColor(primary, 0xff, 0xff, 0xff, cmd.windowOpacity); |
|
1568 |
} |
|
1569 |
const QRegion ®ion = cmd.source; |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1570 |
const int rectCount = region.rectCount(); |
0 | 1571 |
DFBRectangle source; |
1572 |
if (rectCount == 1) { |
|
1573 |
::initParameters(source, region.boundingRect(), cmd.windowPosition); |
|
1574 |
primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y); |
|
1575 |
} else { |
|
1576 |
const QVector<QRect> rects = region.rects(); |
|
1577 |
for (int i=0; i<rectCount; ++i) { |
|
1578 |
::initParameters(source, rects.at(i), cmd.windowPosition); |
|
1579 |
primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y); |
|
1580 |
} |
|
1581 |
} |
|
1582 |
if (surface != cmd.dfbSurface) { |
|
1583 |
surface->Release(surface); |
|
1584 |
} |
|
1585 |
} |
|
1586 |
||
1587 |
primary->SetColor(primary, 0xff, 0xff, 0xff, 0xff); |
|
1588 |
||
1589 |
#if defined QT_NO_DIRECTFB_CURSOR and !defined QT_NO_QWS_CURSOR |
|
1590 |
if (QScreenCursor *cursor = QScreenCursor::instance()) { |
|
1591 |
const QRect cursorRectangle = cursor->boundingRect(); |
|
1592 |
if (cursor->isVisible() && !cursor->isAccelerated() && r.intersects(cursorRectangle)) { |
|
1593 |
const QImage image = cursor->image(); |
|
1594 |
if (image.cacheKey() != d_ptr->cursorImageKey) { |
|
1595 |
if (d_ptr->cursorSurface) { |
|
1596 |
releaseDFBSurface(d_ptr->cursorSurface); |
|
1597 |
} |
|
1598 |
d_ptr->cursorSurface = createDFBSurface(image, image.format(), QDirectFBScreen::TrackSurface); |
|
1599 |
d_ptr->cursorImageKey = image.cacheKey(); |
|
1600 |
} |
|
1601 |
||
1602 |
Q_ASSERT(d_ptr->cursorSurface); |
|
1603 |
primary->SetBlittingFlags(primary, DSBLIT_BLEND_ALPHACHANNEL); |
|
1604 |
primary->Blit(primary, d_ptr->cursorSurface, 0, cursorRectangle.x(), cursorRectangle.y()); |
|
1605 |
} |
|
1606 |
} |
|
1607 |
#endif |
|
1608 |
flipSurface(primary, d_ptr->flipFlags, r, QPoint()); |
|
1609 |
primary->SetBlittingFlags(primary, DSBLIT_NOFX); |
|
1610 |
#endif |
|
1611 |
} |
|
1612 |
||
1613 |
void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) |
|
1614 |
{ |
|
1615 |
#ifdef QT_DIRECTFB_WM |
|
1616 |
Q_UNUSED(color); |
|
1617 |
Q_UNUSED(region); |
|
1618 |
#else |
|
1619 |
if (region.isEmpty()) |
|
1620 |
return; |
|
1621 |
||
1622 |
d_ptr->primarySurface->SetColor(d_ptr->primarySurface, |
|
1623 |
color.red(), color.green(), color.blue(), |
|
1624 |
color.alpha()); |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1625 |
const int n = region.rectCount(); |
0 | 1626 |
if (n == 1) { |
1627 |
const QRect r = region.boundingRect(); |
|
1628 |
d_ptr->primarySurface->FillRectangle(d_ptr->primarySurface, r.x(), r.y(), r.width(), r.height()); |
|
1629 |
} else { |
|
1630 |
const QVector<QRect> rects = region.rects(); |
|
1631 |
QVarLengthArray<DFBRectangle, 32> rectArray(n); |
|
1632 |
for (int i=0; i<n; ++i) { |
|
1633 |
const QRect &r = rects.at(i); |
|
1634 |
rectArray[i].x = r.x(); |
|
1635 |
rectArray[i].y = r.y(); |
|
1636 |
rectArray[i].w = r.width(); |
|
1637 |
rectArray[i].h = r.height(); |
|
1638 |
} |
|
1639 |
d_ptr->primarySurface->FillRectangles(d_ptr->primarySurface, rectArray.constData(), n); |
|
1640 |
} |
|
1641 |
#endif |
|
1642 |
} |
|
1643 |
||
1644 |
QImage::Format QDirectFBScreen::alphaPixmapFormat() const |
|
1645 |
{ |
|
1646 |
return d_ptr->alphaPixmapFormat; |
|
1647 |
} |
|
1648 |
||
1649 |
bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, |
|
1650 |
QImage::Format format) |
|
1651 |
{ |
|
1652 |
const DFBSurfacePixelFormat pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); |
|
1653 |
if (pixelformat == DSPF_UNKNOWN) |
|
1654 |
return false; |
|
1655 |
description->flags |= DSDESC_PIXELFORMAT; |
|
1656 |
description->pixelformat = pixelformat; |
|
1657 |
if (QDirectFBScreen::isPremultiplied(format)) { |
|
1658 |
if (!(description->flags & DSDESC_CAPS)) { |
|
1659 |
description->caps = DSCAPS_PREMULTIPLIED; |
|
1660 |
description->flags |= DSDESC_CAPS; |
|
1661 |
} else { |
|
1662 |
description->caps |= DSCAPS_PREMULTIPLIED; |
|
1663 |
} |
|
1664 |
} |
|
1665 |
return true; |
|
1666 |
} |
|
1667 |
||
1668 |
uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl) |
|
1669 |
{ |
|
1670 |
void *mem; |
|
1671 |
const DFBResult result = surface->Lock(surface, flags, &mem, bpl); |
|
1672 |
if (result != DFB_OK) { |
|
1673 |
DirectFBError("QDirectFBScreen::lockSurface()", result); |
|
1674 |
} |
|
1675 |
||
1676 |
return reinterpret_cast<uchar*>(mem); |
|
1677 |
} |
|
1678 |
||
1679 |
||
1680 |
void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags, |
|
1681 |
const QRegion ®ion, const QPoint &offset) |
|
1682 |
{ |
|
1683 |
if (!(flipFlags & DSFLIP_BLIT)) { |
|
1684 |
surface->Flip(surface, 0, flipFlags); |
|
1685 |
} else { |
|
3
41300fa6a67c
Revision: 201003
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
1686 |
if (!(d_ptr->directFBFlags & BoundingRectFlip) && region.rectCount() > 1) { |
0 | 1687 |
const QVector<QRect> rects = region.rects(); |
1688 |
const DFBSurfaceFlipFlags nonWaitFlags = flipFlags & ~DSFLIP_WAIT; |
|
1689 |
for (int i=0; i<rects.size(); ++i) { |
|
1690 |
const QRect &r = rects.at(i); |
|
1691 |
const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), |
|
1692 |
r.right() + offset.x(), |
|
1693 |
r.bottom() + offset.y() }; |
|
1694 |
surface->Flip(surface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags); |
|
1695 |
} |
|
1696 |
} else { |
|
1697 |
const QRect r = region.boundingRect(); |
|
1698 |
const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), |
|
1699 |
r.right() + offset.x(), |
|
1700 |
r.bottom() + offset.y() }; |
|
1701 |
surface->Flip(surface, &dfbReg, flipFlags); |
|
1702 |
} |
|
1703 |
} |
|
1704 |
} |
|
1705 |
||
1706 |
#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE |
|
1707 |
void QDirectFBScreen::setDirectFBImageProvider(IDirectFBImageProvider *provider) |
|
1708 |
{ |
|
1709 |
Q_ASSERT(provider); |
|
1710 |
if (d_ptr->imageProvider) |
|
1711 |
d_ptr->imageProvider->Release(d_ptr->imageProvider); |
|
1712 |
d_ptr->imageProvider = provider; |
|
1713 |
} |
|
1714 |
#endif |
|
1715 |
||
1716 |
void QDirectFBScreen::waitIdle() |
|
1717 |
{ |
|
1718 |
d_ptr->dfb->WaitIdle(d_ptr->dfb); |
|
1719 |
} |
|
1720 |
||
1721 |
#ifdef QT_DIRECTFB_WM |
|
1722 |
IDirectFBWindow *QDirectFBScreen::windowForWidget(const QWidget *widget) const |
|
1723 |
{ |
|
1724 |
if (widget) { |
|
1725 |
const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface()); |
|
1726 |
if (surface && surface->key() == QLatin1String("directfb")) { |
|
1727 |
return static_cast<const QDirectFBWindowSurface*>(surface)->directFBWindow(); |
|
1728 |
} |
|
1729 |
} |
|
1730 |
return 0; |
|
1731 |
} |
|
1732 |
#endif |
|
1733 |
||
1734 |
IDirectFBSurface * QDirectFBScreen::surfaceForWidget(const QWidget *widget, QRect *rect) const |
|
1735 |
{ |
|
1736 |
Q_ASSERT(widget); |
|
1737 |
if (!widget->isVisible() || widget->size().isNull()) |
|
1738 |
return 0; |
|
1739 |
||
1740 |
const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface()); |
|
1741 |
if (surface && surface->key() == QLatin1String("directfb")) { |
|
1742 |
return static_cast<const QDirectFBWindowSurface*>(surface)->surfaceForWidget(widget, rect); |
|
1743 |
} |
|
1744 |
return 0; |
|
1745 |
} |
|
1746 |
||
1747 |
#ifdef QT_DIRECTFB_SUBSURFACE |
|
1748 |
IDirectFBSurface *QDirectFBScreen::subSurfaceForWidget(const QWidget *widget, const QRect &area) const |
|
1749 |
{ |
|
1750 |
Q_ASSERT(widget); |
|
1751 |
QRect rect; |
|
1752 |
IDirectFBSurface *surface = surfaceForWidget(widget, &rect); |
|
1753 |
IDirectFBSurface *subSurface = 0; |
|
1754 |
if (surface) { |
|
1755 |
if (!area.isNull()) |
|
1756 |
rect &= area.translated(widget->mapTo(widget->window(), QPoint(0, 0))); |
|
1757 |
if (!rect.isNull()) { |
|
1758 |
const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() }; |
|
1759 |
const DFBResult result = surface->GetSubSurface(surface, &subRect, &subSurface); |
|
1760 |
if (result != DFB_OK) { |
|
1761 |
DirectFBError("QDirectFBScreen::subSurface(): Can't get sub surface", result); |
|
1762 |
} |
|
1763 |
} |
|
1764 |
} |
|
1765 |
return subSurface; |
|
1766 |
} |
|
1767 |
#endif |
|
1768 |
||
1769 |
#ifndef QT_DIRECTFB_PLUGIN |
|
1770 |
Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_widget(const QWidget *widget, QRect *rect) |
|
1771 |
{ |
|
1772 |
return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->surfaceForWidget(widget, rect) : 0; |
|
1773 |
} |
|
1774 |
#ifdef QT_DIRECTFB_SUBSURFACE |
|
1775 |
Q_GUI_EXPORT IDirectFBSurface *qt_directfb_subsurface_for_widget(const QWidget *widget, const QRect &area) |
|
1776 |
{ |
|
1777 |
return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->subSurfaceForWidget(widget, area) : 0; |
|
1778 |
} |
|
1779 |
#endif |
|
1780 |
#ifdef QT_DIRECTFB_WM |
|
1781 |
Q_GUI_EXPORT IDirectFBWindow *qt_directfb_window_for_widget(const QWidget *widget) |
|
1782 |
{ |
|
1783 |
return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->windowForWidget(widget) : 0; |
|
1784 |
} |
|
1785 |
||
1786 |
#endif |
|
1787 |
#endif |
|
1788 |
||
1789 |
QT_END_NAMESPACE |
|
1790 |
||
1791 |
#include "qdirectfbscreen.moc" |
|
1792 |
#endif // QT_NO_QWS_DIRECTFB |
|
1793 |