1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation (qt-info@nokia.com)
|
---|
6 | **
|
---|
7 | ** This file is part of the 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 qt-info@nokia.com.
|
---|
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
|
---|
134 | connect(QWSServer::instance(), SIGNAL(windowEvent(QWSWindow*,QWSServer::WindowEvent)),
|
---|
135 | this, SLOT(onWindowEvent(QWSWindow*,QWSServer::WindowEvent)));
|
---|
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)) {
|
---|
217 | memcpy(mem, image.bits(), image.byteCount());
|
---|
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
|
---|
228 | if (image.colorCount() != 0 && surface)
|
---|
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 |
|
---|
500 | const int numColors = image.colorCount();
|
---|
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|DSFLIP_ONSYNC;
|
---|
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[] = {
|
---|
961 | { "DFXL_NONE", DFXL_NONE },
|
---|
962 | { "DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE },
|
---|
963 | { "DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE },
|
---|
964 | { "DFXL_DRAWLINE", DFXL_DRAWLINE },
|
---|
965 | { "DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE },
|
---|
966 | { "DFXL_BLIT", DFXL_BLIT },
|
---|
967 | { "DFXL_STRETCHBLIT", DFXL_STRETCHBLIT },
|
---|
968 | { "DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES },
|
---|
969 | { "DFXL_DRAWSTRING", DFXL_DRAWSTRING },
|
---|
970 | { 0, 0 }
|
---|
971 | };
|
---|
972 |
|
---|
973 | static const FlagDescription blitDescriptions[] = {
|
---|
974 | { "DSBLIT_NOFX", DSBLIT_NOFX },
|
---|
975 | { "DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL },
|
---|
976 | { "DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA },
|
---|
977 | { "DSBLIT_COLORIZE", DSBLIT_COLORIZE },
|
---|
978 | { "DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY },
|
---|
979 | { "DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY },
|
---|
980 | { "DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY },
|
---|
981 | { "DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY },
|
---|
982 | { "DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY },
|
---|
983 | { "DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE },
|
---|
984 | #if (Q_DIRECTFB_VERSION >= 0x000923)
|
---|
985 | { "DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR },
|
---|
986 | { "DSBLIT_XOR", DSBLIT_XOR },
|
---|
987 | #endif
|
---|
988 | #if (Q_DIRECTFB_VERSION >= 0x010000)
|
---|
989 | { "DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION },
|
---|
990 | #endif
|
---|
991 | { 0, 0 }
|
---|
992 | };
|
---|
993 |
|
---|
994 | static const FlagDescription drawDescriptions[] = {
|
---|
995 | { "DSDRAW_NOFX", DSDRAW_NOFX },
|
---|
996 | { "DSDRAW_BLEND", DSDRAW_BLEND },
|
---|
997 | { "DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY },
|
---|
998 | { "DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY },
|
---|
999 | { "DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY },
|
---|
1000 | { "DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY },
|
---|
1001 | { "DSDRAW_XOR", DSDRAW_XOR },
|
---|
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(QLatin1String("#([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)) {
|
---|
1069 | Q_ASSERT(rx.captureCount() == 4);
|
---|
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 | } else if (displayArgs.contains(QLatin1String("nopartialflip"), Qt::CaseInsensitive)) {
|
---|
1130 | d_ptr->directFBFlags |= NoPartialFlip;
|
---|
1131 | }
|
---|
1132 |
|
---|
1133 | #ifdef QT_DIRECTFB_IMAGECACHE
|
---|
1134 | int imageCacheSize = 4 * 1024 * 1024; // 4 MB
|
---|
1135 | setIntOption(displayArgs, QLatin1String("imagecachesize"), &imageCacheSize);
|
---|
1136 | QDirectFBPaintEngine::initImageCache(imageCacheSize);
|
---|
1137 | #endif
|
---|
1138 |
|
---|
1139 | #ifndef QT_NO_DIRECTFB_WM
|
---|
1140 | if (displayArgs.contains(QLatin1String("fullscreen")))
|
---|
1141 | #endif
|
---|
1142 | d_ptr->dfb->SetCooperativeLevel(d_ptr->dfb, DFSCL_FULLSCREEN);
|
---|
1143 |
|
---|
1144 | const bool forcePremultiplied = displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive);
|
---|
1145 |
|
---|
1146 | DFBSurfaceDescription description;
|
---|
1147 | memset(&description, 0, sizeof(DFBSurfaceDescription));
|
---|
1148 | IDirectFBSurface *surface;
|
---|
1149 |
|
---|
1150 | #ifdef QT_NO_DIRECTFB_WM
|
---|
1151 | description.flags = DSDESC_CAPS;
|
---|
1152 | if (::setIntOption(displayArgs, QLatin1String("width"), &description.width))
|
---|
1153 | description.flags |= DSDESC_WIDTH;
|
---|
1154 | if (::setIntOption(displayArgs, QLatin1String("height"), &description.height))
|
---|
1155 | description.flags |= DSDESC_HEIGHT;
|
---|
1156 |
|
---|
1157 | description.caps = DSCAPS_PRIMARY|DSCAPS_DOUBLE;
|
---|
1158 | struct {
|
---|
1159 | const char *name;
|
---|
1160 | const DFBSurfaceCapabilities cap;
|
---|
1161 | } const capabilities[] = {
|
---|
1162 | { "static_alloc", DSCAPS_STATIC_ALLOC },
|
---|
1163 | { "triplebuffer", DSCAPS_TRIPLE },
|
---|
1164 | { "interlaced", DSCAPS_INTERLACED },
|
---|
1165 | { "separated", DSCAPS_SEPARATED },
|
---|
1166 | // { "depthbuffer", DSCAPS_DEPTH }, // only makes sense with TextureTriangles which are not supported
|
---|
1167 | { 0, DSCAPS_NONE }
|
---|
1168 | };
|
---|
1169 | for (int i=0; capabilities[i].name; ++i) {
|
---|
1170 | if (displayArgs.contains(QString::fromLatin1(capabilities[i].name), Qt::CaseInsensitive))
|
---|
1171 | description.caps |= capabilities[i].cap;
|
---|
1172 | }
|
---|
1173 |
|
---|
1174 | if (forcePremultiplied) {
|
---|
1175 | description.caps |= DSCAPS_PREMULTIPLIED;
|
---|
1176 | }
|
---|
1177 |
|
---|
1178 | // We don't track the primary surface as it's released in disconnect
|
---|
1179 | d_ptr->primarySurface = createDFBSurface(description, DontTrackSurface, &result);
|
---|
1180 | if (!d_ptr->primarySurface) {
|
---|
1181 | DirectFBError("QDirectFBScreen: error creating primary surface",
|
---|
1182 | result);
|
---|
1183 | return false;
|
---|
1184 | }
|
---|
1185 |
|
---|
1186 | surface = d_ptr->primarySurface;
|
---|
1187 | #else
|
---|
1188 | description.flags = DSDESC_WIDTH|DSDESC_HEIGHT;
|
---|
1189 | description.width = description.height = 1;
|
---|
1190 | surface = createDFBSurface(description, DontTrackSurface, &result);
|
---|
1191 | if (!surface) {
|
---|
1192 | DirectFBError("QDirectFBScreen: error creating surface", result);
|
---|
1193 | return false;
|
---|
1194 | }
|
---|
1195 | #endif
|
---|
1196 | // Work out what format we're going to use for surfaces with an alpha channel
|
---|
1197 | QImage::Format pixelFormat = QDirectFBScreen::getImageFormat(surface);
|
---|
1198 | d_ptr->alphaPixmapFormat = pixelFormat;
|
---|
1199 |
|
---|
1200 | switch (pixelFormat) {
|
---|
1201 | case QImage::Format_RGB666:
|
---|
1202 | d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied;
|
---|
1203 | break;
|
---|
1204 | case QImage::Format_RGB444:
|
---|
1205 | d_ptr->alphaPixmapFormat = QImage::Format_ARGB4444_Premultiplied;
|
---|
1206 | break;
|
---|
1207 | case QImage::Format_RGB32:
|
---|
1208 | pixelFormat = d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
|
---|
1209 | // ### Format_RGB32 doesn't work so well with Qt. Force ARGB32 for windows/pixmaps
|
---|
1210 | break;
|
---|
1211 | case QImage::Format_Indexed8:
|
---|
1212 | qWarning("QDirectFBScreen::connect(). Qt/DirectFB does not work with the LUT8 pixelformat.");
|
---|
1213 | return false;
|
---|
1214 | case QImage::NImageFormats:
|
---|
1215 | case QImage::Format_Invalid:
|
---|
1216 | case QImage::Format_Mono:
|
---|
1217 | case QImage::Format_MonoLSB:
|
---|
1218 | case QImage::Format_RGB888:
|
---|
1219 | case QImage::Format_RGB16:
|
---|
1220 | case QImage::Format_RGB555:
|
---|
1221 | d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
|
---|
1222 | break;
|
---|
1223 | case QImage::Format_ARGB32:
|
---|
1224 | if (forcePremultiplied)
|
---|
1225 | d_ptr->alphaPixmapFormat = pixelFormat = QImage::Format_ARGB32_Premultiplied;
|
---|
1226 | case QImage::Format_ARGB32_Premultiplied:
|
---|
1227 | case QImage::Format_ARGB4444_Premultiplied:
|
---|
1228 | case QImage::Format_ARGB8555_Premultiplied:
|
---|
1229 | case QImage::Format_ARGB8565_Premultiplied:
|
---|
1230 | case QImage::Format_ARGB6666_Premultiplied:
|
---|
1231 | // works already
|
---|
1232 | break;
|
---|
1233 | }
|
---|
1234 | setPixelFormat(pixelFormat);
|
---|
1235 | QScreen::d = QDirectFBScreen::depth(pixelFormat);
|
---|
1236 | data = 0;
|
---|
1237 | lstep = 0;
|
---|
1238 | size = 0;
|
---|
1239 |
|
---|
1240 | if (result != DFB_OK) {
|
---|
1241 | DirectFBError("QDirectFBScreen::connect: "
|
---|
1242 | "Unable to get screen!", result);
|
---|
1243 | return false;
|
---|
1244 | }
|
---|
1245 | const QString qws_size = QString::fromLatin1(qgetenv("QWS_SIZE"));
|
---|
1246 | if (!qws_size.isEmpty()) {
|
---|
1247 | QRegExp rx(QLatin1String("(\\d+)x(\\d+)"));
|
---|
1248 | if (!rx.exactMatch(qws_size)) {
|
---|
1249 | qWarning("QDirectFBScreen::connect: Can't parse QWS_SIZE=\"%s\"", qPrintable(qws_size));
|
---|
1250 | } else {
|
---|
1251 | int *ints[2] = { &w, &h };
|
---|
1252 | for (int i=0; i<2; ++i) {
|
---|
1253 | *ints[i] = rx.cap(i + 1).toInt();
|
---|
1254 | if (*ints[i] <= 0) {
|
---|
1255 | qWarning("QDirectFBScreen::connect: %s is not a positive integer",
|
---|
1256 | qPrintable(rx.cap(i + 1)));
|
---|
1257 | w = h = 0;
|
---|
1258 | break;
|
---|
1259 | }
|
---|
1260 | }
|
---|
1261 | }
|
---|
1262 | }
|
---|
1263 |
|
---|
1264 | setIntOption(displayArgs, QLatin1String("width"), &w);
|
---|
1265 | setIntOption(displayArgs, QLatin1String("height"), &h);
|
---|
1266 |
|
---|
1267 | #ifndef QT_NO_DIRECTFB_LAYER
|
---|
1268 | int layerId = DLID_PRIMARY;
|
---|
1269 | setIntOption(displayArgs, QLatin1String("layerid"), &layerId);
|
---|
1270 |
|
---|
1271 | result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, static_cast<DFBDisplayLayerID>(layerId),
|
---|
1272 | &d_ptr->dfbLayer);
|
---|
1273 | if (result != DFB_OK) {
|
---|
1274 | DirectFBError("QDirectFBScreen::connect: "
|
---|
1275 | "Unable to get display layer!", result);
|
---|
1276 | return false;
|
---|
1277 | }
|
---|
1278 | result = d_ptr->dfbLayer->GetScreen(d_ptr->dfbLayer, &d_ptr->dfbScreen);
|
---|
1279 | #else
|
---|
1280 | result = d_ptr->dfb->GetScreen(d_ptr->dfb, 0, &d_ptr->dfbScreen);
|
---|
1281 | #endif
|
---|
1282 |
|
---|
1283 | if (w <= 0 || h <= 0) {
|
---|
1284 | #ifdef QT_NO_DIRECTFB_WM
|
---|
1285 | result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h);
|
---|
1286 | #elif (Q_DIRECTFB_VERSION >= 0x010000)
|
---|
1287 | IDirectFBSurface *layerSurface;
|
---|
1288 | if (d_ptr->dfbLayer->GetSurface(d_ptr->dfbLayer, &layerSurface) != DFB_OK) {
|
---|
1289 | result = layerSurface->GetSize(layerSurface, &w, &h);
|
---|
1290 | layerSurface->Release(layerSurface);
|
---|
1291 | }
|
---|
1292 | if (w <= 0 || h <= 0) {
|
---|
1293 | result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h);
|
---|
1294 | }
|
---|
1295 | #else
|
---|
1296 | qWarning("QDirectFBScreen::connect: DirectFB versions prior to 1.0 do not offer a way\n"
|
---|
1297 | "query the size of the primary surface in windowed mode. You have to specify\n"
|
---|
1298 | "the size of the display using QWS_SIZE=[0-9]x[0-9] or\n"
|
---|
1299 | "QWS_DISPLAY=directfb:width=[0-9]:height=[0-9]");
|
---|
1300 | return false;
|
---|
1301 | #endif
|
---|
1302 | if (result != DFB_OK) {
|
---|
1303 | DirectFBError("QDirectFBScreen::connect: "
|
---|
1304 | "Unable to get screen size!", result);
|
---|
1305 | return false;
|
---|
1306 | }
|
---|
1307 | }
|
---|
1308 |
|
---|
1309 |
|
---|
1310 | dw = w;
|
---|
1311 | dh = h;
|
---|
1312 |
|
---|
1313 | Q_ASSERT(dw != 0 && dh != 0);
|
---|
1314 |
|
---|
1315 | physWidth = physHeight = -1;
|
---|
1316 | setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth);
|
---|
1317 | setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight);
|
---|
1318 | const int dpi = 72;
|
---|
1319 | if (physWidth < 0)
|
---|
1320 | physWidth = qRound(dw * 25.4 / dpi);
|
---|
1321 | if (physHeight < 0)
|
---|
1322 | physHeight = qRound(dh * 25.4 / dpi);
|
---|
1323 |
|
---|
1324 | setGraphicsSystem(d_ptr);
|
---|
1325 |
|
---|
1326 | #if (Q_DIRECTFB_VERSION >= 0x000923)
|
---|
1327 | if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive))
|
---|
1328 | printDirectFBInfo(d_ptr->dfb, surface);
|
---|
1329 | #endif
|
---|
1330 | #ifdef QT_DIRECTFB_WM
|
---|
1331 | surface->Release(surface);
|
---|
1332 | QColor backgroundColor;
|
---|
1333 | #else
|
---|
1334 | QColor &backgroundColor = d_ptr->backgroundColor;
|
---|
1335 | #endif
|
---|
1336 |
|
---|
1337 | QRegExp backgroundColorRegExp(QLatin1String("bgcolor=(.+)"));
|
---|
1338 | backgroundColorRegExp.setCaseSensitivity(Qt::CaseInsensitive);
|
---|
1339 | if (displayArgs.indexOf(backgroundColorRegExp) != -1) {
|
---|
1340 | backgroundColor = colorFromName(backgroundColorRegExp.cap(1));
|
---|
1341 | }
|
---|
1342 | #ifdef QT_NO_DIRECTFB_WM
|
---|
1343 | if (!backgroundColor.isValid())
|
---|
1344 | backgroundColor = Qt::green;
|
---|
1345 | d_ptr->primarySurface->Clear(d_ptr->primarySurface, backgroundColor.red(),
|
---|
1346 | backgroundColor.green(), backgroundColor.blue(),
|
---|
1347 | backgroundColor.alpha());
|
---|
1348 | d_ptr->primarySurface->Flip(d_ptr->primarySurface, 0, d_ptr->flipFlags);
|
---|
1349 | #else
|
---|
1350 | if (backgroundColor.isValid()) {
|
---|
1351 | DFBResult result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_ADMINISTRATIVE);
|
---|
1352 | if (result != DFB_OK) {
|
---|
1353 | DirectFBError("QDirectFBScreen::connect "
|
---|
1354 | "Unable to set cooperative level", result);
|
---|
1355 | }
|
---|
1356 | result = d_ptr->dfbLayer->SetBackgroundColor(d_ptr->dfbLayer, backgroundColor.red(), backgroundColor.green(),
|
---|
1357 | backgroundColor.blue(), backgroundColor.alpha());
|
---|
1358 | if (result != DFB_OK) {
|
---|
1359 | DirectFBError("QDirectFBScreenCursor::connect: "
|
---|
1360 | "Unable to set background color", result);
|
---|
1361 | }
|
---|
1362 |
|
---|
1363 | result = d_ptr->dfbLayer->SetBackgroundMode(d_ptr->dfbLayer, DLBM_COLOR);
|
---|
1364 | if (result != DFB_OK) {
|
---|
1365 | DirectFBError("QDirectFBScreenCursor::connect: "
|
---|
1366 | "Unable to set background mode", result);
|
---|
1367 | }
|
---|
1368 |
|
---|
1369 | result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_SHARED);
|
---|
1370 | if (result != DFB_OK) {
|
---|
1371 | DirectFBError("QDirectFBScreen::connect "
|
---|
1372 | "Unable to set cooperative level", result);
|
---|
1373 | }
|
---|
1374 |
|
---|
1375 | }
|
---|
1376 | #endif
|
---|
1377 |
|
---|
1378 | return true;
|
---|
1379 | }
|
---|
1380 |
|
---|
1381 | void QDirectFBScreen::disconnect()
|
---|
1382 | {
|
---|
1383 | #if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
|
---|
1384 | if (d_ptr->imageProvider)
|
---|
1385 | d_ptr->imageProvider->Release(d_ptr->imageProvider);
|
---|
1386 | #endif
|
---|
1387 | #ifdef QT_NO_DIRECTFB_WM
|
---|
1388 | d_ptr->primarySurface->Release(d_ptr->primarySurface);
|
---|
1389 | d_ptr->primarySurface = 0;
|
---|
1390 | #endif
|
---|
1391 |
|
---|
1392 | foreach (IDirectFBSurface *surf, d_ptr->allocatedSurfaces)
|
---|
1393 | surf->Release(surf);
|
---|
1394 | d_ptr->allocatedSurfaces.clear();
|
---|
1395 |
|
---|
1396 | #ifndef QT_NO_DIRECTFB_LAYER
|
---|
1397 | d_ptr->dfbLayer->Release(d_ptr->dfbLayer);
|
---|
1398 | d_ptr->dfbLayer = 0;
|
---|
1399 | #endif
|
---|
1400 |
|
---|
1401 | d_ptr->dfbScreen->Release(d_ptr->dfbScreen);
|
---|
1402 | d_ptr->dfbScreen = 0;
|
---|
1403 |
|
---|
1404 | d_ptr->dfb->Release(d_ptr->dfb);
|
---|
1405 | d_ptr->dfb = 0;
|
---|
1406 | }
|
---|
1407 |
|
---|
1408 | bool QDirectFBScreen::initDevice()
|
---|
1409 | {
|
---|
1410 | #ifndef QT_NO_DIRECTFB_MOUSE
|
---|
1411 | if (qgetenv("QWS_MOUSE_PROTO").isEmpty()) {
|
---|
1412 | QWSServer::instance()->setDefaultMouse("None");
|
---|
1413 | d_ptr->mouse = new QDirectFBMouseHandler;
|
---|
1414 | }
|
---|
1415 | #endif
|
---|
1416 | #ifndef QT_NO_DIRECTFB_KEYBOARD
|
---|
1417 | if (qgetenv("QWS_KEYBOARD").isEmpty()) {
|
---|
1418 | QWSServer::instance()->setDefaultKeyboard("None");
|
---|
1419 | d_ptr->keyboard = new QDirectFBKeyboardHandler(QString());
|
---|
1420 | }
|
---|
1421 | #endif
|
---|
1422 |
|
---|
1423 | #ifdef QT_DIRECTFB_CURSOR
|
---|
1424 | qt_screencursor = new QDirectFBScreenCursor;
|
---|
1425 | #elif !defined QT_NO_QWS_CURSOR
|
---|
1426 | QScreenCursor::initSoftwareCursor();
|
---|
1427 | #endif
|
---|
1428 | return true;
|
---|
1429 | }
|
---|
1430 |
|
---|
1431 | void QDirectFBScreen::shutdownDevice()
|
---|
1432 | {
|
---|
1433 | #ifndef QT_NO_DIRECTFB_MOUSE
|
---|
1434 | delete d_ptr->mouse;
|
---|
1435 | d_ptr->mouse = 0;
|
---|
1436 | #endif
|
---|
1437 | #ifndef QT_NO_DIRECTFB_KEYBOARD
|
---|
1438 | delete d_ptr->keyboard;
|
---|
1439 | d_ptr->keyboard = 0;
|
---|
1440 | #endif
|
---|
1441 |
|
---|
1442 | #ifndef QT_NO_QWS_CURSOR
|
---|
1443 | delete qt_screencursor;
|
---|
1444 | qt_screencursor = 0;
|
---|
1445 | #endif
|
---|
1446 | }
|
---|
1447 |
|
---|
1448 | void QDirectFBScreen::setMode(int width, int height, int depth)
|
---|
1449 | {
|
---|
1450 | d_ptr->dfb->SetVideoMode(d_ptr->dfb, width, height, depth);
|
---|
1451 | }
|
---|
1452 |
|
---|
1453 | void QDirectFBScreen::blank(bool on)
|
---|
1454 | {
|
---|
1455 | d_ptr->dfbScreen->SetPowerMode(d_ptr->dfbScreen,
|
---|
1456 | (on ? DSPM_ON : DSPM_SUSPEND));
|
---|
1457 | }
|
---|
1458 |
|
---|
1459 | QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const
|
---|
1460 | {
|
---|
1461 | #ifdef QT_NO_DIRECTFB_WM
|
---|
1462 | if (QApplication::type() == QApplication::GuiServer) {
|
---|
1463 | return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
|
---|
1464 | } else {
|
---|
1465 | return QScreen::createSurface(widget);
|
---|
1466 | }
|
---|
1467 | #else
|
---|
1468 | return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
|
---|
1469 | #endif
|
---|
1470 | }
|
---|
1471 |
|
---|
1472 | QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const
|
---|
1473 | {
|
---|
1474 | if (key == QLatin1String("directfb")) {
|
---|
1475 | return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this));
|
---|
1476 | }
|
---|
1477 | return QScreen::createSurface(key);
|
---|
1478 | }
|
---|
1479 |
|
---|
1480 | #if defined QT_NO_DIRECTFB_WM
|
---|
1481 | struct PaintCommand {
|
---|
1482 | PaintCommand() : dfbSurface(0), windowOpacity(255), blittingFlags(DSBLIT_NOFX) {}
|
---|
1483 | IDirectFBSurface *dfbSurface;
|
---|
1484 | QImage image;
|
---|
1485 | QPoint windowPosition;
|
---|
1486 | QRegion source;
|
---|
1487 | quint8 windowOpacity;
|
---|
1488 | DFBSurfaceBlittingFlags blittingFlags;
|
---|
1489 | };
|
---|
1490 |
|
---|
1491 | static inline void initParameters(DFBRectangle &source, const QRect &sourceGlobal, const QPoint &pos)
|
---|
1492 | {
|
---|
1493 | source.x = sourceGlobal.x() - pos.x();
|
---|
1494 | source.y = sourceGlobal.y() - pos.y();
|
---|
1495 | source.w = sourceGlobal.width();
|
---|
1496 | source.h = sourceGlobal.height();
|
---|
1497 | }
|
---|
1498 | #endif
|
---|
1499 |
|
---|
1500 | void QDirectFBScreen::exposeRegion(QRegion r, int)
|
---|
1501 | {
|
---|
1502 | Q_UNUSED(r);
|
---|
1503 | #if defined QT_NO_DIRECTFB_WM
|
---|
1504 |
|
---|
1505 | r &= region();
|
---|
1506 | if (r.isEmpty()) {
|
---|
1507 | return;
|
---|
1508 | }
|
---|
1509 | r = r.boundingRect();
|
---|
1510 |
|
---|
1511 | IDirectFBSurface *primary = d_ptr->primarySurface;
|
---|
1512 | const QList<QWSWindow*> windows = QWSServer::instance()->clientWindows();
|
---|
1513 | QVarLengthArray<PaintCommand, 4> commands(windows.size());
|
---|
1514 | QRegion region = r;
|
---|
1515 | int idx = 0;
|
---|
1516 | for (int i=0; i<windows.size(); ++i) {
|
---|
1517 | QWSWindowSurface *surface = windows.at(i)->windowSurface();
|
---|
1518 | if (!surface)
|
---|
1519 | continue;
|
---|
1520 |
|
---|
1521 | const QRect windowGeometry = surface->geometry();
|
---|
1522 | const QRegion intersection = region & windowGeometry;
|
---|
1523 | if (intersection.isEmpty()) {
|
---|
1524 | continue;
|
---|
1525 | }
|
---|
1526 |
|
---|
1527 | PaintCommand &cmd = commands[idx];
|
---|
1528 |
|
---|
1529 | if (surface->key() == QLatin1String("directfb")) {
|
---|
1530 | const QDirectFBWindowSurface *ws = static_cast<QDirectFBWindowSurface*>(surface);
|
---|
1531 | cmd.dfbSurface = ws->directFBSurface();
|
---|
1532 |
|
---|
1533 | if (!cmd.dfbSurface) {
|
---|
1534 | continue;
|
---|
1535 | }
|
---|
1536 | } else {
|
---|
1537 | cmd.image = surface->image();
|
---|
1538 | if (cmd.image.isNull()) {
|
---|
1539 | continue;
|
---|
1540 | }
|
---|
1541 | }
|
---|
1542 | ++idx;
|
---|
1543 |
|
---|
1544 | cmd.windowPosition = windowGeometry.topLeft();
|
---|
1545 | cmd.source = intersection;
|
---|
1546 | if (windows.at(i)->isOpaque()) {
|
---|
1547 | region -= intersection;
|
---|
1548 | if (region.isEmpty())
|
---|
1549 | break;
|
---|
1550 | } else {
|
---|
1551 | cmd.windowOpacity = windows.at(i)->opacity();
|
---|
1552 | cmd.blittingFlags = cmd.windowOpacity == 255
|
---|
1553 | ? DSBLIT_BLEND_ALPHACHANNEL
|
---|
1554 | : (DSBLIT_BLEND_ALPHACHANNEL|DSBLIT_BLEND_COLORALPHA);
|
---|
1555 | }
|
---|
1556 | }
|
---|
1557 |
|
---|
1558 | solidFill(d_ptr->backgroundColor, region);
|
---|
1559 |
|
---|
1560 | while (idx > 0) {
|
---|
1561 | const PaintCommand &cmd = commands[--idx];
|
---|
1562 | Q_ASSERT(cmd.dfbSurface || !cmd.image.isNull());
|
---|
1563 | IDirectFBSurface *surface;
|
---|
1564 | if (cmd.dfbSurface) {
|
---|
1565 | surface = cmd.dfbSurface;
|
---|
1566 | } else {
|
---|
1567 | Q_ASSERT(!cmd.image.isNull());
|
---|
1568 | DFBResult result;
|
---|
1569 | surface = createDFBSurface(cmd.image, cmd.image.format(), DontTrackSurface, &result);
|
---|
1570 | Q_ASSERT((result != DFB_OK) == !surface);
|
---|
1571 | if (result != DFB_OK) {
|
---|
1572 | DirectFBError("QDirectFBScreen::exposeRegion: Can't create surface from image", result);
|
---|
1573 | continue;
|
---|
1574 | }
|
---|
1575 | }
|
---|
1576 |
|
---|
1577 | primary->SetBlittingFlags(primary, cmd.blittingFlags);
|
---|
1578 | if (cmd.blittingFlags & DSBLIT_BLEND_COLORALPHA) {
|
---|
1579 | primary->SetColor(primary, 0xff, 0xff, 0xff, cmd.windowOpacity);
|
---|
1580 | }
|
---|
1581 | const QRegion ®ion = cmd.source;
|
---|
1582 | const int rectCount = region.rectCount();
|
---|
1583 | DFBRectangle source;
|
---|
1584 | if (rectCount == 1) {
|
---|
1585 | ::initParameters(source, region.boundingRect(), cmd.windowPosition);
|
---|
1586 | primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y);
|
---|
1587 | } else {
|
---|
1588 | const QVector<QRect> rects = region.rects();
|
---|
1589 | for (int i=0; i<rectCount; ++i) {
|
---|
1590 | ::initParameters(source, rects.at(i), cmd.windowPosition);
|
---|
1591 | primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y);
|
---|
1592 | }
|
---|
1593 | }
|
---|
1594 | if (surface != cmd.dfbSurface) {
|
---|
1595 | surface->Release(surface);
|
---|
1596 | }
|
---|
1597 | }
|
---|
1598 |
|
---|
1599 | primary->SetColor(primary, 0xff, 0xff, 0xff, 0xff);
|
---|
1600 |
|
---|
1601 | #if defined QT_NO_DIRECTFB_CURSOR and !defined QT_NO_QWS_CURSOR
|
---|
1602 | if (QScreenCursor *cursor = QScreenCursor::instance()) {
|
---|
1603 | const QRect cursorRectangle = cursor->boundingRect();
|
---|
1604 | if (cursor->isVisible() && !cursor->isAccelerated() && r.intersects(cursorRectangle)) {
|
---|
1605 | const QImage image = cursor->image();
|
---|
1606 | if (image.cacheKey() != d_ptr->cursorImageKey) {
|
---|
1607 | if (d_ptr->cursorSurface) {
|
---|
1608 | releaseDFBSurface(d_ptr->cursorSurface);
|
---|
1609 | }
|
---|
1610 | d_ptr->cursorSurface = createDFBSurface(image, image.format(), QDirectFBScreen::TrackSurface);
|
---|
1611 | d_ptr->cursorImageKey = image.cacheKey();
|
---|
1612 | }
|
---|
1613 |
|
---|
1614 | Q_ASSERT(d_ptr->cursorSurface);
|
---|
1615 | primary->SetBlittingFlags(primary, DSBLIT_BLEND_ALPHACHANNEL);
|
---|
1616 | primary->Blit(primary, d_ptr->cursorSurface, 0, cursorRectangle.x(), cursorRectangle.y());
|
---|
1617 | }
|
---|
1618 | }
|
---|
1619 | #endif
|
---|
1620 | flipSurface(primary, d_ptr->flipFlags, r, QPoint());
|
---|
1621 | primary->SetBlittingFlags(primary, DSBLIT_NOFX);
|
---|
1622 | #endif
|
---|
1623 | }
|
---|
1624 |
|
---|
1625 | void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion)
|
---|
1626 | {
|
---|
1627 | #ifdef QT_DIRECTFB_WM
|
---|
1628 | Q_UNUSED(color);
|
---|
1629 | Q_UNUSED(region);
|
---|
1630 | #else
|
---|
1631 | QDirectFBScreen::solidFill(d_ptr->primarySurface, color, region);
|
---|
1632 | #endif
|
---|
1633 | }
|
---|
1634 |
|
---|
1635 | static inline void clearRect(IDirectFBSurface *surface, const QColor &color, const QRect &rect)
|
---|
1636 | {
|
---|
1637 | Q_ASSERT(surface);
|
---|
1638 | const DFBRegion region = { rect.left(), rect.top(), rect.right(), rect.bottom() };
|
---|
1639 | // could just reinterpret_cast this to a DFBRegion
|
---|
1640 | surface->SetClip(surface, ®ion);
|
---|
1641 | surface->Clear(surface, color.red(), color.green(), color.blue(), color.alpha());
|
---|
1642 | }
|
---|
1643 |
|
---|
1644 | void QDirectFBScreen::solidFill(IDirectFBSurface *surface, const QColor &color, const QRegion ®ion)
|
---|
1645 | {
|
---|
1646 | if (region.isEmpty())
|
---|
1647 | return;
|
---|
1648 |
|
---|
1649 | const int n = region.rectCount();
|
---|
1650 | if (n == 1) {
|
---|
1651 | clearRect(surface, color, region.boundingRect());
|
---|
1652 | } else {
|
---|
1653 | const QVector<QRect> rects = region.rects();
|
---|
1654 | for (int i=0; i<n; ++i) {
|
---|
1655 | clearRect(surface, color, rects.at(i));
|
---|
1656 | }
|
---|
1657 | }
|
---|
1658 | surface->SetClip(surface, 0);
|
---|
1659 | }
|
---|
1660 |
|
---|
1661 | QImage::Format QDirectFBScreen::alphaPixmapFormat() const
|
---|
1662 | {
|
---|
1663 | return d_ptr->alphaPixmapFormat;
|
---|
1664 | }
|
---|
1665 |
|
---|
1666 | bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description,
|
---|
1667 | QImage::Format format)
|
---|
1668 | {
|
---|
1669 | const DFBSurfacePixelFormat pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
|
---|
1670 | if (pixelformat == DSPF_UNKNOWN)
|
---|
1671 | return false;
|
---|
1672 | description->flags |= DSDESC_PIXELFORMAT;
|
---|
1673 | description->pixelformat = pixelformat;
|
---|
1674 | if (QDirectFBScreen::isPremultiplied(format)) {
|
---|
1675 | if (!(description->flags & DSDESC_CAPS)) {
|
---|
1676 | description->caps = DSCAPS_PREMULTIPLIED;
|
---|
1677 | description->flags |= DSDESC_CAPS;
|
---|
1678 | } else {
|
---|
1679 | description->caps |= DSCAPS_PREMULTIPLIED;
|
---|
1680 | }
|
---|
1681 | }
|
---|
1682 | return true;
|
---|
1683 | }
|
---|
1684 |
|
---|
1685 | uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl)
|
---|
1686 | {
|
---|
1687 | void *mem = 0;
|
---|
1688 | const DFBResult result = surface->Lock(surface, flags, &mem, bpl);
|
---|
1689 | if (result != DFB_OK) {
|
---|
1690 | DirectFBError("QDirectFBScreen::lockSurface()", result);
|
---|
1691 | }
|
---|
1692 |
|
---|
1693 | return reinterpret_cast<uchar*>(mem);
|
---|
1694 | }
|
---|
1695 |
|
---|
1696 | static inline bool isFullUpdate(IDirectFBSurface *surface, const QRegion ®ion, const QPoint &offset)
|
---|
1697 | {
|
---|
1698 | if (offset == QPoint(0, 0) && region.rectCount() == 1) {
|
---|
1699 | QSize size;
|
---|
1700 | surface->GetSize(surface, &size.rwidth(), &size.rheight());
|
---|
1701 | if (region.boundingRect().size() == size)
|
---|
1702 | return true;
|
---|
1703 | }
|
---|
1704 | return false;
|
---|
1705 | }
|
---|
1706 |
|
---|
1707 | void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags,
|
---|
1708 | const QRegion ®ion, const QPoint &offset)
|
---|
1709 | {
|
---|
1710 | if (d_ptr->directFBFlags & NoPartialFlip
|
---|
1711 | || (!(flipFlags & DSFLIP_BLIT) && QT_PREPEND_NAMESPACE(isFullUpdate(surface, region, offset)))) {
|
---|
1712 | surface->Flip(surface, 0, flipFlags);
|
---|
1713 | } else {
|
---|
1714 | if (!(d_ptr->directFBFlags & BoundingRectFlip) && region.rectCount() > 1) {
|
---|
1715 | const QVector<QRect> rects = region.rects();
|
---|
1716 | const DFBSurfaceFlipFlags nonWaitFlags = flipFlags & ~DSFLIP_WAIT;
|
---|
1717 | for (int i=0; i<rects.size(); ++i) {
|
---|
1718 | const QRect &r = rects.at(i);
|
---|
1719 | const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
|
---|
1720 | r.right() + offset.x(),
|
---|
1721 | r.bottom() + offset.y() };
|
---|
1722 | surface->Flip(surface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags);
|
---|
1723 | }
|
---|
1724 | } else {
|
---|
1725 | const QRect r = region.boundingRect();
|
---|
1726 | const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
|
---|
1727 | r.right() + offset.x(),
|
---|
1728 | r.bottom() + offset.y() };
|
---|
1729 | surface->Flip(surface, &dfbReg, flipFlags);
|
---|
1730 | }
|
---|
1731 | }
|
---|
1732 | }
|
---|
1733 |
|
---|
1734 | #if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
|
---|
1735 | void QDirectFBScreen::setDirectFBImageProvider(IDirectFBImageProvider *provider)
|
---|
1736 | {
|
---|
1737 | Q_ASSERT(provider);
|
---|
1738 | if (d_ptr->imageProvider)
|
---|
1739 | d_ptr->imageProvider->Release(d_ptr->imageProvider);
|
---|
1740 | d_ptr->imageProvider = provider;
|
---|
1741 | }
|
---|
1742 | #endif
|
---|
1743 |
|
---|
1744 | void QDirectFBScreen::waitIdle()
|
---|
1745 | {
|
---|
1746 | d_ptr->dfb->WaitIdle(d_ptr->dfb);
|
---|
1747 | }
|
---|
1748 |
|
---|
1749 | #ifdef QT_DIRECTFB_WM
|
---|
1750 | IDirectFBWindow *QDirectFBScreen::windowForWidget(const QWidget *widget) const
|
---|
1751 | {
|
---|
1752 | if (widget) {
|
---|
1753 | const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
|
---|
1754 | if (surface && surface->key() == QLatin1String("directfb")) {
|
---|
1755 | return static_cast<const QDirectFBWindowSurface*>(surface)->directFBWindow();
|
---|
1756 | }
|
---|
1757 | }
|
---|
1758 | return 0;
|
---|
1759 | }
|
---|
1760 | #endif
|
---|
1761 |
|
---|
1762 | IDirectFBSurface * QDirectFBScreen::surfaceForWidget(const QWidget *widget, QRect *rect) const
|
---|
1763 | {
|
---|
1764 | Q_ASSERT(widget);
|
---|
1765 | if (!widget->isVisible() || widget->size().isNull())
|
---|
1766 | return 0;
|
---|
1767 |
|
---|
1768 | const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
|
---|
1769 | if (surface && surface->key() == QLatin1String("directfb")) {
|
---|
1770 | return static_cast<const QDirectFBWindowSurface*>(surface)->surfaceForWidget(widget, rect);
|
---|
1771 | }
|
---|
1772 | return 0;
|
---|
1773 | }
|
---|
1774 |
|
---|
1775 | #ifdef QT_DIRECTFB_SUBSURFACE
|
---|
1776 | IDirectFBSurface *QDirectFBScreen::subSurfaceForWidget(const QWidget *widget, const QRect &area) const
|
---|
1777 | {
|
---|
1778 | Q_ASSERT(widget);
|
---|
1779 | QRect rect;
|
---|
1780 | IDirectFBSurface *surface = surfaceForWidget(widget, &rect);
|
---|
1781 | IDirectFBSurface *subSurface = 0;
|
---|
1782 | if (surface) {
|
---|
1783 | if (!area.isNull())
|
---|
1784 | rect &= area.translated(widget->mapTo(widget->window(), QPoint(0, 0)));
|
---|
1785 | if (!rect.isNull()) {
|
---|
1786 | const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() };
|
---|
1787 | const DFBResult result = surface->GetSubSurface(surface, &subRect, &subSurface);
|
---|
1788 | if (result != DFB_OK) {
|
---|
1789 | DirectFBError("QDirectFBScreen::subSurface(): Can't get sub surface", result);
|
---|
1790 | }
|
---|
1791 | }
|
---|
1792 | }
|
---|
1793 | return subSurface;
|
---|
1794 | }
|
---|
1795 | #endif
|
---|
1796 |
|
---|
1797 | Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_widget(const QWidget *widget, QRect *rect)
|
---|
1798 | {
|
---|
1799 | return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->surfaceForWidget(widget, rect) : 0;
|
---|
1800 | }
|
---|
1801 | #ifdef QT_DIRECTFB_SUBSURFACE
|
---|
1802 | Q_GUI_EXPORT IDirectFBSurface *qt_directfb_subsurface_for_widget(const QWidget *widget, const QRect &area)
|
---|
1803 | {
|
---|
1804 | return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->subSurfaceForWidget(widget, area) : 0;
|
---|
1805 | }
|
---|
1806 | #endif
|
---|
1807 | #ifdef QT_DIRECTFB_WM
|
---|
1808 | Q_GUI_EXPORT IDirectFBWindow *qt_directfb_window_for_widget(const QWidget *widget)
|
---|
1809 | {
|
---|
1810 | return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->windowForWidget(widget) : 0;
|
---|
1811 | }
|
---|
1812 |
|
---|
1813 | #endif
|
---|
1814 |
|
---|
1815 | QT_END_NAMESPACE
|
---|
1816 |
|
---|
1817 | #include "qdirectfbscreen.moc"
|
---|
1818 | #endif // QT_NO_QWS_DIRECTFB
|
---|
1819 |
|
---|