summaryrefslogtreecommitdiffstats
path: root/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp')
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp1819
1 files changed, 1819 insertions, 0 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
new file mode 100644
index 0000000000..ff15078ee4
--- /dev/null
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -0,0 +1,1819 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdirectfbscreen.h"
+#include "qdirectfbwindowsurface.h"
+#include "qdirectfbpixmap.h"
+#include "qdirectfbmouse.h"
+#include "qdirectfbkeyboard.h"
+#include <QtGui/qwsdisplay_qws.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qapplication.h>
+#include <QtGui/qwindowsystem_qws.h>
+#include <QtGui/private/qgraphicssystem_qws_p.h>
+#include <QtGui/private/qwssignalhandler_p.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qrect.h>
+
+#ifndef QT_NO_QWS_DIRECTFB
+
+QT_BEGIN_NAMESPACE
+
+class QDirectFBScreenPrivate : public QObject, public QWSGraphicsSystem
+{
+ Q_OBJECT
+public:
+ QDirectFBScreenPrivate(QDirectFBScreen *qptr);
+ ~QDirectFBScreenPrivate();
+
+ void setFlipFlags(const QStringList &args);
+ QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
+public slots:
+#ifdef QT_DIRECTFB_WM
+ void onWindowEvent(QWSWindow *window, QWSServer::WindowEvent event);
+#endif
+public:
+ IDirectFB *dfb;
+ DFBSurfaceFlipFlags flipFlags;
+ QDirectFBScreen::DirectFBFlags directFBFlags;
+ QImage::Format alphaPixmapFormat;
+ IDirectFBScreen *dfbScreen;
+#ifdef QT_NO_DIRECTFB_WM
+ IDirectFBSurface *primarySurface;
+ QColor backgroundColor;
+#endif
+#ifndef QT_NO_DIRECTFB_LAYER
+ IDirectFBDisplayLayer *dfbLayer;
+#endif
+ QSet<IDirectFBSurface*> allocatedSurfaces;
+
+#ifndef QT_NO_DIRECTFB_MOUSE
+ QDirectFBMouseHandler *mouse;
+#endif
+#ifndef QT_NO_DIRECTFB_KEYBOARD
+ QDirectFBKeyboardHandler *keyboard;
+#endif
+#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ IDirectFBImageProvider *imageProvider;
+#endif
+ IDirectFBSurface *cursorSurface;
+ qint64 cursorImageKey;
+
+ QDirectFBScreen *q;
+ static QDirectFBScreen *instance;
+};
+
+QDirectFBScreen *QDirectFBScreenPrivate::instance = 0;
+
+QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *qptr)
+ : QWSGraphicsSystem(qptr), dfb(0), flipFlags(DSFLIP_NONE),
+ directFBFlags(QDirectFBScreen::NoFlags), alphaPixmapFormat(QImage::Format_Invalid),
+ dfbScreen(0)
+#ifdef QT_NO_DIRECTFB_WM
+ , primarySurface(0)
+#endif
+#ifndef QT_NO_DIRECTFB_LAYER
+ , dfbLayer(0)
+#endif
+#ifndef QT_NO_DIRECTFB_MOUSE
+ , mouse(0)
+#endif
+#ifndef QT_NO_DIRECTFB_KEYBOARD
+ , keyboard(0)
+#endif
+#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ , imageProvider(0)
+#endif
+ , cursorSurface(0)
+ , cursorImageKey(0)
+ , q(qptr)
+{
+#ifndef QT_NO_QWS_SIGNALHANDLER
+ QWSSignalHandler::instance()->addObject(this);
+#endif
+#ifdef QT_DIRECTFB_WM
+ connect(QWSServer::instance(), SIGNAL(windowEvent(QWSWindow*,QWSServer::WindowEvent)),
+ this, SLOT(onWindowEvent(QWSWindow*,QWSServer::WindowEvent)));
+#endif
+}
+
+QDirectFBScreenPrivate::~QDirectFBScreenPrivate()
+{
+#ifndef QT_NO_DIRECTFB_MOUSE
+ delete mouse;
+#endif
+#ifndef QT_NO_DIRECTFB_KEYBOARD
+ delete keyboard;
+#endif
+#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ if (imageProvider)
+ imageProvider->Release(imageProvider);
+#endif
+
+ for (QSet<IDirectFBSurface*>::const_iterator it = allocatedSurfaces.begin(); it != allocatedSurfaces.end(); ++it) {
+ (*it)->Release(*it);
+ }
+
+#ifdef QT_NO_DIRECTFB_WM
+ if (primarySurface)
+ primarySurface->Release(primarySurface);
+#endif
+
+#ifndef QT_NO_DIRECTFB_LAYER
+ if (dfbLayer)
+ dfbLayer->Release(dfbLayer);
+#endif
+
+ if (dfbScreen)
+ dfbScreen->Release(dfbScreen);
+
+ if (dfb)
+ dfb->Release(dfb);
+}
+
+IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QImage &image, QImage::Format format, SurfaceCreationOptions options, DFBResult *resultPtr)
+{
+ if (image.isNull()) // assert?
+ return 0;
+
+ if (QDirectFBScreen::getSurfacePixelFormat(format) == DSPF_UNKNOWN) {
+ format = QDirectFBPixmapData::hasAlphaChannel(image) ? d_ptr->alphaPixmapFormat : pixelFormat();
+ }
+ if (image.format() != format) {
+ return createDFBSurface(image.convertToFormat(format), format, options | NoPreallocated, resultPtr);
+ }
+
+ DFBSurfaceDescription description;
+ memset(&description, 0, sizeof(DFBSurfaceDescription));
+ description.width = image.width();
+ description.height = image.height();
+ description.flags = DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT;
+ initSurfaceDescriptionPixelFormat(&description, format);
+ bool doMemCopy = true;
+#ifdef QT_DIRECTFB_PREALLOCATED
+ if (!(options & NoPreallocated)) {
+ doMemCopy = false;
+ description.flags |= DSDESC_PREALLOCATED;
+ description.preallocated[0].data = const_cast<uchar*>(image.bits());
+ description.preallocated[0].pitch = image.bytesPerLine();
+ description.preallocated[1].data = 0;
+ description.preallocated[1].pitch = 0;
+ }
+#endif
+ DFBResult result;
+ IDirectFBSurface *surface = createDFBSurface(description, options, &result);
+ if (resultPtr)
+ *resultPtr = result;
+ if (!surface) {
+ DirectFBError("Couldn't create surface createDFBSurface(QImage, QImage::Format, SurfaceCreationOptions)", result);
+ return 0;
+ }
+ if (doMemCopy) {
+ int bplDFB;
+ uchar *mem = QDirectFBScreen::lockSurface(surface, DSLF_WRITE, &bplDFB);
+ if (mem) {
+ const int height = image.height();
+ const int bplQt = image.bytesPerLine();
+ if (bplQt == bplDFB && bplQt == (image.width() * image.depth() / 8)) {
+ memcpy(mem, image.bits(), image.byteCount());
+ } else {
+ for (int i=0; i<height; ++i) {
+ memcpy(mem, image.scanLine(i), bplQt);
+ mem += bplDFB;
+ }
+ }
+ surface->Unlock(surface);
+ }
+ }
+#ifdef QT_DIRECTFB_PALETTE
+ if (image.colorCount() != 0 && surface)
+ QDirectFBScreen::setSurfaceColorTable(surface, image);
+#endif
+ return surface;
+}
+
+IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src,
+ QImage::Format format,
+ SurfaceCreationOptions options,
+ DFBResult *result)
+{
+ Q_ASSERT(src);
+ QSize size;
+ src->GetSize(src, &size.rwidth(), &size.rheight());
+ IDirectFBSurface *surface = createDFBSurface(size, format, options, result);
+ DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlphaChannel(surface)
+ ? DSBLIT_BLEND_ALPHACHANNEL
+ : DSBLIT_NOFX;
+ if (flags & DSBLIT_BLEND_ALPHACHANNEL)
+ surface->Clear(surface, 0, 0, 0, 0);
+
+ surface->SetBlittingFlags(surface, flags);
+ surface->Blit(surface, src, 0, 0, 0);
+#if (Q_DIRECTFB_VERSION >= 0x010000)
+ surface->ReleaseSource(surface);
+#endif
+ return surface;
+}
+
+IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size,
+ QImage::Format format,
+ SurfaceCreationOptions options,
+ DFBResult *result)
+{
+ DFBSurfaceDescription desc;
+ memset(&desc, 0, sizeof(DFBSurfaceDescription));
+ desc.flags |= DSDESC_WIDTH|DSDESC_HEIGHT;
+ if (!QDirectFBScreen::initSurfaceDescriptionPixelFormat(&desc, format))
+ return 0;
+ desc.width = size.width();
+ desc.height = size.height();
+ return createDFBSurface(desc, options, result);
+}
+
+IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc, SurfaceCreationOptions options, DFBResult *resultPtr)
+{
+ DFBResult tmp;
+ DFBResult &result = (resultPtr ? *resultPtr : tmp);
+ result = DFB_OK;
+ IDirectFBSurface *newSurface = 0;
+
+ if (!d_ptr->dfb) {
+ qWarning("QDirectFBScreen::createDFBSurface() - not connected");
+ return 0;
+ }
+
+ if (d_ptr->directFBFlags & VideoOnly
+ && !(desc.flags & DSDESC_PREALLOCATED)
+ && (!(desc.flags & DSDESC_CAPS) || !(desc.caps & DSCAPS_SYSTEMONLY))) {
+ // Add the video only capability. This means the surface will be created in video ram
+ if (!(desc.flags & DSDESC_CAPS)) {
+ desc.caps = DSCAPS_VIDEOONLY;
+ desc.flags |= DSDESC_CAPS;
+ } else {
+ desc.caps |= DSCAPS_VIDEOONLY;
+ }
+ result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface);
+ if (result != DFB_OK
+#ifdef QT_NO_DEBUG
+ && (desc.flags & DSDESC_CAPS) && (desc.caps & DSCAPS_PRIMARY)
+#endif
+ ) {
+ qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n"
+ " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s",
+ desc.flags, desc.caps, desc.width, desc.height,
+ desc.pixelformat, DFB_PIXELFORMAT_INDEX(desc.pixelformat),
+ desc.preallocated[0].data, desc.preallocated[0].pitch,
+ DirectFBErrorString(result));
+ }
+ desc.caps &= ~DSCAPS_VIDEOONLY;
+ }
+
+ if (d_ptr->directFBFlags & SystemOnly)
+ desc.caps |= DSCAPS_SYSTEMONLY;
+
+ if (!newSurface)
+ result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &desc, &newSurface);
+
+ if (result != DFB_OK) {
+ qWarning("QDirectFBScreen::createDFBSurface() Failed!\n"
+ " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s",
+ desc.flags, desc.caps, desc.width, desc.height,
+ desc.pixelformat, DFB_PIXELFORMAT_INDEX(desc.pixelformat),
+ desc.preallocated[0].data, desc.preallocated[0].pitch,
+ DirectFBErrorString(result));
+ return 0;
+ }
+
+ Q_ASSERT(newSurface);
+
+ if (options & TrackSurface) {
+ d_ptr->allocatedSurfaces.insert(newSurface);
+ }
+
+ return newSurface;
+}
+
+#ifdef QT_DIRECTFB_SUBSURFACE
+IDirectFBSurface *QDirectFBScreen::getSubSurface(IDirectFBSurface *surface,
+ const QRect &rect,
+ SurfaceCreationOptions options,
+ DFBResult *resultPtr)
+{
+ Q_ASSERT(!(options & NoPreallocated));
+ Q_ASSERT(surface);
+ DFBResult res;
+ DFBResult &result = (resultPtr ? *resultPtr : res);
+ IDirectFBSurface *subSurface = 0;
+ if (rect.isNull()) {
+ result = surface->GetSubSurface(surface, 0, &subSurface);
+ } else {
+ const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() };
+ result = surface->GetSubSurface(surface, &subRect, &subSurface);
+ }
+ if (result != DFB_OK) {
+ DirectFBError("Can't get sub surface", result);
+ } else if (options & TrackSurface) {
+ d_ptr->allocatedSurfaces.insert(subSurface);
+ }
+ return subSurface;
+}
+#endif
+
+
+void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface)
+{
+ Q_ASSERT(QDirectFBScreen::instance());
+ Q_ASSERT(surface);
+ surface->Release(surface);
+ if (!d_ptr->allocatedSurfaces.remove(surface))
+ qWarning("QDirectFBScreen::releaseDFBSurface() - %p not in list", surface);
+
+ //qDebug("Released surface at %p. New count = %d", surface, d_ptr->allocatedSurfaces.count());
+}
+
+QDirectFBScreen::DirectFBFlags QDirectFBScreen::directFBFlags() const
+{
+ return d_ptr->directFBFlags;
+}
+
+IDirectFB *QDirectFBScreen::dfb()
+{
+ return d_ptr->dfb;
+}
+
+#ifdef QT_NO_DIRECTFB_WM
+IDirectFBSurface *QDirectFBScreen::primarySurface()
+{
+ return d_ptr->primarySurface;
+}
+#endif
+
+#ifndef QT_NO_DIRECTFB_LAYER
+IDirectFBDisplayLayer *QDirectFBScreen::dfbDisplayLayer()
+{
+ return d_ptr->dfbLayer;
+}
+#endif
+
+DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format format)
+{
+ switch (format) {
+#ifndef QT_NO_DIRECTFB_PALETTE
+ case QImage::Format_Indexed8:
+ return DSPF_LUT8;
+#endif
+ case QImage::Format_RGB888:
+ return DSPF_RGB24;
+ case QImage::Format_ARGB4444_Premultiplied:
+ return DSPF_ARGB4444;
+#if (Q_DIRECTFB_VERSION >= 0x010100)
+ case QImage::Format_RGB444:
+ return DSPF_RGB444;
+ case QImage::Format_RGB555:
+ return DSPF_RGB555;
+#endif
+ case QImage::Format_RGB16:
+ return DSPF_RGB16;
+#if (Q_DIRECTFB_VERSION >= 0x010000)
+ case QImage::Format_ARGB6666_Premultiplied:
+ return DSPF_ARGB6666;
+ case QImage::Format_RGB666:
+ return DSPF_RGB18;
+#endif
+ case QImage::Format_RGB32:
+ return DSPF_RGB32;
+ case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_ARGB32:
+ return DSPF_ARGB;
+ default:
+ return DSPF_UNKNOWN;
+ };
+}
+
+QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface)
+{
+ DFBSurfacePixelFormat format;
+ surface->GetPixelFormat(surface, &format);
+
+ switch (format) {
+ case DSPF_LUT8:
+ return QImage::Format_Indexed8;
+ case DSPF_RGB24:
+ return QImage::Format_RGB888;
+ case DSPF_ARGB4444:
+ return QImage::Format_ARGB4444_Premultiplied;
+#if (Q_DIRECTFB_VERSION >= 0x010100)
+ case DSPF_RGB444:
+ return QImage::Format_RGB444;
+ case DSPF_RGB555:
+#endif
+ case DSPF_ARGB1555:
+ return QImage::Format_RGB555;
+ case DSPF_RGB16:
+ return QImage::Format_RGB16;
+#if (Q_DIRECTFB_VERSION >= 0x010000)
+ case DSPF_ARGB6666:
+ return QImage::Format_ARGB6666_Premultiplied;
+ case DSPF_RGB18:
+ return QImage::Format_RGB666;
+#endif
+ case DSPF_RGB32:
+ return QImage::Format_RGB32;
+ case DSPF_ARGB: {
+ DFBSurfaceCapabilities caps;
+ const DFBResult result = surface->GetCapabilities(surface, &caps);
+ Q_ASSERT(result == DFB_OK);
+ Q_UNUSED(result);
+ return (caps & DSCAPS_PREMULTIPLIED
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_ARGB32); }
+ default:
+ break;
+ }
+ return QImage::Format_Invalid;
+}
+
+DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const uint *buffer,
+ int length)
+{
+ DFBSurfaceDescription description;
+ memset(&description, 0, sizeof(DFBSurfaceDescription));
+
+ description.flags = DSDESC_CAPS|DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT|DSDESC_PREALLOCATED;
+ description.caps = DSCAPS_PREMULTIPLIED;
+ description.width = length;
+ description.height = 1;
+ description.pixelformat = DSPF_ARGB;
+ description.preallocated[0].data = (void*)buffer;
+ description.preallocated[0].pitch = length * sizeof(uint);
+ description.preallocated[1].data = 0;
+ description.preallocated[1].pitch = 0;
+ return description;
+}
+
+#ifndef QT_NO_DIRECTFB_PALETTE
+void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface,
+ const QImage &image)
+{
+ if (!surface)
+ return;
+
+ const int numColors = image.colorCount();
+ if (numColors == 0)
+ return;
+
+ QVarLengthArray<DFBColor, 256> colors(numColors);
+ for (int i = 0; i < numColors; ++i) {
+ QRgb c = image.color(i);
+ colors[i].a = qAlpha(c);
+ colors[i].r = qRed(c);
+ colors[i].g = qGreen(c);
+ colors[i].b = qBlue(c);
+ }
+
+ IDirectFBPalette *palette;
+ DFBResult result;
+ result = surface->GetPalette(surface, &palette);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::setSurfaceColorTable GetPalette",
+ result);
+ return;
+ }
+ result = palette->SetEntries(palette, colors.data(), numColors, 0);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::setSurfaceColorTable SetEntries",
+ result);
+ }
+ palette->Release(palette);
+}
+
+#endif // QT_NO_DIRECTFB_PALETTE
+
+#if defined QT_DIRECTFB_CURSOR
+class Q_GUI_EXPORT QDirectFBScreenCursor : public QScreenCursor
+{
+public:
+ QDirectFBScreenCursor();
+ virtual void set(const QImage &image, int hotx, int hoty);
+ virtual void move(int x, int y);
+ virtual void show();
+ virtual void hide();
+private:
+#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
+ ~QDirectFBScreenCursor();
+ bool createWindow();
+ IDirectFBWindow *window;
+#endif
+ IDirectFBDisplayLayer *layer;
+};
+
+QDirectFBScreenCursor::QDirectFBScreenCursor()
+{
+ IDirectFB *fb = QDirectFBScreen::instance()->dfb();
+ if (!fb)
+ qFatal("QDirectFBScreenCursor: DirectFB not initialized");
+
+ layer = QDirectFBScreen::instance()->dfbDisplayLayer();
+ Q_ASSERT(layer);
+
+ enable = false;
+ hwaccel = true;
+ supportsAlpha = true;
+#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
+ window = 0;
+ DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::hide: "
+ "Unable to set cooperative level", result);
+ }
+ result = layer->SetCursorOpacity(layer, 0);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::hide: "
+ "Unable to set cursor opacity", result);
+ }
+
+ result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::hide: "
+ "Unable to set cooperative level", result);
+ }
+#endif
+}
+
+#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
+QDirectFBScreenCursor::~QDirectFBScreenCursor()
+{
+ if (window) {
+ window->Release(window);
+ window = 0;
+ }
+}
+
+bool QDirectFBScreenCursor::createWindow()
+{
+ Q_ASSERT(!window);
+ Q_ASSERT(!cursor.isNull());
+ DFBWindowDescription description;
+ memset(&description, 0, sizeof(DFBWindowDescription));
+ description.flags = DWDESC_POSX|DWDESC_POSY|DWDESC_WIDTH|DWDESC_HEIGHT|DWDESC_CAPS|DWDESC_PIXELFORMAT|DWDESC_SURFACE_CAPS;
+ description.width = cursor.width();
+ description.height = cursor.height();
+ description.posx = pos.x() - hotspot.x();
+ description.posy = pos.y() - hotspot.y();
+#if (Q_DIRECTFB_VERSION >= 0x010100)
+ description.flags |= DWDESC_OPTIONS;
+ description.options = DWOP_GHOST|DWOP_ALPHACHANNEL;
+#endif
+ description.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER;
+ const QImage::Format format = QDirectFBScreen::instance()->alphaPixmapFormat();
+ description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
+ if (QDirectFBScreen::isPremultiplied(format))
+ description.surface_caps = DSCAPS_PREMULTIPLIED;
+
+ DFBResult result = layer->CreateWindow(layer, &description, &window);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::createWindow: Unable to create window", result);
+ return false;
+ }
+ result = window->SetOpacity(window, 255);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::createWindow: Unable to set opacity ", result);
+ return false;
+ }
+
+ result = window->SetStackingClass(window, DWSC_UPPER);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::createWindow: Unable to set stacking class ", result);
+ return false;
+ }
+
+ result = window->RaiseToTop(window);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::createWindow: Unable to raise window ", result);
+ return false;
+ }
+
+ return true;
+}
+#endif
+
+void QDirectFBScreenCursor::move(int x, int y)
+{
+ pos = QPoint(x, y);
+#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
+ if (window) {
+ const QPoint p = pos - hotspot;
+ DFBResult result = window->MoveTo(window, p.x(), p.y());
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::move: Unable to move window", result);
+ }
+ }
+#else
+ layer->WarpCursor(layer, x, y);
+#endif
+}
+
+void QDirectFBScreenCursor::hide()
+{
+ if (enable) {
+ enable = false;
+ DFBResult result;
+#ifndef QT_DIRECTFB_WINDOW_AS_CURSOR
+ result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::hide: "
+ "Unable to set cooperative level", result);
+ }
+ result = layer->SetCursorOpacity(layer, 0);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::hide: "
+ "Unable to set cursor opacity", result);
+ }
+ result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::hide: "
+ "Unable to set cooperative level", result);
+ }
+#else
+ if (window) {
+ result = window->SetOpacity(window, 0);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::hide: "
+ "Unable to set window opacity", result);
+ }
+ }
+#endif
+ }
+}
+
+void QDirectFBScreenCursor::show()
+{
+ if (!enable) {
+ enable = true;
+ DFBResult result;
+ result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::show: "
+ "Unable to set cooperative level", result);
+ }
+ result = layer->SetCursorOpacity(layer,
+#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
+ 0
+#else
+ 255
+#endif
+ );
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::show: "
+ "Unable to set cursor shape", result);
+ }
+ result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::show: "
+ "Unable to set cooperative level", result);
+ }
+#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
+ if (window) {
+ DFBResult result = window->SetOpacity(window, 255);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::show: "
+ "Unable to set window opacity", result);
+ }
+ }
+#endif
+ }
+}
+
+void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty)
+{
+ QDirectFBScreen *screen = QDirectFBScreen::instance();
+ if (!screen)
+ return;
+
+ if (image.isNull()) {
+ cursor = QImage();
+ hide();
+ } else {
+ cursor = image.convertToFormat(screen->alphaPixmapFormat());
+ size = cursor.size();
+ hotspot = QPoint(hotx, hoty);
+ DFBResult result = DFB_OK;
+ IDirectFBSurface *surface = screen->createDFBSurface(cursor, screen->alphaPixmapFormat(),
+ QDirectFBScreen::DontTrackSurface, &result);
+ if (!surface) {
+ DirectFBError("QDirectFBScreenCursor::set: Unable to create surface", result);
+ return;
+ }
+#ifndef QT_DIRECTFB_WINDOW_AS_CURSOR
+ result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::show: "
+ "Unable to set cooperative level", result);
+ }
+ result = layer->SetCursorShape(layer, surface, hotx, hoty);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::show: "
+ "Unable to set cursor shape", result);
+ }
+ result = layer->SetCooperativeLevel(layer, DLSCL_SHARED);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::show: "
+ "Unable to set cooperative level", result);
+ }
+#else
+ if (window || createWindow()) {
+ QSize windowSize;
+ result = window->GetSize(window, &windowSize.rwidth(), &windowSize.rheight());
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: "
+ "Unable to get window size", result);
+ }
+ result = window->Resize(window, size.width(), size.height());
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: Unable to resize window", result);
+ }
+
+ IDirectFBSurface *windowSurface;
+ result = window->GetSurface(window, &windowSurface);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: Unable to get window surface", result);
+ } else {
+ result = windowSurface->Clear(windowSurface, 0, 0, 0, 0);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: Unable to clear surface", result);
+ }
+
+ result = windowSurface->Blit(windowSurface, surface, 0, 0, 0);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: Unable to blit to surface", result);
+ }
+ }
+ result = windowSurface->Flip(windowSurface, 0, DSFLIP_NONE);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::set: Unable to flip window", result);
+ }
+
+ windowSurface->Release(windowSurface);
+ }
+#endif
+ surface->Release(surface);
+ show();
+ }
+
+}
+#endif // QT_DIRECTFB_CURSOR
+
+QDirectFBScreen::QDirectFBScreen(int display_id)
+ : QScreen(display_id, DirectFBClass), d_ptr(new QDirectFBScreenPrivate(this))
+{
+ QDirectFBScreenPrivate::instance = this;
+}
+
+QDirectFBScreen::~QDirectFBScreen()
+{
+ if (QDirectFBScreenPrivate::instance == this)
+ QDirectFBScreenPrivate::instance = 0;
+ delete d_ptr;
+}
+
+QDirectFBScreen *QDirectFBScreen::instance()
+{
+ return QDirectFBScreenPrivate::instance;
+}
+
+int QDirectFBScreen::depth(DFBSurfacePixelFormat format)
+{
+ switch (format) {
+ case DSPF_A1:
+ return 1;
+ case DSPF_A8:
+ case DSPF_RGB332:
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ return 8;
+ case DSPF_I420:
+ case DSPF_YV12:
+ case DSPF_NV12:
+ case DSPF_NV21:
+#if (Q_DIRECTFB_VERSION >= 0x010100)
+ case DSPF_RGB444:
+#endif
+ return 12;
+#if (Q_DIRECTFB_VERSION >= 0x010100)
+ case DSPF_RGB555:
+ return 15;
+#endif
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ case DSPF_NV16:
+ case DSPF_ARGB2554:
+ case DSPF_ARGB4444:
+ return 16;
+ case DSPF_RGB24:
+ return 24;
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_AiRGB:
+ return 32;
+ case DSPF_UNKNOWN:
+ default:
+ return 0;
+ };
+ return 0;
+}
+
+int QDirectFBScreen::depth(QImage::Format format)
+{
+ int depth = 0;
+ switch(format) {
+ case QImage::Format_Invalid:
+ case QImage::NImageFormats:
+ Q_ASSERT(false);
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ depth = 1;
+ break;
+ case QImage::Format_Indexed8:
+ depth = 8;
+ break;
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
+ case QImage::Format_ARGB32_Premultiplied:
+ depth = 32;
+ break;
+ case QImage::Format_RGB555:
+ case QImage::Format_RGB16:
+ case QImage::Format_RGB444:
+ case QImage::Format_ARGB4444_Premultiplied:
+ depth = 16;
+ break;
+ case QImage::Format_RGB666:
+ case QImage::Format_ARGB6666_Premultiplied:
+ case QImage::Format_ARGB8565_Premultiplied:
+ case QImage::Format_ARGB8555_Premultiplied:
+ case QImage::Format_RGB888:
+ depth = 24;
+ break;
+ }
+ return depth;
+}
+
+void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args)
+{
+ QRegExp flipRegexp(QLatin1String("^flip=([\\w,]*)$"));
+ int index = args.indexOf(flipRegexp);
+ if (index >= 0) {
+ const QStringList flips = flipRegexp.cap(1).split(QLatin1Char(','),
+ QString::SkipEmptyParts);
+ flipFlags = DSFLIP_NONE;
+ foreach(const QString &flip, flips) {
+ if (flip == QLatin1String("wait"))
+ flipFlags |= DSFLIP_WAIT;
+ else if (flip == QLatin1String("blit"))
+ flipFlags |= DSFLIP_BLIT;
+ else if (flip == QLatin1String("onsync"))
+ flipFlags |= DSFLIP_ONSYNC;
+ else if (flip == QLatin1String("pipeline"))
+ flipFlags |= DSFLIP_PIPELINE;
+ else
+ qWarning("QDirectFBScreen: Unknown flip argument: %s",
+ qPrintable(flip));
+ }
+ } else {
+ flipFlags = DSFLIP_BLIT|DSFLIP_ONSYNC;
+ }
+}
+
+#ifdef QT_DIRECTFB_WM
+void QDirectFBScreenPrivate::onWindowEvent(QWSWindow *window, QWSServer::WindowEvent event)
+{
+ if (event == QWSServer::Raise) {
+ QWSWindowSurface *windowSurface = window->windowSurface();
+ if (windowSurface && windowSurface->key() == QLatin1String("directfb")) {
+ static_cast<QDirectFBWindowSurface*>(windowSurface)->raise();
+ }
+ }
+}
+#endif
+
+QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType type) const
+{
+ if (type == QPixmapData::BitmapType)
+ return QWSGraphicsSystem::createPixmapData(type);
+
+ return new QDirectFBPixmapData(q, type);
+}
+
+#if (Q_DIRECTFB_VERSION >= 0x000923)
+#ifdef QT_NO_DEBUG
+struct FlagDescription;
+static const FlagDescription *accelerationDescriptions = 0;
+static const FlagDescription *blitDescriptions = 0;
+static const FlagDescription *drawDescriptions = 0;
+#else
+struct FlagDescription {
+ const char *name;
+ uint flag;
+};
+
+static const FlagDescription accelerationDescriptions[] = {
+ { "DFXL_NONE", DFXL_NONE },
+ { "DFXL_FILLRECTANGLE", DFXL_FILLRECTANGLE },
+ { "DFXL_DRAWRECTANGLE", DFXL_DRAWRECTANGLE },
+ { "DFXL_DRAWLINE", DFXL_DRAWLINE },
+ { "DFXL_FILLTRIANGLE", DFXL_FILLTRIANGLE },
+ { "DFXL_BLIT", DFXL_BLIT },
+ { "DFXL_STRETCHBLIT", DFXL_STRETCHBLIT },
+ { "DFXL_TEXTRIANGLES", DFXL_TEXTRIANGLES },
+ { "DFXL_DRAWSTRING", DFXL_DRAWSTRING },
+ { 0, 0 }
+};
+
+static const FlagDescription blitDescriptions[] = {
+ { "DSBLIT_NOFX", DSBLIT_NOFX },
+ { "DSBLIT_BLEND_ALPHACHANNEL", DSBLIT_BLEND_ALPHACHANNEL },
+ { "DSBLIT_BLEND_COLORALPHA", DSBLIT_BLEND_COLORALPHA },
+ { "DSBLIT_COLORIZE", DSBLIT_COLORIZE },
+ { "DSBLIT_SRC_COLORKEY", DSBLIT_SRC_COLORKEY },
+ { "DSBLIT_DST_COLORKEY", DSBLIT_DST_COLORKEY },
+ { "DSBLIT_SRC_PREMULTIPLY", DSBLIT_SRC_PREMULTIPLY },
+ { "DSBLIT_DST_PREMULTIPLY", DSBLIT_DST_PREMULTIPLY },
+ { "DSBLIT_DEMULTIPLY", DSBLIT_DEMULTIPLY },
+ { "DSBLIT_DEINTERLACE", DSBLIT_DEINTERLACE },
+#if (Q_DIRECTFB_VERSION >= 0x000923)
+ { "DSBLIT_SRC_PREMULTCOLOR", DSBLIT_SRC_PREMULTCOLOR },
+ { "DSBLIT_XOR", DSBLIT_XOR },
+#endif
+#if (Q_DIRECTFB_VERSION >= 0x010000)
+ { "DSBLIT_INDEX_TRANSLATION", DSBLIT_INDEX_TRANSLATION },
+#endif
+ { 0, 0 }
+};
+
+static const FlagDescription drawDescriptions[] = {
+ { "DSDRAW_NOFX", DSDRAW_NOFX },
+ { "DSDRAW_BLEND", DSDRAW_BLEND },
+ { "DSDRAW_DST_COLORKEY", DSDRAW_DST_COLORKEY },
+ { "DSDRAW_SRC_PREMULTIPLY", DSDRAW_SRC_PREMULTIPLY },
+ { "DSDRAW_DST_PREMULTIPLY", DSDRAW_DST_PREMULTIPLY },
+ { "DSDRAW_DEMULTIPLY", DSDRAW_DEMULTIPLY },
+ { "DSDRAW_XOR", DSDRAW_XOR },
+ { 0, 0 }
+};
+#endif
+
+static const QByteArray flagDescriptions(uint mask, const FlagDescription *flags)
+{
+#ifdef QT_NO_DEBUG
+ Q_UNUSED(mask);
+ Q_UNUSED(flags);
+ return QByteArray("");
+#else
+ if (!mask)
+ return flags[0].name;
+
+ QStringList list;
+ for (int i=1; flags[i].name; ++i) {
+ if (mask & flags[i].flag) {
+ list.append(QString::fromLatin1(flags[i].name));
+ }
+ }
+ Q_ASSERT(!list.isEmpty());
+ return (QLatin1Char(' ') + list.join(QLatin1String("|"))).toLatin1();
+#endif
+}
+static void printDirectFBInfo(IDirectFB *fb, IDirectFBSurface *primarySurface)
+{
+ DFBResult result;
+ DFBGraphicsDeviceDescription dev;
+
+ result = fb->GetDeviceDescription(fb, &dev);
+ if (result != DFB_OK) {
+ DirectFBError("Error reading graphics device description", result);
+ return;
+ }
+
+ DFBSurfacePixelFormat pixelFormat;
+ primarySurface->GetPixelFormat(primarySurface, &pixelFormat);
+
+ qDebug("Device: %s (%s), Driver: %s v%i.%i (%s) Pixelformat: %d (%d)\n"
+ "acceleration: 0x%x%s\nblit: 0x%x%s\ndraw: 0x%0x%s\nvideo: %iKB\n",
+ dev.name, dev.vendor, dev.driver.name, dev.driver.major,
+ dev.driver.minor, dev.driver.vendor, DFB_PIXELFORMAT_INDEX(pixelFormat),
+ QDirectFBScreen::getImageFormat(primarySurface), dev.acceleration_mask,
+ flagDescriptions(dev.acceleration_mask, accelerationDescriptions).constData(),
+ dev.blitting_flags, flagDescriptions(dev.blitting_flags, blitDescriptions).constData(),
+ dev.drawing_flags, flagDescriptions(dev.drawing_flags, drawDescriptions).constData(),
+ (dev.video_memory >> 10));
+}
+#endif
+
+static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value)
+{
+ Q_ASSERT(value);
+ QRegExp rx(QString::fromLatin1("%1=?(\\d+)").arg(variable));
+ rx.setCaseSensitivity(Qt::CaseInsensitive);
+ if (arguments.indexOf(rx) != -1) {
+ *value = rx.cap(1).toInt();
+ return true;
+ }
+ return false;
+}
+
+static inline QColor colorFromName(const QString &name)
+{
+ 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])"));
+ rx.setCaseSensitivity(Qt::CaseInsensitive);
+ if (rx.exactMatch(name)) {
+ Q_ASSERT(rx.captureCount() == 4);
+ int ints[4];
+ int i;
+ for (i=0; i<4; ++i) {
+ bool ok;
+ ints[i] = rx.cap(i + 1).toUInt(&ok, 16);
+ if (!ok || ints[i] > 255)
+ break;
+ }
+ if (i == 4)
+ return QColor(ints[0], ints[1], ints[2], ints[3]);
+ }
+ return QColor(name);
+}
+
+bool QDirectFBScreen::connect(const QString &displaySpec)
+{
+ DFBResult result = DFB_OK;
+
+ { // pass command line arguments to DirectFB
+ const QStringList args = QCoreApplication::arguments();
+ int argc = args.size();
+ char **argv = new char*[argc];
+
+ for (int i = 0; i < argc; ++i)
+ argv[i] = qstrdup(args.at(i).toLocal8Bit().constData());
+
+ result = DirectFBInit(&argc, &argv);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen: error initializing DirectFB",
+ result);
+ }
+ delete[] argv;
+ }
+
+ const QStringList displayArgs = displaySpec.split(QLatin1Char(':'),
+ QString::SkipEmptyParts);
+
+ d_ptr->setFlipFlags(displayArgs);
+
+ result = DirectFBCreate(&d_ptr->dfb);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen: error creating DirectFB interface",
+ result);
+ return false;
+ }
+
+ if (displayArgs.contains(QLatin1String("videoonly"), Qt::CaseInsensitive))
+ d_ptr->directFBFlags |= VideoOnly;
+
+ if (displayArgs.contains(QLatin1String("systemonly"), Qt::CaseInsensitive)) {
+ if (d_ptr->directFBFlags & VideoOnly) {
+ qWarning("QDirectFBScreen: error. videoonly and systemonly are mutually exclusive");
+ } else {
+ d_ptr->directFBFlags |= SystemOnly;
+ }
+ }
+
+ if (displayArgs.contains(QLatin1String("boundingrectflip"), Qt::CaseInsensitive)) {
+ d_ptr->directFBFlags |= BoundingRectFlip;
+ } else if (displayArgs.contains(QLatin1String("nopartialflip"), Qt::CaseInsensitive)) {
+ d_ptr->directFBFlags |= NoPartialFlip;
+ }
+
+#ifdef QT_DIRECTFB_IMAGECACHE
+ int imageCacheSize = 4 * 1024 * 1024; // 4 MB
+ setIntOption(displayArgs, QLatin1String("imagecachesize"), &imageCacheSize);
+ QDirectFBPaintEngine::initImageCache(imageCacheSize);
+#endif
+
+#ifndef QT_NO_DIRECTFB_WM
+ if (displayArgs.contains(QLatin1String("fullscreen")))
+#endif
+ d_ptr->dfb->SetCooperativeLevel(d_ptr->dfb, DFSCL_FULLSCREEN);
+
+ const bool forcePremultiplied = displayArgs.contains(QLatin1String("forcepremultiplied"), Qt::CaseInsensitive);
+
+ DFBSurfaceDescription description;
+ memset(&description, 0, sizeof(DFBSurfaceDescription));
+ IDirectFBSurface *surface;
+
+#ifdef QT_NO_DIRECTFB_WM
+ description.flags = DSDESC_CAPS;
+ if (::setIntOption(displayArgs, QLatin1String("width"), &description.width))
+ description.flags |= DSDESC_WIDTH;
+ if (::setIntOption(displayArgs, QLatin1String("height"), &description.height))
+ description.flags |= DSDESC_HEIGHT;
+
+ description.caps = DSCAPS_PRIMARY|DSCAPS_DOUBLE;
+ struct {
+ const char *name;
+ const DFBSurfaceCapabilities cap;
+ } const capabilities[] = {
+ { "static_alloc", DSCAPS_STATIC_ALLOC },
+ { "triplebuffer", DSCAPS_TRIPLE },
+ { "interlaced", DSCAPS_INTERLACED },
+ { "separated", DSCAPS_SEPARATED },
+// { "depthbuffer", DSCAPS_DEPTH }, // only makes sense with TextureTriangles which are not supported
+ { 0, DSCAPS_NONE }
+ };
+ for (int i=0; capabilities[i].name; ++i) {
+ if (displayArgs.contains(QString::fromLatin1(capabilities[i].name), Qt::CaseInsensitive))
+ description.caps |= capabilities[i].cap;
+ }
+
+ if (forcePremultiplied) {
+ description.caps |= DSCAPS_PREMULTIPLIED;
+ }
+
+ // We don't track the primary surface as it's released in disconnect
+ d_ptr->primarySurface = createDFBSurface(description, DontTrackSurface, &result);
+ if (!d_ptr->primarySurface) {
+ DirectFBError("QDirectFBScreen: error creating primary surface",
+ result);
+ return false;
+ }
+
+ surface = d_ptr->primarySurface;
+#else
+ description.flags = DSDESC_WIDTH|DSDESC_HEIGHT;
+ description.width = description.height = 1;
+ surface = createDFBSurface(description, DontTrackSurface, &result);
+ if (!surface) {
+ DirectFBError("QDirectFBScreen: error creating surface", result);
+ return false;
+ }
+#endif
+ // Work out what format we're going to use for surfaces with an alpha channel
+ QImage::Format pixelFormat = QDirectFBScreen::getImageFormat(surface);
+ d_ptr->alphaPixmapFormat = pixelFormat;
+
+ switch (pixelFormat) {
+ case QImage::Format_RGB666:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied;
+ break;
+ case QImage::Format_RGB444:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB4444_Premultiplied;
+ break;
+ case QImage::Format_RGB32:
+ pixelFormat = d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
+ // ### Format_RGB32 doesn't work so well with Qt. Force ARGB32 for windows/pixmaps
+ break;
+ case QImage::Format_Indexed8:
+ qWarning("QDirectFBScreen::connect(). Qt/DirectFB does not work with the LUT8 pixelformat.");
+ return false;
+ case QImage::NImageFormats:
+ case QImage::Format_Invalid:
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ case QImage::Format_RGB888:
+ case QImage::Format_RGB16:
+ case QImage::Format_RGB555:
+ d_ptr->alphaPixmapFormat = QImage::Format_ARGB32_Premultiplied;
+ break;
+ case QImage::Format_ARGB32:
+ if (forcePremultiplied)
+ d_ptr->alphaPixmapFormat = pixelFormat = QImage::Format_ARGB32_Premultiplied;
+ case QImage::Format_ARGB32_Premultiplied:
+ case QImage::Format_ARGB4444_Premultiplied:
+ case QImage::Format_ARGB8555_Premultiplied:
+ case QImage::Format_ARGB8565_Premultiplied:
+ case QImage::Format_ARGB6666_Premultiplied:
+ // works already
+ break;
+ }
+ setPixelFormat(pixelFormat);
+ QScreen::d = QDirectFBScreen::depth(pixelFormat);
+ data = 0;
+ lstep = 0;
+ size = 0;
+
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::connect: "
+ "Unable to get screen!", result);
+ return false;
+ }
+ const QString qws_size = QString::fromLatin1(qgetenv("QWS_SIZE"));
+ if (!qws_size.isEmpty()) {
+ QRegExp rx(QLatin1String("(\\d+)x(\\d+)"));
+ if (!rx.exactMatch(qws_size)) {
+ qWarning("QDirectFBScreen::connect: Can't parse QWS_SIZE=\"%s\"", qPrintable(qws_size));
+ } else {
+ int *ints[2] = { &w, &h };
+ for (int i=0; i<2; ++i) {
+ *ints[i] = rx.cap(i + 1).toInt();
+ if (*ints[i] <= 0) {
+ qWarning("QDirectFBScreen::connect: %s is not a positive integer",
+ qPrintable(rx.cap(i + 1)));
+ w = h = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ setIntOption(displayArgs, QLatin1String("width"), &w);
+ setIntOption(displayArgs, QLatin1String("height"), &h);
+
+#ifndef QT_NO_DIRECTFB_LAYER
+ int layerId = DLID_PRIMARY;
+ setIntOption(displayArgs, QLatin1String("layerid"), &layerId);
+
+ result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, static_cast<DFBDisplayLayerID>(layerId),
+ &d_ptr->dfbLayer);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::connect: "
+ "Unable to get display layer!", result);
+ return false;
+ }
+ result = d_ptr->dfbLayer->GetScreen(d_ptr->dfbLayer, &d_ptr->dfbScreen);
+#else
+ result = d_ptr->dfb->GetScreen(d_ptr->dfb, 0, &d_ptr->dfbScreen);
+#endif
+
+ if (w <= 0 || h <= 0) {
+#ifdef QT_NO_DIRECTFB_WM
+ result = d_ptr->primarySurface->GetSize(d_ptr->primarySurface, &w, &h);
+#elif (Q_DIRECTFB_VERSION >= 0x010000)
+ IDirectFBSurface *layerSurface;
+ if (d_ptr->dfbLayer->GetSurface(d_ptr->dfbLayer, &layerSurface) == DFB_OK) {
+ result = layerSurface->GetSize(layerSurface, &w, &h);
+ layerSurface->Release(layerSurface);
+ }
+ if (w <= 0 || h <= 0) {
+ result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h);
+ }
+#else
+ qWarning("QDirectFBScreen::connect: DirectFB versions prior to 1.0 do not offer a way\n"
+ "query the size of the primary surface in windowed mode. You have to specify\n"
+ "the size of the display using QWS_SIZE=[0-9]x[0-9] or\n"
+ "QWS_DISPLAY=directfb:width=[0-9]:height=[0-9]");
+ return false;
+#endif
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::connect: "
+ "Unable to get screen size!", result);
+ return false;
+ }
+ }
+
+
+ dw = w;
+ dh = h;
+
+ Q_ASSERT(dw != 0 && dh != 0);
+
+ physWidth = physHeight = -1;
+ setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth);
+ setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight);
+ const int dpi = 72;
+ if (physWidth < 0)
+ physWidth = qRound(dw * 25.4 / dpi);
+ if (physHeight < 0)
+ physHeight = qRound(dh * 25.4 / dpi);
+
+ setGraphicsSystem(d_ptr);
+
+#if (Q_DIRECTFB_VERSION >= 0x000923)
+ if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive))
+ printDirectFBInfo(d_ptr->dfb, surface);
+#endif
+#ifdef QT_DIRECTFB_WM
+ surface->Release(surface);
+ QColor backgroundColor;
+#else
+ QColor &backgroundColor = d_ptr->backgroundColor;
+#endif
+
+ QRegExp backgroundColorRegExp(QLatin1String("bgcolor=(.+)"));
+ backgroundColorRegExp.setCaseSensitivity(Qt::CaseInsensitive);
+ if (displayArgs.indexOf(backgroundColorRegExp) != -1) {
+ backgroundColor = colorFromName(backgroundColorRegExp.cap(1));
+ }
+#ifdef QT_NO_DIRECTFB_WM
+ if (!backgroundColor.isValid())
+ backgroundColor = Qt::green;
+ d_ptr->primarySurface->Clear(d_ptr->primarySurface, backgroundColor.red(),
+ backgroundColor.green(), backgroundColor.blue(),
+ backgroundColor.alpha());
+ d_ptr->primarySurface->Flip(d_ptr->primarySurface, 0, d_ptr->flipFlags);
+#else
+ if (backgroundColor.isValid()) {
+ DFBResult result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_ADMINISTRATIVE);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::connect "
+ "Unable to set cooperative level", result);
+ }
+ result = d_ptr->dfbLayer->SetBackgroundColor(d_ptr->dfbLayer, backgroundColor.red(), backgroundColor.green(),
+ backgroundColor.blue(), backgroundColor.alpha());
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::connect: "
+ "Unable to set background color", result);
+ }
+
+ result = d_ptr->dfbLayer->SetBackgroundMode(d_ptr->dfbLayer, DLBM_COLOR);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreenCursor::connect: "
+ "Unable to set background mode", result);
+ }
+
+ result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_SHARED);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::connect "
+ "Unable to set cooperative level", result);
+ }
+
+ }
+#endif
+
+ return true;
+}
+
+void QDirectFBScreen::disconnect()
+{
+#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ if (d_ptr->imageProvider)
+ d_ptr->imageProvider->Release(d_ptr->imageProvider);
+#endif
+#ifdef QT_NO_DIRECTFB_WM
+ d_ptr->primarySurface->Release(d_ptr->primarySurface);
+ d_ptr->primarySurface = 0;
+#endif
+
+ foreach (IDirectFBSurface *surf, d_ptr->allocatedSurfaces)
+ surf->Release(surf);
+ d_ptr->allocatedSurfaces.clear();
+
+#ifndef QT_NO_DIRECTFB_LAYER
+ d_ptr->dfbLayer->Release(d_ptr->dfbLayer);
+ d_ptr->dfbLayer = 0;
+#endif
+
+ d_ptr->dfbScreen->Release(d_ptr->dfbScreen);
+ d_ptr->dfbScreen = 0;
+
+ d_ptr->dfb->Release(d_ptr->dfb);
+ d_ptr->dfb = 0;
+}
+
+bool QDirectFBScreen::initDevice()
+{
+#ifndef QT_NO_DIRECTFB_MOUSE
+ if (qgetenv("QWS_MOUSE_PROTO").isEmpty()) {
+ QWSServer::instance()->setDefaultMouse("None");
+ d_ptr->mouse = new QDirectFBMouseHandler;
+ }
+#endif
+#ifndef QT_NO_DIRECTFB_KEYBOARD
+ if (qgetenv("QWS_KEYBOARD").isEmpty()) {
+ QWSServer::instance()->setDefaultKeyboard("None");
+ d_ptr->keyboard = new QDirectFBKeyboardHandler(QString());
+ }
+#endif
+
+#ifdef QT_DIRECTFB_CURSOR
+ qt_screencursor = new QDirectFBScreenCursor;
+#elif !defined QT_NO_QWS_CURSOR
+ QScreenCursor::initSoftwareCursor();
+#endif
+ return true;
+}
+
+void QDirectFBScreen::shutdownDevice()
+{
+#ifndef QT_NO_DIRECTFB_MOUSE
+ delete d_ptr->mouse;
+ d_ptr->mouse = 0;
+#endif
+#ifndef QT_NO_DIRECTFB_KEYBOARD
+ delete d_ptr->keyboard;
+ d_ptr->keyboard = 0;
+#endif
+
+#ifndef QT_NO_QWS_CURSOR
+ delete qt_screencursor;
+ qt_screencursor = 0;
+#endif
+}
+
+void QDirectFBScreen::setMode(int width, int height, int depth)
+{
+ d_ptr->dfb->SetVideoMode(d_ptr->dfb, width, height, depth);
+}
+
+void QDirectFBScreen::blank(bool on)
+{
+ d_ptr->dfbScreen->SetPowerMode(d_ptr->dfbScreen,
+ (on ? DSPM_ON : DSPM_SUSPEND));
+}
+
+QWSWindowSurface *QDirectFBScreen::createSurface(QWidget *widget) const
+{
+#ifdef QT_NO_DIRECTFB_WM
+ if (QApplication::type() == QApplication::GuiServer) {
+ return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
+ } else {
+ return QScreen::createSurface(widget);
+ }
+#else
+ return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this), widget);
+#endif
+}
+
+QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const
+{
+ if (key == QLatin1String("directfb")) {
+ return new QDirectFBWindowSurface(d_ptr->flipFlags, const_cast<QDirectFBScreen*>(this));
+ }
+ return QScreen::createSurface(key);
+}
+
+#if defined QT_NO_DIRECTFB_WM
+struct PaintCommand {
+ PaintCommand() : dfbSurface(0), windowOpacity(255), blittingFlags(DSBLIT_NOFX) {}
+ IDirectFBSurface *dfbSurface;
+ QImage image;
+ QPoint windowPosition;
+ QRegion source;
+ quint8 windowOpacity;
+ DFBSurfaceBlittingFlags blittingFlags;
+};
+
+static inline void initParameters(DFBRectangle &source, const QRect &sourceGlobal, const QPoint &pos)
+{
+ source.x = sourceGlobal.x() - pos.x();
+ source.y = sourceGlobal.y() - pos.y();
+ source.w = sourceGlobal.width();
+ source.h = sourceGlobal.height();
+}
+#endif
+
+void QDirectFBScreen::exposeRegion(QRegion r, int)
+{
+ Q_UNUSED(r);
+#if defined QT_NO_DIRECTFB_WM
+
+ r &= region();
+ if (r.isEmpty()) {
+ return;
+ }
+ r = r.boundingRect();
+
+ IDirectFBSurface *primary = d_ptr->primarySurface;
+ const QList<QWSWindow*> windows = QWSServer::instance()->clientWindows();
+ QVarLengthArray<PaintCommand, 4> commands(windows.size());
+ QRegion region = r;
+ int idx = 0;
+ for (int i=0; i<windows.size(); ++i) {
+ QWSWindowSurface *surface = windows.at(i)->windowSurface();
+ if (!surface)
+ continue;
+
+ const QRect windowGeometry = surface->geometry();
+ const QRegion intersection = region & windowGeometry;
+ if (intersection.isEmpty()) {
+ continue;
+ }
+
+ PaintCommand &cmd = commands[idx];
+
+ if (surface->key() == QLatin1String("directfb")) {
+ const QDirectFBWindowSurface *ws = static_cast<QDirectFBWindowSurface*>(surface);
+ cmd.dfbSurface = ws->directFBSurface();
+
+ if (!cmd.dfbSurface) {
+ continue;
+ }
+ } else {
+ cmd.image = surface->image();
+ if (cmd.image.isNull()) {
+ continue;
+ }
+ }
+ ++idx;
+
+ cmd.windowPosition = windowGeometry.topLeft();
+ cmd.source = intersection;
+ if (windows.at(i)->isOpaque()) {
+ region -= intersection;
+ if (region.isEmpty())
+ break;
+ } else {
+ cmd.windowOpacity = windows.at(i)->opacity();
+ cmd.blittingFlags = cmd.windowOpacity == 255
+ ? DSBLIT_BLEND_ALPHACHANNEL
+ : (DSBLIT_BLEND_ALPHACHANNEL|DSBLIT_BLEND_COLORALPHA);
+ }
+ }
+
+ solidFill(d_ptr->backgroundColor, region);
+
+ while (idx > 0) {
+ const PaintCommand &cmd = commands[--idx];
+ Q_ASSERT(cmd.dfbSurface || !cmd.image.isNull());
+ IDirectFBSurface *surface;
+ if (cmd.dfbSurface) {
+ surface = cmd.dfbSurface;
+ } else {
+ Q_ASSERT(!cmd.image.isNull());
+ DFBResult result;
+ surface = createDFBSurface(cmd.image, cmd.image.format(), DontTrackSurface, &result);
+ Q_ASSERT((result != DFB_OK) == !surface);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::exposeRegion: Can't create surface from image", result);
+ continue;
+ }
+ }
+
+ primary->SetBlittingFlags(primary, cmd.blittingFlags);
+ if (cmd.blittingFlags & DSBLIT_BLEND_COLORALPHA) {
+ primary->SetColor(primary, 0xff, 0xff, 0xff, cmd.windowOpacity);
+ }
+ const QRegion &region = cmd.source;
+ const int rectCount = region.rectCount();
+ DFBRectangle source;
+ if (rectCount == 1) {
+ ::initParameters(source, region.boundingRect(), cmd.windowPosition);
+ primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y);
+ } else {
+ const QVector<QRect> rects = region.rects();
+ for (int i=0; i<rectCount; ++i) {
+ ::initParameters(source, rects.at(i), cmd.windowPosition);
+ primary->Blit(primary, surface, &source, cmd.windowPosition.x() + source.x, cmd.windowPosition.y() + source.y);
+ }
+ }
+ if (surface != cmd.dfbSurface) {
+ surface->Release(surface);
+ }
+ }
+
+ primary->SetColor(primary, 0xff, 0xff, 0xff, 0xff);
+
+#if defined QT_NO_DIRECTFB_CURSOR and !defined QT_NO_QWS_CURSOR
+ if (QScreenCursor *cursor = QScreenCursor::instance()) {
+ const QRect cursorRectangle = cursor->boundingRect();
+ if (cursor->isVisible() && !cursor->isAccelerated() && r.intersects(cursorRectangle)) {
+ const QImage image = cursor->image();
+ if (image.cacheKey() != d_ptr->cursorImageKey) {
+ if (d_ptr->cursorSurface) {
+ releaseDFBSurface(d_ptr->cursorSurface);
+ }
+ d_ptr->cursorSurface = createDFBSurface(image, image.format(), QDirectFBScreen::TrackSurface);
+ d_ptr->cursorImageKey = image.cacheKey();
+ }
+
+ Q_ASSERT(d_ptr->cursorSurface);
+ primary->SetBlittingFlags(primary, DSBLIT_BLEND_ALPHACHANNEL);
+ primary->Blit(primary, d_ptr->cursorSurface, 0, cursorRectangle.x(), cursorRectangle.y());
+ }
+ }
+#endif
+ flipSurface(primary, d_ptr->flipFlags, r, QPoint());
+ primary->SetBlittingFlags(primary, DSBLIT_NOFX);
+#endif
+}
+
+void QDirectFBScreen::solidFill(const QColor &color, const QRegion &region)
+{
+#ifdef QT_DIRECTFB_WM
+ Q_UNUSED(color);
+ Q_UNUSED(region);
+#else
+ QDirectFBScreen::solidFill(d_ptr->primarySurface, color, region);
+#endif
+}
+
+static inline void clearRect(IDirectFBSurface *surface, const QColor &color, const QRect &rect)
+{
+ Q_ASSERT(surface);
+ const DFBRegion region = { rect.left(), rect.top(), rect.right(), rect.bottom() };
+ // could just reinterpret_cast this to a DFBRegion
+ surface->SetClip(surface, &region);
+ surface->Clear(surface, color.red(), color.green(), color.blue(), color.alpha());
+}
+
+void QDirectFBScreen::solidFill(IDirectFBSurface *surface, const QColor &color, const QRegion &region)
+{
+ if (region.isEmpty())
+ return;
+
+ const int n = region.rectCount();
+ if (n == 1) {
+ clearRect(surface, color, region.boundingRect());
+ } else {
+ const QVector<QRect> rects = region.rects();
+ for (int i=0; i<n; ++i) {
+ clearRect(surface, color, rects.at(i));
+ }
+ }
+ surface->SetClip(surface, 0);
+}
+
+QImage::Format QDirectFBScreen::alphaPixmapFormat() const
+{
+ return d_ptr->alphaPixmapFormat;
+}
+
+bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description,
+ QImage::Format format)
+{
+ const DFBSurfacePixelFormat pixelformat = QDirectFBScreen::getSurfacePixelFormat(format);
+ if (pixelformat == DSPF_UNKNOWN)
+ return false;
+ description->flags |= DSDESC_PIXELFORMAT;
+ description->pixelformat = pixelformat;
+ if (QDirectFBScreen::isPremultiplied(format)) {
+ if (!(description->flags & DSDESC_CAPS)) {
+ description->caps = DSCAPS_PREMULTIPLIED;
+ description->flags |= DSDESC_CAPS;
+ } else {
+ description->caps |= DSCAPS_PREMULTIPLIED;
+ }
+ }
+ return true;
+}
+
+uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl)
+{
+ void *mem = 0;
+ const DFBResult result = surface->Lock(surface, flags, &mem, bpl);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::lockSurface()", result);
+ }
+
+ return reinterpret_cast<uchar*>(mem);
+}
+
+static inline bool isFullUpdate(IDirectFBSurface *surface, const QRegion &region, const QPoint &offset)
+{
+ if (offset == QPoint(0, 0) && region.rectCount() == 1) {
+ QSize size;
+ surface->GetSize(surface, &size.rwidth(), &size.rheight());
+ if (region.boundingRect().size() == size)
+ return true;
+ }
+ return false;
+}
+
+void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags,
+ const QRegion &region, const QPoint &offset)
+{
+ if (d_ptr->directFBFlags & NoPartialFlip
+ || (!(flipFlags & DSFLIP_BLIT) && QT_PREPEND_NAMESPACE(isFullUpdate(surface, region, offset)))) {
+ surface->Flip(surface, 0, flipFlags);
+ } else {
+ if (!(d_ptr->directFBFlags & BoundingRectFlip) && region.rectCount() > 1) {
+ const QVector<QRect> rects = region.rects();
+ const DFBSurfaceFlipFlags nonWaitFlags = flipFlags & ~DSFLIP_WAIT;
+ for (int i=0; i<rects.size(); ++i) {
+ const QRect &r = rects.at(i);
+ const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
+ r.right() + offset.x(),
+ r.bottom() + offset.y() };
+ surface->Flip(surface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags);
+ }
+ } else {
+ const QRect r = region.boundingRect();
+ const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(),
+ r.right() + offset.x(),
+ r.bottom() + offset.y() };
+ surface->Flip(surface, &dfbReg, flipFlags);
+ }
+ }
+}
+
+#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+void QDirectFBScreen::setDirectFBImageProvider(IDirectFBImageProvider *provider)
+{
+ Q_ASSERT(provider);
+ if (d_ptr->imageProvider)
+ d_ptr->imageProvider->Release(d_ptr->imageProvider);
+ d_ptr->imageProvider = provider;
+}
+#endif
+
+void QDirectFBScreen::waitIdle()
+{
+ d_ptr->dfb->WaitIdle(d_ptr->dfb);
+}
+
+#ifdef QT_DIRECTFB_WM
+IDirectFBWindow *QDirectFBScreen::windowForWidget(const QWidget *widget) const
+{
+ if (widget) {
+ const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
+ if (surface && surface->key() == QLatin1String("directfb")) {
+ return static_cast<const QDirectFBWindowSurface*>(surface)->directFBWindow();
+ }
+ }
+ return 0;
+}
+#endif
+
+IDirectFBSurface * QDirectFBScreen::surfaceForWidget(const QWidget *widget, QRect *rect) const
+{
+ Q_ASSERT(widget);
+ if (!widget->isVisible() || widget->size().isNull())
+ return 0;
+
+ const QWSWindowSurface *surface = static_cast<const QWSWindowSurface*>(widget->windowSurface());
+ if (surface && surface->key() == QLatin1String("directfb")) {
+ return static_cast<const QDirectFBWindowSurface*>(surface)->surfaceForWidget(widget, rect);
+ }
+ return 0;
+}
+
+#ifdef QT_DIRECTFB_SUBSURFACE
+IDirectFBSurface *QDirectFBScreen::subSurfaceForWidget(const QWidget *widget, const QRect &area) const
+{
+ Q_ASSERT(widget);
+ QRect rect;
+ IDirectFBSurface *surface = surfaceForWidget(widget, &rect);
+ IDirectFBSurface *subSurface = 0;
+ if (surface) {
+ if (!area.isNull())
+ rect &= area.translated(widget->mapTo(widget->window(), QPoint(0, 0)));
+ if (!rect.isNull()) {
+ const DFBRectangle subRect = { rect.x(), rect.y(), rect.width(), rect.height() };
+ const DFBResult result = surface->GetSubSurface(surface, &subRect, &subSurface);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBScreen::subSurface(): Can't get sub surface", result);
+ }
+ }
+ }
+ return subSurface;
+}
+#endif
+
+Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_widget(const QWidget *widget, QRect *rect)
+{
+ return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->surfaceForWidget(widget, rect) : 0;
+}
+#ifdef QT_DIRECTFB_SUBSURFACE
+Q_GUI_EXPORT IDirectFBSurface *qt_directfb_subsurface_for_widget(const QWidget *widget, const QRect &area)
+{
+ return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->subSurfaceForWidget(widget, area) : 0;
+}
+#endif
+#ifdef QT_DIRECTFB_WM
+Q_GUI_EXPORT IDirectFBWindow *qt_directfb_window_for_widget(const QWidget *widget)
+{
+ return QDirectFBScreen::instance() ? QDirectFBScreen::instance()->windowForWidget(widget) : 0;
+}
+
+#endif
+
+QT_END_NAMESPACE
+
+#include "qdirectfbscreen.moc"
+#endif // QT_NO_QWS_DIRECTFB
+