diff options
Diffstat (limited to 'src/plugins/gfxdrivers/directfb')
16 files changed, 1640 insertions, 947 deletions
diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro index 5c60b2f..0706f01 100644 --- a/src/plugins/gfxdrivers/directfb/directfb.pro +++ b/src/plugins/gfxdrivers/directfb/directfb.pro @@ -1,44 +1,15 @@ TARGET = qdirectfbscreen include(../../qpluginbase.pri) +include($$QT_SOURCE_TREE/src/gui/embedded/directfb.pri) QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers -# These defines might be necessary if your DirectFB driver doesn't -# support all of the DirectFB API. -# -#DEFINES += QT_DIRECTFB_IMAGECACHE -#DEFINES += QT_NO_DIRECTFB_WM -#DEFINES += QT_NO_DIRECTFB_LAYER -#DEFINES += QT_NO_DIRECTFB_PALETTE -#DEFINES += QT_NO_DIRECTFB_PREALLOCATED -#DEFINES += QT_NO_DIRECTFB_MOUSE -#DEFINES += QT_NO_DIRECTFB_KEYBOARD -#DEFINES += QT_DIRECTFB_TIMING -#DEFINES += QT_NO_DIRECTFB_OPAQUE_DETECTION -#DIRECTFB_DRAWINGOPERATIONS=DRAW_RECTS|DRAW_LINES|DRAW_IMAGE|DRAW_PIXMAP|DRAW_TILED_PIXMAP|STROKE_PATH|DRAW_PATH|DRAW_POINTS|DRAW_ELLIPSE|DRAW_POLYGON|DRAW_TEXT|FILL_PATH|FILL_RECT|DRAW_COLORSPANS -#DEFINES += \"QT_DIRECTFB_WARN_ON_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\" -#DEFINES += \"QT_DIRECTFB_DISABLE_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\" - target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers INSTALLS += target -HEADERS = qdirectfbscreen.h \ - qdirectfbwindowsurface.h \ - qdirectfbpaintengine.h \ - qdirectfbpaintdevice.h \ - qdirectfbpixmap.h \ - qdirectfbkeyboard.h \ - qdirectfbmouse.h - -SOURCES = qdirectfbscreen.cpp \ - qdirectfbscreenplugin.cpp \ - qdirectfbwindowsurface.cpp \ - qdirectfbpaintengine.cpp \ - qdirectfbpaintdevice.cpp \ - qdirectfbpixmap.cpp \ - qdirectfbkeyboard.cpp \ - qdirectfbmouse.cpp +SOURCES += qdirectfbscreenplugin.cpp QMAKE_CXXFLAGS += $$QT_CFLAGS_DIRECTFB LIBS += $$QT_LIBS_DIRECTFB -DEFINES += $$QT_DEFINES_DIRECTFB +DEFINES += $$QT_DEFINES_DIRECTFB QT_DIRECTFB_PLUGIN +contains(gfx-plugins, directfb):DEFINES += QT_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp index cd442a3..da5c5a5 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,28 +21,27 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qdirectfbkeyboard.h" -#ifndef QT_NO_DIRECTFB +#ifndef QT_NO_QWS_DIRECTFB #include "qdirectfbscreen.h" #include <qobject.h> @@ -53,6 +53,8 @@ #include <fcntl.h> #include <errno.h> +QT_BEGIN_NAMESPACE + class KeyMap : public QHash<DFBInputDeviceKeySymbol, Qt::Key> { public: @@ -429,6 +431,6 @@ KeyMap::KeyMap() insert(DIKS_TILDE , Qt::Key_AsciiTilde); } +QT_END_NAMESPACE #include "qdirectfbkeyboard.moc" - -#endif // QT_NO_DIRECTFB +#endif // QT_NO_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h index 5c724cb..b41748e 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,13 +42,16 @@ #ifndef QDIRECTFBKEYBOARD_H #define QDIRECTFBKEYBOARD_H +#include <qglobal.h> #include <QtGui/qkbd_qws.h> +#ifndef QT_NO_QWS_DIRECTFB + QT_BEGIN_HEADER -QT_MODULE(Gui) +QT_BEGIN_NAMESPACE -#ifndef QT_NO_DIRECTFB +QT_MODULE(Gui) class QDirectFBKeyboardHandlerPrivate; @@ -62,7 +65,9 @@ private: QDirectFBKeyboardHandlerPrivate *d; }; -#endif // QT_NO_DIRECTFB +QT_END_NAMESPACE + +#endif // QT_NO_QWS_DIRECTFB QT_END_HEADER diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp index 1391db8..8662df6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,27 +21,28 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qdirectfbmouse.h" +#ifndef QT_NO_QWS_DIRECTFB + #include "qdirectfbscreen.h" #include <qsocketnotifier.h> @@ -49,6 +51,8 @@ #include <fcntl.h> #include <errno.h> +QT_BEGIN_NAMESPACE + class QDirectFBMouseHandlerPrivate : public QObject { Q_OBJECT @@ -117,8 +121,8 @@ QDirectFBMouseHandlerPrivate::QDirectFBMouseHandlerPrivate(QDirectFBMouseHandler return; } - int flags = ::fcntl(fd, F_GETFL, 0); - ::fcntl(fd, F_SETFL, flags | O_NONBLOCK); + int flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); // DirectFB seems to assume that the mouse always starts centered prevPoint = QPoint(screen->deviceWidth() / 2, screen->deviceHeight() / 2); @@ -203,6 +207,7 @@ void QDirectFBMouseHandlerPrivate::readMouseData() int wheel = 0; if (input.type == DIET_AXISMOTION) { +#ifdef QT_NO_DIRECTFB_LAYER if (input.flags & DIEF_AXISABS) { switch (input.axis) { case DIAI_X: x = input.axisabs; break; @@ -222,6 +227,19 @@ void QDirectFBMouseHandlerPrivate::readMouseData() "unknown axis (releative) %d", input.axis); } } +#else + if (input.axis == DIAI_X || input.axis == DIAI_Y) { + DFBResult result = layer->GetCursorPosition(layer, &x, &y); + if (result != DFB_OK) { + DirectFBError("QDirectFBMouseHandler::readMouseData", + result); + } + } else if (input.axis == DIAI_Z) { + Q_ASSERT(input.flags & DIEF_AXISREL); + wheel = input.axisrel; + wheel *= -120; + } +#endif } Qt::MouseButtons buttons = Qt::NoButton; @@ -269,5 +287,8 @@ void QDirectFBMouseHandler::resume() d->setEnabled(true); } +QT_END_NAMESPACE #include "qdirectfbmouse.moc" +#endif // QT_NO_QWS_DIRECTFB + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h index dce949f..25790a3 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,13 +42,16 @@ #ifndef QDIRECTFBMOUSE_H #define QDIRECTFBMOUSE_H +#include <qglobal.h> #include <QtGui/qmouse_qws.h> +#ifndef QT_NO_QWS_DIRECTFB + QT_BEGIN_HEADER -QT_MODULE(Gui) +QT_BEGIN_NAMESPACE -#ifndef QT_NO_DIRECTFB +QT_MODULE(Gui) class QDirectFBMouseHandlerPrivate; @@ -65,8 +68,8 @@ protected: QDirectFBMouseHandlerPrivate *d; }; -#endif // QT_NO_DIRECTFB +QT_END_NAMESPACE QT_END_HEADER - +#endif // QT_NO_QWS_DIRECTFB #endif // QDIRECTFBMOUSE_H diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index d2fadcb..46cf65b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,102 +21,131 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef QT_NO_DIRECTFB - #include "qdirectfbscreen.h" #include "qdirectfbpaintdevice.h" #include "qdirectfbpaintengine.h" +#ifndef QT_NO_QWS_DIRECTFB + +QT_BEGIN_NAMESPACE + QDirectFBPaintDevice::QDirectFBPaintDevice(QDirectFBScreen *scr) - : QCustomRasterPaintDevice(0), dfbSurface(0), lockedImage(0), screen(scr), - lock(DFBSurfaceLockFlags(0)), mem(0), engine(0) -{} + : QCustomRasterPaintDevice(0), dfbSurface(0), screen(scr), + bpl(-1), lockFlgs(DFBSurfaceLockFlags(0)), mem(0), engine(0), imageFormat(QImage::Format_Invalid) +{ +#ifdef QT_DIRECTFB_SUBSURFACE + subSurface = 0; + syncPending = false; +#endif +} QDirectFBPaintDevice::~QDirectFBPaintDevice() { - delete lockedImage; + if (QDirectFBScreen::instance()) { + unlockSurface(); +#ifdef QT_DIRECTFB_SUBSURFACE + releaseSubSurface(); +#endif + if (dfbSurface) { + screen->releaseDFBSurface(dfbSurface); + } + } delete engine; } - IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const { return dfbSurface; } - -void QDirectFBPaintDevice::lockDirectFB(DFBSurfaceLockFlags flags) +bool QDirectFBPaintDevice::lockSurface(DFBSurfaceLockFlags lockFlags) { - if (!(lock & flags)) { - if (lock) - unlockDirectFB(); - mem = QDirectFBScreen::lockSurface(dfbSurface, flags, &bpl); + if (lockFlgs && (lockFlags & ~lockFlgs)) + unlockSurface(); + if (!mem) { + Q_ASSERT(dfbSurface); +#ifdef QT_DIRECTFB_SUBSURFACE + if (!subSurface) { + DFBResult result; + subSurface = screen->getSubSurface(dfbSurface, QRect(), QDirectFBScreen::TrackSurface, &result); + if (result != DFB_OK || !subSurface) { + DirectFBError("Couldn't create sub surface", result); + return false; + } + } + IDirectFBSurface *surface = subSurface; +#else + IDirectFBSurface *surface = dfbSurface; +#endif + Q_ASSERT(surface); + mem = QDirectFBScreen::lockSurface(surface, lockFlags, &bpl); + lockFlgs = lockFlags; Q_ASSERT(mem); + Q_ASSERT(bpl > 0); const QSize s = size(); - lockedImage = new QImage(mem, s.width(), s.height(), bpl, - QDirectFBScreen::getImageFormat(dfbSurface)); - lock = flags; + lockedImage = QImage(mem, s.width(), s.height(), bpl, + QDirectFBScreen::getImageFormat(dfbSurface)); + return true; } +#ifdef QT_DIRECTFB_SUBSURFACE + if (syncPending) { + syncPending = false; + screen->waitIdle(); + } +#endif + return false; } - -void QDirectFBPaintDevice::unlockDirectFB() +void QDirectFBPaintDevice::unlockSurface() { - if (!lockedImage || !QDirectFBScreen::instance()) - return; - - dfbSurface->Unlock(dfbSurface); - delete lockedImage; - lockedImage = 0; - mem = 0; - lock = DFBSurfaceLockFlags(0); + if (QDirectFBScreen::instance() && lockFlgs) { +#ifdef QT_DIRECTFB_SUBSURFACE + IDirectFBSurface *surface = subSurface; +#else + IDirectFBSurface *surface = dfbSurface; +#endif + if (surface) { + surface->Unlock(surface); + lockFlgs = static_cast<DFBSurfaceLockFlags>(0); + mem = 0; + } + } } - void *QDirectFBPaintDevice::memory() const { return mem; } - QImage::Format QDirectFBPaintDevice::format() const { - return QDirectFBScreen::getImageFormat(dfbSurface); + return imageFormat; } - int QDirectFBPaintDevice::bytesPerLine() const { - if (bpl == -1) { - // Can only get the stride when we lock the surface - Q_ASSERT(!lockedImage); - QDirectFBPaintDevice* that = const_cast<QDirectFBPaintDevice*>(this); - that->lockDirectFB(DSLF_READ); - Q_ASSERT(bpl != -1); - } + Q_ASSERT(!mem || bpl != -1); return bpl; } - QSize QDirectFBPaintDevice::size() const { int w, h; @@ -143,12 +173,10 @@ int QDirectFBPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const case QPaintDevice::PdmDpiY: return (dotsPerMeterY() * 254) / 10000; // 0.0254 meters-per-inch case QPaintDevice::PdmDepth: - DFBSurfacePixelFormat format; - dfbSurface->GetPixelFormat(dfbSurface, &format); - return QDirectFBScreen::depth(format); + return QDirectFBScreen::depth(imageFormat); case QPaintDevice::PdmNumColors: { - if (lockedImage) - return lockedImage->numColors(); + if (!lockedImage.isNull()) + return lockedImage.numColors(); DFBResult result; IDirectFBPalette *palette = 0; @@ -176,5 +204,17 @@ QPaintEngine *QDirectFBPaintDevice::paintEngine() const return engine; } +#ifdef QT_DIRECTFB_SUBSURFACE +void QDirectFBPaintDevice::releaseSubSurface() +{ + Q_ASSERT(QDirectFBScreen::instance()); + if (subSurface) { + screen->releaseDFBSurface(subSurface); + subSurface = 0; + } +} #endif +QT_END_NAMESPACE + +#endif // QT_NO_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index 3932403..0b2d00c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -43,11 +43,14 @@ #define QDIRECTFBPAINTDEVICE_H #include <private/qpaintengine_raster_p.h> -#include <directfb.h> #include "qdirectfbscreen.h" +#ifndef QT_NO_QWS_DIRECTFB + QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + QT_MODULE(Gui) // Inherited by both window surface and pixmap @@ -57,10 +60,10 @@ class QDirectFBPaintDevice : public QCustomRasterPaintDevice public: ~QDirectFBPaintDevice(); - IDirectFBSurface *directFBSurface() const; + virtual IDirectFBSurface *directFBSurface() const; - void lockDirectFB(DFBSurfaceLockFlags lock); - void unlockDirectFB(); + bool lockSurface(DFBSurfaceLockFlags lockFlags); + void unlockSurface(); // Reimplemented from QCustomRasterPaintDevice: void *memory() const; @@ -68,9 +71,8 @@ public: int bytesPerLine() const; QSize size() const; int metric(QPaintDevice::PaintDeviceMetric metric) const; - DFBSurfaceLockFlags lockFlags() const { return lock; } + DFBSurfaceLockFlags lockFlags() const { return lockFlgs; } QPaintEngine *paintEngine() const; - protected: QDirectFBPaintDevice(QDirectFBScreen *scr); inline int dotsPerMeterX() const @@ -81,18 +83,26 @@ protected: { return (screen->deviceHeight() * 1000) / screen->physicalHeight(); } -protected: + IDirectFBSurface *dfbSurface; - QImage *lockedImage; +#ifdef QT_DIRECTFB_SUBSURFACE + void releaseSubSurface(); + IDirectFBSurface *subSurface; + friend class QDirectFBPaintEnginePrivate; + bool syncPending; +#endif + QImage lockedImage; QDirectFBScreen *screen; int bpl; - DFBSurfaceLockFlags lock; + DFBSurfaceLockFlags lockFlgs; uchar *mem; QDirectFBPaintEngine *engine; -private: - Q_DISABLE_COPY(QDirectFBPaintDevice); + QImage::Format imageFormat; }; +QT_END_NAMESPACE + QT_END_HEADER +#endif // QT_NO_QWS_DIRECTFB #endif //QDIRECTFBPAINTDEVICE_H diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 131ff4b..043189e 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,28 +21,27 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qdirectfbpaintengine.h" -#ifndef QT_NO_DIRECTFB +#ifndef QT_NO_QWS_DIRECTFB #include "qdirectfbwindowsurface.h" #include "qdirectfbscreen.h" @@ -55,6 +55,8 @@ #include <private/qpixmap_raster_p.h> #include <private/qimagepixmapcleanuphooks_p.h> +QT_BEGIN_NAMESPACE + class SurfaceCache; class QDirectFBPaintEnginePrivate : public QRasterPaintEnginePrivate { @@ -91,6 +93,7 @@ public: inline void lock(); inline void unlock(); + static inline void unlock(QDirectFBPaintDevice *device); inline bool isSimpleBrush(const QBrush &brush) const; @@ -107,7 +110,7 @@ public: #endif void prepareForBlit(bool alpha); -private: + IDirectFBSurface *surface; bool antialiased; @@ -119,14 +122,14 @@ private: IDirectFB *fb; quint8 opacity; - bool dirtyClip; ClipType clipType; QDirectFBPaintDevice *dfbDevice; uint compositionModeStatus; - QDirectFBPaintEngine *q; + bool inClip; QRect currentClip; - friend class QDirectFBPaintEngine; + + QDirectFBPaintEngine *q; }; class SurfaceCache @@ -144,7 +147,9 @@ private: #ifdef QT_DIRECTFB_IMAGECACHE +QT_BEGIN_INCLUDE_NAMESPACE #include <private/qimage_p.h> +QT_END_INCLUDE_NAMESPACE struct CachedImage { IDirectFBSurface *surface; @@ -165,7 +170,8 @@ enum PaintOperation { DRAW_PIXMAP = 0x0008, DRAW_TILED_PIXMAP = 0x0010, STROKE_PATH = 0x0020, DRAW_PATH = 0x0040, DRAW_POINTS = 0x0080, DRAW_ELLIPSE = 0x0100, DRAW_POLYGON = 0x0200, DRAW_TEXT = 0x0400, FILL_PATH = 0x0800, - FILL_RECT = 0x1000, DRAW_COLORSPANS = 0x2000, ALL = 0xffff + FILL_RECT = 0x1000, DRAW_COLORSPANS = 0x2000, DRAW_ROUNDED_RECT = 0x4000, + ALL = 0xffff }; #endif @@ -217,6 +223,7 @@ template <class T> static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface); #define CLIPPED_PAINT(operation) { \ + d->unlock(); \ DFBRegion clipRegion; \ switch (d->clipType) { \ case QDirectFBPaintEnginePrivate::NoClip: \ @@ -236,7 +243,7 @@ static inline void drawRects(const T *rects, int n, const QTransform &transform, d->surface->SetClip(d->surface, &clipRegion); \ operation; \ } \ - d->dirtyClip = true; \ + d->updateClip(); \ break; } \ case QDirectFBPaintEnginePrivate::ComplexClip: \ case QDirectFBPaintEnginePrivate::ClipUnset: \ @@ -264,6 +271,7 @@ bool QDirectFBPaintEngine::begin(QPaintDevice *device) QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbPixmapData = static_cast<QDirectFBPixmapData*>(data); + QDirectFBPaintEnginePrivate::unlock(dfbPixmapData); d->dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData); } @@ -297,8 +305,8 @@ bool QDirectFBPaintEngine::end() void QDirectFBPaintEngine::clipEnabledChanged() { Q_D(QDirectFBPaintEngine); - d->dirtyClip = true; QRasterPaintEngine::clipEnabledChanged(); + d->updateClip(); } void QDirectFBPaintEngine::penChanged() @@ -341,26 +349,49 @@ void QDirectFBPaintEngine::setState(QPainterState *state) { Q_D(QDirectFBPaintEngine); QRasterPaintEngine::setState(state); - d->dirtyClip = true; d->setPen(state->pen); d->opacity = quint8(state->opacity * 255); d->setCompositionMode(state->compositionMode()); d->setTransform(state->transform()); d->setRenderHints(state->renderHints); + if (d->surface) + d->updateClip(); } void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); - d->dirtyClip = true; + const bool wasInClip = d->inClip; + d->inClip = true; QRasterPaintEngine::clip(path, op); + if (!wasInClip) { + d->inClip = false; + d->updateClip(); + } +} + +void QDirectFBPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) +{ + Q_D(QDirectFBPaintEngine); + const bool wasInClip = d->inClip; + d->inClip = true; + QRasterPaintEngine::clip(region, op); + if (!wasInClip) { + d->inClip = false; + d->updateClip(); + } } void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); - d->dirtyClip = true; + const bool wasInClip = d->inClip; + d->inClip = true; QRasterPaintEngine::clip(rect, op); + if (!wasInClip) { + d->inClip = false; + d->updateClip(); + } } void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) @@ -368,10 +399,9 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) Q_D(QDirectFBPaintEngine); const QPen &pen = state()->pen; const QBrush &brush = state()->brush; - if (brush == Qt::NoBrush && pen == Qt::NoPen) + if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen) return; - d->updateClip(); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->simplePen @@ -382,14 +412,15 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) QRasterPaintEngine::drawRects(rects, rectCount); return; } - d->unlock(); - if (brush != Qt::NoBrush) { + + if (brush.style() != Qt::NoBrush) { d->setDFBColor(brush.color()); - CLIPPED_PAINT(::fillRects<QRect>(rects, rectCount, state()->matrix, d->surface)); + CLIPPED_PAINT(QT_PREPEND_NAMESPACE(fillRects<QRect>)(rects, rectCount, state()->matrix, d->surface)); } - if (pen != Qt::NoPen) { + + if (pen.style() != Qt::NoPen) { d->setDFBColor(pen.color()); - CLIPPED_PAINT(::drawRects<QRect>(rects, rectCount, state()->matrix, d->surface)); + CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawRects<QRect>)(rects, rectCount, state()->matrix, d->surface)); } } @@ -398,10 +429,9 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) Q_D(QDirectFBPaintEngine); const QPen &pen = state()->pen; const QBrush &brush = state()->brush; - if (brush == Qt::NoBrush && pen == Qt::NoPen) + if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen) return; - d->updateClip(); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || !d->simplePen @@ -412,21 +442,21 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) QRasterPaintEngine::drawRects(rects, rectCount); return; } - d->unlock(); - if (brush != Qt::NoBrush) { + + if (brush.style() != Qt::NoBrush) { d->setDFBColor(brush.color()); - CLIPPED_PAINT(::fillRects<QRectF>(rects, rectCount, state()->matrix, d->surface)); + CLIPPED_PAINT(fillRects<QRectF>(rects, rectCount, state()->matrix, d->surface)); } - if (pen != Qt::NoPen) { + + if (pen.style() != Qt::NoPen) { d->setDFBColor(pen.color()); - CLIPPED_PAINT(::drawRects<QRectF>(rects, rectCount, state()->matrix, d->surface)); + CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawRects<QRectF>)(rects, rectCount, state()->matrix, d->surface)); } } void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) { Q_D(QDirectFBPaintEngine); - d->updateClip(); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || !d->simplePen @@ -438,17 +468,15 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) } const QPen &pen = state()->pen; - if (pen != Qt::NoPen) { - d->unlock(); + if (pen.style() != Qt::NoPen) { d->setDFBColor(pen.color()); - CLIPPED_PAINT(::drawLines<QLine>(lines, lineCount, state()->matrix, d->surface)); + CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface)); } } void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) { Q_D(QDirectFBPaintEngine); - d->updateClip(); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || !d->simplePen @@ -460,10 +488,9 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) } const QPen &pen = state()->pen; - if (pen != Qt::NoPen) { - d->unlock(); + if (pen.style() != Qt::NoPen) { d->setDFBColor(pen.color()); - CLIPPED_PAINT(::drawLines<QLineF>(lines, lineCount, state()->matrix, d->surface)); + CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface)); } } @@ -491,7 +518,6 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, than the max image cache size we fall back to raster engine. */ - d->updateClip(); #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) @@ -510,10 +536,9 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, return; } #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE - d->unlock(); bool release; IDirectFBSurface *imgSurface = d->getSurface(image, &release); - d->prepareForBlit(QDirectFBScreen::hasAlpha(imgSurface)); + d->prepareForBlit(QDirectFBScreen::hasAlphaChannel(imgSurface)); CLIPPED_PAINT(d->blit(r, imgSurface, sr)); if (release) { #if (Q_DIRECTFB_VERSION >= 0x010000) @@ -534,28 +559,29 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, { Q_D(QDirectFBPaintEngine); - d->updateClip(); if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); d->lock(); QRasterPaintEngine::drawPixmap(r, pixmap, sr); - } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) - || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { - RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); - const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(DSLF_READ); - d->lock(); - QRasterPaintEngine::drawImage(r, *img, sr); } else { - d->unlock(); - d->prepareForBlit(pixmap.hasAlphaChannel()); QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); - dfbData->unlockDirectFB(); - IDirectFBSurface *s = dfbData->directFBSurface(); - - CLIPPED_PAINT(d->blit(r, s, sr)); + if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip + || (state()->renderHints & QPainter::SmoothPixmapTransform + && state()->matrix.mapRect(r).size() != sr.size())) { + RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr); + const QImage *img = dfbData->buffer(); + d->lock(); + QRasterPaintEngine::drawImage(r, *img, sr); + } else { + QDirectFBPaintEnginePrivate::unlock(dfbData); + d->prepareForBlit(pixmap.hasAlphaChannel()); + IDirectFBSurface *s = dfbData->directFBSurface(); + CLIPPED_PAINT(d->blit(r, s, sr)); + } } } @@ -569,24 +595,26 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, const QPointF &offset) { Q_D(QDirectFBPaintEngine); - d->updateClip(); if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset); } else if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) - || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { + || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip + || (state()->renderHints & QPainter::SmoothPixmapTransform && state()->matrix.isScaling())) { RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset); - const QImage *img = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(DSLF_READ); + QPixmapData *pixmapData = pixmap.pixmapData(); + Q_ASSERT(pixmapData->classId() == QPixmapData::DirectFBClass); + QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(pixmapData); + const QImage *img = dfbData->buffer(); d->lock(); QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType); data->fromImage(*img, Qt::AutoColor); const QPixmap pix(data); QRasterPaintEngine::drawTiledPixmap(r, pix, offset); } else { - d->unlock(); - d->drawTiledPixmap(r, pixmap, offset); + CLIPPED_PAINT(d->drawTiledPixmap(r, pixmap, offset)); } } @@ -668,13 +696,19 @@ void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush) QRasterPaintEngine::fill(path, brush); } +void QDirectFBPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode) +{ + RASTERFALLBACK(DRAW_ROUNDED_RECT, rect, xrad, yrad); + Q_D(QDirectFBPaintEngine); + d->lock(); + QRasterPaintEngine::drawRoundedRect(rect, xrad, yrad, mode); +} void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) { Q_D(QDirectFBPaintEngine); if (brush.style() == Qt::NoBrush) return; - d->updateClip(); if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) { switch (brush.style()) { case Qt::SolidPattern: { @@ -685,7 +719,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) const QColor color = brush.color(); if (!color.isValid()) return; - d->unlock(); d->setDFBColor(color); const QRect r = state()->matrix.mapRect(rect).toRect(); CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height())); @@ -693,7 +726,8 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) case Qt::TexturePattern: { if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedBlits) - || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported)) { + || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) + || (state()->renderHints & QPainter::SmoothPixmapTransform && state()->matrix.isScaling())) { break; } @@ -701,7 +735,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (texture.pixmapData()->classId() != QPixmapData::DirectFBClass) break; - d->unlock(); CLIPPED_PAINT(d->drawTiledPixmap(rect, texture, rect.topLeft() - state()->brushOrigin)); return; } default: @@ -718,7 +751,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) if (!color.isValid()) return; Q_D(QDirectFBPaintEngine); - d->updateClip(); if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives) || (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported) || d->clipType == QDirectFBPaintEnginePrivate::ComplexClip) { @@ -726,11 +758,9 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) d->lock(); QRasterPaintEngine::fillRect(rect, color); } else { - d->unlock(); d->setDFBColor(color); const QRect r = state()->matrix.mapRect(rect).toRect(); - d->surface->FillRectangle(d->surface, r.x(), r.y(), - r.width(), r.height()); + CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height())); } } @@ -765,9 +795,9 @@ void QDirectFBPaintEngine::initImageCache(int size) QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) : surface(0), antialiased(false), simplePen(false), - transformationType(0), opacity(255), dirtyClip(true), + transformationType(0), opacity(255), clipType(ClipUnset), dfbDevice(0), - compositionModeStatus(0), q(p) + compositionModeStatus(0), inClip(false), q(p) { fb = QDirectFBScreen::instance()->dfb(); surfaceCache = new SurfaceCache; @@ -789,8 +819,7 @@ void QDirectFBPaintEnginePrivate::lock() // lock so we need to call the base implementation of prepare so // it updates its rasterBuffer to point to the new buffer address. Q_ASSERT(dfbDevice); - if (dfbDevice->lockFlags() != (DSLF_WRITE|DSLF_READ)) { - dfbDevice->lockDirectFB(DSLF_READ|DSLF_WRITE); + if (dfbDevice->lockSurface(DSLF_READ|DSLF_WRITE)) { prepare(dfbDevice); } } @@ -798,7 +827,21 @@ void QDirectFBPaintEnginePrivate::lock() void QDirectFBPaintEnginePrivate::unlock() { Q_ASSERT(dfbDevice); - dfbDevice->unlockDirectFB(); +#ifdef QT_DIRECTFB_SUBSURFACE + dfbDevice->syncPending = true; +#else + QDirectFBPaintEnginePrivate::unlock(dfbDevice); +#endif +} + +void QDirectFBPaintEnginePrivate::unlock(QDirectFBPaintDevice *device) +{ +#ifdef QT_NO_DIRECTFB_SUBSURFACE + Q_ASSERT(device); + device->unlockSurface(); +#else + Q_UNUSED(device); +#endif } void QDirectFBPaintEnginePrivate::setTransform(const QTransform &transform) @@ -829,6 +872,13 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m { if (!surface) return; + + static const bool forceRasterFallBack = qgetenv("QT_DIRECTFB_FORCE_RASTER").toInt() > 0; + if (forceRasterFallBack) { + compositionModeStatus = 0; + return; + } + compositionModeStatus = PorterDuff_SupportedBlits; switch (mode) { case QPainter::CompositionMode_Clear: @@ -866,10 +916,10 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m case QPainter::CompositionMode_Plus: surface->SetPorterDuff(surface, DSPD_ADD); break; -#endif case QPainter::CompositionMode_Xor: surface->SetPorterDuff(surface, DSPD_XOR); break; +#endif default: compositionModeStatus = 0; break; @@ -887,12 +937,12 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) { - quint32 blittingFlags = alpha ? DSBLIT_BLEND_ALPHACHANNEL : DSBLIT_NOFX; + DFBSurfaceBlittingFlags blittingFlags = alpha ? DSBLIT_BLEND_ALPHACHANNEL : DSBLIT_NOFX; if (opacity != 255) { blittingFlags |= DSBLIT_BLEND_COLORALPHA; } surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); + surface->SetBlittingFlags(surface, blittingFlags); } static inline uint ALPHA_MUL(uint x, uint a) @@ -914,9 +964,9 @@ void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release) { -#ifndef QT_DIRECTFB_IMAGECACHE +#ifdef QT_NO_DIRECTFB_IMAGECACHE *release = true; - return QDirectFBScreen::instance()->createDFBSurface(img, QDirectFBScreen::DontTrackSurface); + return QDirectFBScreen::instance()->createDFBSurface(img, img.format(), QDirectFBScreen::DontTrackSurface); #else const qint64 key = img.cacheKey(); *release = false; @@ -930,7 +980,7 @@ IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, boo const QImage::Format format = (img.format() == screen->alphaPixmapFormat() || QDirectFBPixmapData::hasAlphaChannel(img) ? screen->alphaPixmapFormat() : screen->pixelFormat()); - IDirectFBSurface *surface = screen->copyToDFBSurface(img, format, + IDirectFBSurface *surface = screen->createDFBSurface(img, format, cache ? QDirectFBScreen::TrackSurface : QDirectFBScreen::DontTrackSurface); @@ -978,7 +1028,6 @@ static inline qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset) void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &off) { - Q_ASSERT(!dirtyClip); Q_ASSERT(!(transformationType & Matrix_BlitsUnsupported)); const QTransform &transform = q->state()->matrix; const QRect destinationRect = transform.mapRect(dest).toRect().normalized(); @@ -1003,7 +1052,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data); - dfbData->unlockDirectFB(); + QDirectFBPaintEnginePrivate::unlock(dfbData); const QSize pixmapSize = dfbData->size(); IDirectFBSurface *sourceSurface = dfbData->directFBSurface(); if (transform.isScaling()) { @@ -1012,8 +1061,8 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix offset.ry() *= transform.m22(); const QSizeF mappedSize(pixmapSize.width() * transform.m11(), pixmapSize.height() * transform.m22()); - qreal y = ::fixCoord(destinationRect.y(), mappedSize.height(), offset.y()); - const qreal startX = ::fixCoord(destinationRect.x(), mappedSize.width(), offset.x()); + qreal y = fixCoord(destinationRect.y(), mappedSize.height(), offset.y()); + const qreal startX = fixCoord(destinationRect.x(), mappedSize.width(), offset.x()); while (y <= destinationRect.bottom()) { qreal x = startX; while (x <= destinationRect.right()) { @@ -1024,8 +1073,8 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix y += mappedSize.height(); } } else { - qreal y = ::fixCoord(destinationRect.y(), pixmapSize.height(), offset.y()); - const qreal startX = ::fixCoord(destinationRect.x(), pixmapSize.width(), offset.x()); + qreal y = fixCoord(destinationRect.y(), pixmapSize.height(), offset.y()); + const qreal startX = fixCoord(destinationRect.x(), pixmapSize.width(), offset.x()); int horizontal = qMax(1, destinationRect.width() / pixmapSize.width()) + 1; if (startX != destinationRect.x()) ++horizontal; @@ -1071,9 +1120,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPix void QDirectFBPaintEnginePrivate::updateClip() { - if (!dirtyClip) - return; - + Q_ASSERT(surface); currentClip = QRect(); const QClipData *clipData = clip(); if (!clipData || !clipData->enabled) { @@ -1095,14 +1142,12 @@ void QDirectFBPaintEnginePrivate::updateClip() } else { clipType = ComplexClip; } - - dirtyClip = false; } void QDirectFBPaintEnginePrivate::systemStateChanged() { - dirtyClip = true; QRasterPaintEnginePrivate::systemStateChanged(); + updateClip(); } IDirectFBSurface *SurfaceCache::getSurface(const uint *buf, int size) @@ -1113,7 +1158,7 @@ IDirectFBSurface *SurfaceCache::getSurface(const uint *buf, int size) clear(); const DFBSurfaceDescription description = QDirectFBScreen::getSurfaceDescription(buf, size); - surface = QDirectFBScreen::instance()->createDFBSurface(description, QDirectFBScreen::TrackSurface); + surface = QDirectFBScreen::instance()->createDFBSurface(description, QDirectFBScreen::TrackSurface, 0); if (!surface) qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface"); @@ -1141,12 +1186,12 @@ template <class T> static inline void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface) { if (n == 1) { - const QLine l = ::map(transform, lines[0]); + const QLine l = map(transform, lines[0]); surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); } else { QVarLengthArray<DFBRegion, 32> lineArray(n); for (int i=0; i<n; ++i) { - const QLine l = ::map(transform, lines[i]); + const QLine l = map(transform, lines[i]); lineArray[i].x1 = l.x1(); lineArray[i].y1 = l.y1(); lineArray[i].x2 = l.x2(); @@ -1160,12 +1205,12 @@ template <class T> static inline void fillRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface) { if (n == 1) { - const QRect r = ::mapRect(transform, rects[0]); + const QRect r = mapRect(transform, rects[0]); surface->FillRectangle(surface, r.x(), r.y(), r.width(), r.height()); } else { QVarLengthArray<DFBRectangle, 32> rectArray(n); for (int i=0; i<n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = mapRect(transform, rects[i]); rectArray[i].x = r.x(); rectArray[i].y = r.y(); rectArray[i].w = r.width(); @@ -1179,7 +1224,7 @@ template <class T> static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface) { for (int i=0; i<n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = mapRect(transform, rects[i]); surface->DrawRectangle(surface, r.x(), r.y(), r.width(), r.height()); } } @@ -1226,4 +1271,7 @@ static void rasterFallbackWarn(const char *msg, const char *func, const device * } #endif // QT_DIRECTFB_WARN_ON_RASTERFALLBACKS -#endif // QT_NO_DIRECTFB + +QT_END_NAMESPACE + +#endif // QT_NO_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h index b939b68..94cb556 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -45,8 +45,12 @@ #include <QtGui/qpaintengine.h> #include <private/qpaintengine_raster_p.h> +#ifndef QT_NO_QWS_DIRECTFB + QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + QT_MODULE(Gui) class QDirectFBPaintEnginePrivate; @@ -90,6 +94,7 @@ public: virtual void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode); virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); virtual void fill(const QVectorPath &path, const QBrush &brush); + virtual void drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode); virtual void clipEnabledChanged(); virtual void penChanged(); @@ -101,11 +106,16 @@ public: virtual void setState(QPainterState *state); virtual void clip(const QVectorPath &path, Qt::ClipOperation op); + virtual void clip(const QRegion ®ion, Qt::ClipOperation op); virtual void clip(const QRect &rect, Qt::ClipOperation op); static void initImageCache(int size); }; +QT_END_NAMESPACE + QT_END_HEADER +#endif // QT_NO_QWS_DIRECTFB + #endif // QPAINTENGINE_DIRECTFB_P_H diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 0afb8a8..ce9a55c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,47 +21,49 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qdirectfbpixmap.h" +#ifndef QT_NO_QWS_DIRECTFB + #include "qdirectfbscreen.h" #include "qdirectfbpaintengine.h" #include <QtGui/qbitmap.h> +#include <QtCore/qfile.h> #include <directfb.h> + +QT_BEGIN_NAMESPACE + static int global_ser_no = 0; QDirectFBPixmapData::QDirectFBPixmapData(QDirectFBScreen *screen, PixelType pixelType) : QPixmapData(pixelType, DirectFBClass), QDirectFBPaintDevice(screen), - format(QImage::Format_Invalid), alpha(false) + alpha(false) { setSerialNumber(0); } QDirectFBPixmapData::~QDirectFBPixmapData() { - unlockDirectFB(); - if (dfbSurface && QDirectFBScreen::instance()) - screen->releaseDFBSurface(dfbSurface); } void QDirectFBPixmapData::resize(int width, int height) @@ -70,11 +73,11 @@ void QDirectFBPixmapData::resize(int width, int height) return; } - format = screen->pixelFormat(); + imageFormat = screen->pixelFormat(); dfbSurface = screen->createDFBSurface(QSize(width, height), - format, + imageFormat, QDirectFBScreen::TrackSurface); - d = screen->depth(); + d = QDirectFBScreen::depth(imageFormat); alpha = false; if (!dfbSurface) { invalidate(); @@ -85,7 +88,6 @@ void QDirectFBPixmapData::resize(int width, int height) w = width; h = height; is_null = (w <= 0 || h <= 0); - d = metric(QPaintDevice::PdmDepth); setSerialNumber(++global_ser_no); } @@ -162,43 +164,185 @@ static bool checkForAlphaPixels(const QImage &img) bool QDirectFBPixmapData::hasAlphaChannel(const QImage &img) { #ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION - return ::checkForAlphaPixels(img); + return checkForAlphaPixels(img); #else return img.hasAlphaChannel(); #endif } +#ifdef QT_DIRECTFB_IMAGEPROVIDER +bool QDirectFBPixmapData::fromFile(const QString &filename, const char *format, + Qt::ImageConversionFlags flags) +{ + if (flags == Qt::AutoColor) { + if (filename.startsWith(QLatin1Char(':'))) { // resource + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)) + return false; + const QByteArray data = file.readAll(); + file.close(); + return fromData(reinterpret_cast<const uchar*>(data.constData()), data.size(), format, flags); + } else { + DFBDataBufferDescription description; + description.flags = DBDESC_FILE; + const QByteArray fileNameData = filename.toLocal8Bit(); + description.file = fileNameData.constData(); + if (fromDataBufferDescription(description)) { + return true; + } + // fall back to Qt + } + } + return QPixmapData::fromFile(filename, format, flags); +} -void QDirectFBPixmapData::fromImage(const QImage &i, - Qt::ImageConversionFlags flags) +bool QDirectFBPixmapData::fromData(const uchar *buffer, uint len, const char *format, + Qt::ImageConversionFlags flags) { -#ifdef QT_NO_DIRECTFB_OPAQUE_DETECTION - Q_UNUSED(flags); + if (flags == Qt::AutoColor) { + DFBDataBufferDescription description; + description.flags = DBDESC_MEMORY; + description.memory.data = buffer; + description.memory.length = len; + if (fromDataBufferDescription(description)) + return true; + // fall back to Qt + } + return QPixmapData::fromData(buffer, len, format, flags); +} + +template <typename T> struct QDirectFBInterfaceCleanupHandler +{ + static void cleanup(T *t) { if (t) t->Release(t); } +}; + +template <typename T> +class QDirectFBPointer : public QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> > +{ +public: + QDirectFBPointer(T *t = 0) + : QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> >(t) + {} +}; + +bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescription &dataBufferDescription) +{ + IDirectFB *dfb = screen->dfb(); + Q_ASSERT(dfb); + DFBResult result = DFB_OK; + IDirectFBDataBuffer *dataBufferPtr; + if ((result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, &dataBufferPtr)) != DFB_OK) { + DirectFBError("QDirectFBPixmapData::fromDataBufferDescription()", result); + return false; + } + QDirectFBPointer<IDirectFBDataBuffer> dataBuffer(dataBufferPtr); + + IDirectFBImageProvider *providerPtr; + if ((result = dataBuffer->CreateImageProvider(dataBuffer.data(), &providerPtr)) != DFB_OK) { + DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't create image provider", result); + return false; + } + QDirectFBPointer<IDirectFBImageProvider> provider(providerPtr); + + DFBSurfaceDescription surfaceDescription; + if ((result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription)) != DFB_OK) { + DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't get surface description", result); + return false; + } + + DFBImageDescription imageDescription; + result = provider->GetImageDescription(provider.data(), &imageDescription); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't get image description", result); + return false; + } + + alpha = imageDescription.caps & (DICAPS_ALPHACHANNEL|DICAPS_COLORKEY); + imageFormat = alpha ? screen->alphaPixmapFormat() : screen->pixelFormat(); + + dfbSurface = screen->createDFBSurface(QSize(surfaceDescription.width, surfaceDescription.height), + imageFormat, QDirectFBScreen::TrackSurface); + + result = provider->RenderTo(provider.data(), dfbSurface, 0); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't render to surface", result); + return false; + } + + w = surfaceDescription.width; + h = surfaceDescription.height; + is_null = (w <= 0 || h <= 0); + d = QDirectFBScreen::depth(imageFormat); + setSerialNumber(++global_ser_no); + +#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE + screen->setDirectFBImageProvider(providerPtr); + provider.take(); +#endif + + return true; +} + #endif - const QImage img = (i.depth() == 1 ? i.convertToFormat(screen->alphaPixmapFormat()) : i); + +void QDirectFBPixmapData::fromImage(const QImage &img, + Qt::ImageConversionFlags flags) +{ + if (img.depth() == 1) { + fromImage(img.convertToFormat(screen->alphaPixmapFormat()), flags); + return; + } + if (img.hasAlphaChannel() #ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION && (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img)) #endif ) { alpha = true; - format = screen->alphaPixmapFormat(); + imageFormat = screen->alphaPixmapFormat(); } else { alpha = false; - format = screen->pixelFormat(); + imageFormat = screen->pixelFormat(); } - dfbSurface = screen->copyToDFBSurface(img, format, - QDirectFBScreen::TrackSurface); + QImage image; + if (flags != Qt::AutoColor) { + image = img.convertToFormat(imageFormat, flags); + flags = Qt::AutoColor; + } else { + image = img; + } + + IDirectFBSurface *imageSurface = screen->createDFBSurface(image, image.format(), QDirectFBScreen::DontTrackSurface); + if (!imageSurface) { + qWarning("QDirectFBPixmapData::fromImage()"); + invalidate(); + return; + } + + dfbSurface = screen->createDFBSurface(image.size(), imageFormat, QDirectFBScreen::TrackSurface); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage()"); invalidate(); return; } - w = img.width(); - h = img.height(); + + if (image.hasAlphaChannel()) { + dfbSurface->Clear(dfbSurface, 0, 0, 0, 0); + dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_BLEND_ALPHACHANNEL); + } else { + dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + } + dfbSurface->Blit(dfbSurface, imageSurface, 0, 0, 0); + imageSurface->Release(imageSurface); + + w = image.width(); + h = image.height(); is_null = (w <= 0 || h <= 0); - d = metric(QPaintDevice::PdmDepth); + d = QDirectFBScreen::depth(imageFormat); setSerialNumber(++global_ser_no); +#ifdef QT_NO_DIRECTFB_OPAQUE_DETECTION + Q_UNUSED(flags); +#endif } void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) @@ -207,17 +351,21 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) QPixmapData::copy(data, rect); return; } - unlockDirectFB(); const QDirectFBPixmapData *otherData = static_cast<const QDirectFBPixmapData*>(data); +#ifdef QT_NO_DIRECTFB_SUBSURFACE + if (otherData->lockFlags()) { + const_cast<QDirectFBPixmapData*>(otherData)->unlockSurface(); + } +#endif IDirectFBSurface *src = otherData->directFBSurface(); alpha = data->hasAlphaChannel(); - format = (alpha - ? QDirectFBScreen::instance()->alphaPixmapFormat() - : QDirectFBScreen::instance()->pixelFormat()); + imageFormat = (alpha + ? QDirectFBScreen::instance()->alphaPixmapFormat() + : QDirectFBScreen::instance()->pixelFormat()); - dfbSurface = screen->createDFBSurface(rect.size(), format, + dfbSurface = screen->createDFBSurface(rect.size(), imageFormat, QDirectFBScreen::TrackSurface); if (!dfbSurface) { qWarning("QDirectFBPixmapData::copy()"); @@ -237,6 +385,7 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) h = rect.height(); d = otherData->d; is_null = (w <= 0 || h <= 0); + unlockSurface(); DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0); #if (Q_DIRECTFB_VERSION >= 0x010000) dfbSurface->ReleaseSource(dfbSurface); @@ -275,11 +424,12 @@ void QDirectFBPixmapData::fill(const QColor &color) alpha = (color.alpha() < 255); - if (alpha && ::isOpaqueFormat(format)) { + if (alpha && isOpaqueFormat(imageFormat)) { QSize size; dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight()); screen->releaseDFBSurface(dfbSurface); - format = screen->alphaPixmapFormat(); + imageFormat = screen->alphaPixmapFormat(); + d = QDirectFBScreen::depth(imageFormat); dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface); setSerialNumber(++global_ser_no); if (!dfbSurface) { @@ -296,18 +446,21 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, Qt::TransformationMode mode) const { QDirectFBPixmapData *that = const_cast<QDirectFBPixmapData*>(this); +#ifdef QT_NO_DIRECTFB_SUBSURFACE + if (lockFlags()) + that->unlockSurface(); +#endif + if (!dfbSurface || transform.type() != QTransform::TxScale || mode != Qt::FastTransformation) { const QImage *image = that->buffer(); Q_ASSERT(image); const QImage transformed = image->transformed(transform, mode); - that->unlockDirectFB(); QDirectFBPixmapData *data = new QDirectFBPixmapData(screen, QPixmapData::PixmapType); data->fromImage(transformed, Qt::AutoColor); return QPixmap(data); } - that->unlockDirectFB(); const QSize size = transform.mapRect(QRect(0, 0, w, h)).size(); if (size.isEmpty()) @@ -320,7 +473,7 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, flags = DSBLIT_BLEND_ALPHACHANNEL; } data->dfbSurface = screen->createDFBSurface(size, - format, + imageFormat, QDirectFBScreen::TrackSurface); if (flags & DSBLIT_BLEND_ALPHACHANNEL) { data->dfbSurface->Clear(data->dfbSurface, 0, 0, 0, 0); @@ -387,21 +540,30 @@ QPaintEngine *QDirectFBPixmapData::paintEngine() const QImage *QDirectFBPixmapData::buffer() { - lockDirectFB(DSLF_READ|DSLF_WRITE); - return lockedImage; -} - -QImage * QDirectFBPixmapData::buffer(DFBSurfaceLockFlags lockFlags) -{ - lockDirectFB(lockFlags); - return lockedImage; + if (!lockFlgs) { + lockSurface(DSLF_READ|DSLF_WRITE); + } + Q_ASSERT(lockFlgs); + Q_ASSERT(!lockedImage.isNull()); + return &lockedImage; } void QDirectFBPixmapData::invalidate() { + if (dfbSurface) { + screen->releaseDFBSurface(dfbSurface); + dfbSurface = 0; + } setSerialNumber(0); alpha = false; d = w = h = 0; - format = QImage::Format_Invalid; + is_null = true; + imageFormat = QImage::Format_Invalid; } +QT_END_NAMESPACE + +#endif // QT_NO_QWS_DIRECTFB + + + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index 2300174..b52b305 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,6 +42,10 @@ #ifndef QDIRECTFBPIXMAP_H #define QDIRECTFBPIXMAP_H +#include <qglobal.h> + +#ifndef QT_NO_QWS_DIRECTFB + #include <QtGui/private/qpixmapdata_p.h> #include <QtGui/private/qpaintengine_raster_p.h> #include "qdirectfbpaintdevice.h" @@ -49,6 +53,8 @@ QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + QT_MODULE(Gui) class QDirectFBPaintEngine; @@ -62,6 +68,12 @@ public: // Re-implemented from QPixmapData: virtual void resize(int width, int height); virtual void fromImage(const QImage &image, Qt::ImageConversionFlags flags); +#ifdef QT_DIRECTFB_IMAGEPROVIDER + virtual bool fromFile(const QString &filename, const char *format, + Qt::ImageConversionFlags flags); + virtual bool fromData(const uchar *buffer, uint len, const char *format, + Qt::ImageConversionFlags flags); +#endif virtual void copy(const QPixmapData *data, const QRect &rect); virtual void fill(const QColor &color); virtual QPixmap transformed(const QTransform &matrix, @@ -69,20 +81,24 @@ public: virtual QImage toImage() const; virtual QPaintEngine *paintEngine() const; virtual QImage *buffer(); - virtual int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} - - QImage *buffer(DFBSurfaceLockFlags lockFlags); - // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice - inline QImage::Format pixelFormat() const { return format; } + virtual int metric(QPaintDevice::PaintDeviceMetric m) const { return QDirectFBPaintDevice::metric(m); } + + inline QImage::Format pixelFormat() const { return imageFormat; } static bool hasAlphaChannel(const QImage &img); inline bool hasAlphaChannel() const { return alpha; } private: +#ifdef QT_DIRECTFB_IMAGEPROVIDER + bool fromDataBufferDescription(const DFBDataBufferDescription &dataBuffer); +#endif void invalidate(); - QImage::Format format; bool alpha; }; +QT_END_NAMESPACE + QT_END_HEADER +#endif // QT_NO_QWS_DIRECTFB + #endif // QDIRECTFBPIXMAP_H diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 774162c..0f7a6de 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -54,15 +54,24 @@ #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; @@ -70,6 +79,7 @@ public: IDirectFBScreen *dfbScreen; #ifdef QT_NO_DIRECTFB_WM IDirectFBSurface *primarySurface; + QColor backgroundColor; #endif #ifndef QT_NO_DIRECTFB_LAYER IDirectFBDisplayLayer *dfbLayer; @@ -82,7 +92,12 @@ public: #ifndef QT_NO_DIRECTFB_KEYBOARD QDirectFBKeyboardHandler *keyboard; #endif - QColor backgroundColor; +#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE + IDirectFBImageProvider *imageProvider; +#endif + IDirectFBSurface *cursorSurface; + qint64 cursorImageKey; + QDirectFBScreen *q; }; @@ -102,11 +117,20 @@ QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *qptr) #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() @@ -117,6 +141,10 @@ QDirectFBScreenPrivate::~QDirectFBScreenPrivate() #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); @@ -139,64 +167,77 @@ QDirectFBScreenPrivate::~QDirectFBScreenPrivate() dfb->Release(dfb); } - - -// creates a preallocated surface with the same format as the image if -// possible. - -IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCreationOptions options) +IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QImage &image, QImage::Format format, SurfaceCreationOptions options, DFBResult *resultPtr) { - if (img.isNull()) // assert? + if (image.isNull()) // assert? return 0; - if (QDirectFBScreen::getSurfacePixelFormat(img.format()) == DSPF_UNKNOWN) { - QImage image = img.convertToFormat(img.hasAlphaChannel() - ? d_ptr->alphaPixmapFormat - : pixelFormat()); - IDirectFBSurface *tmp = createDFBSurface(image, false); - if (!tmp) { - qWarning("Couldn't create surface createDFBSurface(QImage, bool)"); - return 0; - } - IDirectFBSurface *surface = copyDFBSurface(tmp, image.format(), options); - tmp->Release(tmp); - return surface; + 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); } - IDirectFBSurface *surface = createDFBSurface(QDirectFBScreen::getSurfaceDescription(img), options); -#ifdef QT_NO_DIRECTFB_PREALLOCATED - if (surface) { - int bpl; - uchar *mem = QDirectFBScreen::lockSurface(surface, DSLF_WRITE, &bpl); + 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 h = img.height(); - const int w = img.width() * img.depth() / 8; - for (int i = 0; i < h; ++i) { - memcpy(mem, img.scanLine(i), w); - mem += bpl; + const int height = image.height(); + const int bplQt = image.bytesPerLine(); + if (bplQt == bplDFB && bplQt == (image.width() * image.depth() / 8)) { + memcpy(mem, image.bits(), image.numBytes()); + } else { + for (int i=0; i<height; ++i) { + memcpy(mem, image.scanLine(i), bplQt); + mem += bplDFB; + } } surface->Unlock(surface); } } -#endif -#ifndef QT_NO_DIRECTFB_PALETTE - if (img.numColors() != 0 && surface) - QDirectFBScreen::setSurfaceColorTable(surface, img); +#ifdef QT_DIRECTFB_PALETTE + if (image.numColors() != 0 && surface) + QDirectFBScreen::setSurfaceColorTable(surface, image); #endif return surface; } IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src, QImage::Format format, - SurfaceCreationOptions options) + SurfaceCreationOptions options, + DFBResult *result) { Q_ASSERT(src); QSize size; src->GetSize(src, &size.rwidth(), &size.rheight()); - IDirectFBSurface *surface = createDFBSurface(size, format, options); - DFBSurfacePixelFormat dspf; - src->GetPixelFormat(src, &dspf); - DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlpha(dspf) + IDirectFBSurface *surface = createDFBSurface(size, format, options, result); + DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlphaChannel(surface) ? DSBLIT_BLEND_ALPHACHANNEL : DSBLIT_NOFX; if (flags & DSBLIT_BLEND_ALPHACHANNEL) @@ -212,7 +253,8 @@ IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src, IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size, QImage::Format format, - SurfaceCreationOptions options) + SurfaceCreationOptions options, + DFBResult *result) { DFBSurfaceDescription desc; memset(&desc, 0, sizeof(DFBSurfaceDescription)); @@ -221,12 +263,14 @@ IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QSize &size, return 0; desc.width = size.width(); desc.height = size.height(); - return createDFBSurface(desc, options); + return createDFBSurface(desc, options, result); } -IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc, SurfaceCreationOptions options) +IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc, SurfaceCreationOptions options, DFBResult *resultPtr) { - DFBResult result = DFB_OK; + DFBResult tmp; + DFBResult &result = (resultPtr ? *resultPtr : tmp); + result = DFB_OK; IDirectFBSurface *newSurface = 0; if (!d_ptr->dfb) { @@ -280,75 +324,37 @@ IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc, if (options & TrackSurface) { d_ptr->allocatedSurfaces.insert(newSurface); - - //qDebug("Created a new DirectFB surface at %p. New count = %d", - // newSurface, d_ptr->allocatedSurfaces.count()); } return newSurface; } -IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, - QImage::Format pixmapFormat, - SurfaceCreationOptions options) +#ifdef QT_DIRECTFB_SUBSURFACE +IDirectFBSurface *QDirectFBScreen::getSubSurface(IDirectFBSurface *surface, + const QRect &rect, + SurfaceCreationOptions options, + DFBResult *resultPtr) { - QImage image = img; - if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN -#ifdef QT_NO_DIRECTFB_PREALLOCATED - || image.format() != pixmapFormat -#endif -#ifdef QT_NO_DIRECTFB_PALETTE - || image.numColors() != 0 -#endif - ) { - image = image.convertToFormat(pixmapFormat); - } - - IDirectFBSurface *dfbSurface = createDFBSurface(image.size(), pixmapFormat, options); - if (!dfbSurface) { - qWarning("QDirectFBScreen::copyToDFBSurface() Couldn't create surface"); - return 0; - } - -#ifndef QT_NO_DIRECTFB_PREALLOCATED - IDirectFBSurface *imgSurface = createDFBSurface(image, DontTrackSurface); - if (!imgSurface) { - qWarning("QDirectFBScreen::copyToDFBSurface()"); - QDirectFBScreen::releaseDFBSurface(dfbSurface); - return 0; + 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); } - - Q_ASSERT(imgSurface); - DFBSurfaceBlittingFlags flags = img.hasAlphaChannel() - ? DSBLIT_BLEND_ALPHACHANNEL - : DSBLIT_NOFX; - if (flags & DSBLIT_BLEND_ALPHACHANNEL) - dfbSurface->Clear(dfbSurface, 0, 0, 0, 0); - - dfbSurface->SetBlittingFlags(dfbSurface, flags); - DFBResult result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0); - if (result != DFB_OK) - DirectFBError("QDirectFBScreen::copyToDFBSurface()", result); - imgSurface->Release(imgSurface); -#if (Q_DIRECTFB_VERSION >= 0x010000) - dfbSurface->ReleaseSource(dfbSurface); -#endif -#else // QT_NO_DIRECTFB_PREALLOCATED - Q_ASSERT(image.format() == pixmapFormat); - int bpl; - uchar *mem = QDirectFBScreen::lockSurface(dfbSurface, DSLF_WRITE, &bpl); - if (mem) { - const int h = image.height(); - const int w = image.width() * image.depth() / 8; - for (int i=0; i<h; ++i) { - memcpy(mem, image.scanLine(i), w); - mem += bpl; - } - dfbSurface->Unlock(dfbSurface); + if (result != DFB_OK) { + DirectFBError("Can't get sub surface", result); + } else if (options & TrackSurface) { + d_ptr->allocatedSurfaces.insert(subSurface); } -#endif - return dfbSurface; + return subSurface; } +#endif + void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface) { @@ -463,36 +469,6 @@ QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface) return QImage::Format_Invalid; } -DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const QImage &image) -{ - DFBSurfaceDescription description; - memset(&description, 0, sizeof(DFBSurfaceDescription)); - - const DFBSurfacePixelFormat format = getSurfacePixelFormat(image.format()); - - if (format == DSPF_UNKNOWN || image.isNull()) { - description.flags = DSDESC_NONE; - return description; - } - - description.flags = DSDESC_WIDTH|DSDESC_HEIGHT|DSDESC_PIXELFORMAT; - QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, image.format()); - description.width = image.width(); - description.height = image.height(); -#ifndef QT_NO_DIRECTFB_PREALLOCATED - description.flags |= DSDESC_PREALLOCATED; - description.preallocated[0].data = (void*)(image.bits()); - description.preallocated[0].pitch = image.bytesPerLine(); - description.preallocated[1].data = 0; - description.preallocated[1].pitch = 0; -#endif - - if (QDirectFBScreen::isPremultiplied(image.format())) - description.caps = DSCAPS_PREMULTIPLIED; - - return description; -} - DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const uint *buffer, int length) { @@ -508,7 +484,7 @@ DFBSurfaceDescription QDirectFBScreen::getSurfaceDescription(const uint *buffer, description.preallocated[0].pitch = length * sizeof(uint); description.preallocated[1].data = 0; description.preallocated[1].pitch = 0; -return description; + return description; } #ifndef QT_NO_DIRECTFB_PALETTE @@ -549,7 +525,7 @@ void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface, #endif // QT_NO_DIRECTFB_PALETTE -#if !defined(QT_NO_DIRECTFB_LAYER) && !defined(QT_NO_QWS_CURSOR) +#if defined QT_DIRECTFB_CURSOR class Q_GUI_EXPORT QDirectFBScreenCursor : public QScreenCursor { public: @@ -559,6 +535,11 @@ public: virtual void show(); virtual void hide(); private: +#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR + ~QDirectFBScreenCursor(); + bool createWindow(); + IDirectFBWindow *window; +#endif IDirectFBDisplayLayer *layer; }; @@ -574,11 +555,98 @@ QDirectFBScreenCursor::QDirectFBScreenCursor() 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() @@ -586,6 +654,7 @@ 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: " @@ -601,6 +670,15 @@ void QDirectFBScreenCursor::hide() 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 } } @@ -614,7 +692,13 @@ void QDirectFBScreenCursor::show() DirectFBError("QDirectFBScreenCursor::show: " "Unable to set cooperative level", result); } - result = layer->SetCursorOpacity(layer, 255); + 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); @@ -624,6 +708,15 @@ void QDirectFBScreenCursor::show() 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 } } @@ -640,12 +733,15 @@ void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty) cursor = image.convertToFormat(screen->alphaPixmapFormat()); size = cursor.size(); hotspot = QPoint(hotx, hoty); - IDirectFBSurface *surface = screen->createDFBSurface(cursor, QDirectFBScreen::DontTrackSurface); + DFBResult result = DFB_OK; + IDirectFBSurface *surface = screen->createDFBSurface(cursor, screen->alphaPixmapFormat(), + QDirectFBScreen::DontTrackSurface, &result); if (!surface) { - qWarning("QDirectFBScreenCursor::set: Unable to create surface"); + DirectFBError("QDirectFBScreenCursor::set: Unable to create surface", result); return; } - DFBResult result = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE); +#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); @@ -655,17 +751,53 @@ void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty) DirectFBError("QDirectFBScreenCursor::show: " "Unable to set cursor shape", result); } - surface->Release(surface); 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_NO_DIRECTFB_LAYER +#endif // QT_DIRECTFB_CURSOR QDirectFBScreen::QDirectFBScreen(int display_id) : QScreen(display_id, DirectFBClass), d_ptr(new QDirectFBScreenPrivate(this)) @@ -720,6 +852,42 @@ int QDirectFBScreen::depth(DFBSurfacePixelFormat format) 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,]*)$")); @@ -746,6 +914,18 @@ void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args) } } +#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) @@ -851,9 +1031,9 @@ static void printDirectFBInfo(IDirectFB *fb, IDirectFBSurface *primarySurface) 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(), + 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 @@ -861,7 +1041,7 @@ static void printDirectFBInfo(IDirectFB *fb, IDirectFBSurface *primarySurface) static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value) { Q_ASSERT(value); - QRegExp rx(QString("%1=?(\\d+)").arg(variable)); + QRegExp rx(QString::fromLatin1("%1=?(\\d+)").arg(variable)); rx.setCaseSensitivity(Qt::CaseInsensitive); if (arguments.indexOf(rx) != -1) { *value = rx.cap(1).toInt(); @@ -870,36 +1050,6 @@ static inline bool setIntOption(const QStringList &arguments, const QString &var return false; } -static inline int depth(QImage::Format format) -{ - switch (format) { - case QImage::Format_Mono: - case QImage::Format_MonoLSB: - return 1; - case QImage::Format_Indexed8: - return 8; - case QImage::Format_RGB32: - case QImage::Format_ARGB32: - case QImage::Format_ARGB32_Premultiplied: - return 32; - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_RGB666: - case QImage::Format_ARGB6666_Premultiplied: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_RGB888: - return 24; - case QImage::Format_RGB555: - case QImage::Format_RGB444: - case QImage::Format_RGB16: - case QImage::Format_ARGB4444_Premultiplied: - return 16; - case QImage::Format_Invalid: - case QImage::NImageFormats: - break; - } - return -1; -} - bool QDirectFBScreen::connect(const QString &displaySpec) { DFBResult result = DFB_OK; @@ -949,7 +1099,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec) #ifdef QT_DIRECTFB_IMAGECACHE int imageCacheSize = 4 * 1024 * 1024; // 4 MB - ::setIntOption(displayArgs, QLatin1String("imagecachesize"), &imageCacheSize); + setIntOption(displayArgs, QLatin1String("imagecachesize"), &imageCacheSize); QDirectFBPaintEngine::initImageCache(imageCacheSize); #endif @@ -991,7 +1141,7 @@ bool QDirectFBScreen::connect(const QString &displaySpec) } // We don't track the primary surface as it's released in disconnect - d_ptr->primarySurface = createDFBSurface(description, DontTrackSurface); + d_ptr->primarySurface = createDFBSurface(description, DontTrackSurface, &result); if (!d_ptr->primarySurface) { DirectFBError("QDirectFBScreen: error creating primary surface", result); @@ -1002,13 +1152,17 @@ bool QDirectFBScreen::connect(const QString &displaySpec) #else description.flags = DSDESC_WIDTH|DSDESC_HEIGHT; description.width = description.height = 1; - surface = createDFBSurface(description, DontTrackSurface); + 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 - d_ptr->alphaPixmapFormat = QDirectFBScreen::getImageFormat(surface); + QImage::Format pixelFormat = QDirectFBScreen::getImageFormat(surface); + d_ptr->alphaPixmapFormat = pixelFormat; - setPixelFormat(d_ptr->alphaPixmapFormat); - switch (d_ptr->alphaPixmapFormat) { + switch (pixelFormat) { case QImage::Format_RGB666: d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied; break; @@ -1016,9 +1170,9 @@ bool QDirectFBScreen::connect(const QString &displaySpec) d_ptr->alphaPixmapFormat = QImage::Format_ARGB4444_Premultiplied; break; case QImage::Format_RGB32: - qWarning("QDirectFBScreen::connect(). Qt/DirectFB does not work with the RGB32 pixelformat. " - "We recommmend using ARGB instead"); - return false; + 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; @@ -1040,12 +1194,39 @@ bool QDirectFBScreen::connect(const QString &displaySpec) // works already break; } - - QScreen::d = ::depth(pixelFormat()); + 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 result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, DLID_PRIMARY, &d_ptr->dfbLayer); @@ -1058,26 +1239,35 @@ bool QDirectFBScreen::connect(const QString &displaySpec) #else result = d_ptr->dfb->GetScreen(d_ptr->dfb, 0, &d_ptr->dfbScreen); #endif - if (result != DFB_OK) { - DirectFBError("QDirectFBScreen::connect: " - "Unable to get screen!", result); - return false; - } - result = d_ptr->dfbScreen->GetSize(d_ptr->dfbScreen, &w, &h); - if (result != DFB_OK) { - DirectFBError("QDirectFBScreen::connect: " - "Unable to get screen size!", result); + + 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) + 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); + setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth); + setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight); const int dpi = 72; if (physWidth < 0) physWidth = qRound(dw * 25.4 / dpi); @@ -1090,23 +1280,31 @@ bool QDirectFBScreen::connect(const QString &displaySpec) if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive)) printDirectFBInfo(d_ptr->dfb, surface); #endif -#ifndef QT_NO_DIRECTFB_WM +#ifdef QT_DIRECTFB_WM surface->Release(surface); -#endif - - QRegExp backgroundColorRegExp("bgcolor=?(.+)"); +#else + QRegExp backgroundColorRegExp(QLatin1String("bgcolor=?(.+)")); backgroundColorRegExp.setCaseSensitivity(Qt::CaseInsensitive); if (displayArgs.indexOf(backgroundColorRegExp) != -1) { d_ptr->backgroundColor.setNamedColor(backgroundColorRegExp.cap(1)); } if (!d_ptr->backgroundColor.isValid()) d_ptr->backgroundColor = Qt::green; + d_ptr->primarySurface->Clear(d_ptr->primarySurface, d_ptr->backgroundColor.red(), + d_ptr->backgroundColor.green(), d_ptr->backgroundColor.blue(), + d_ptr->backgroundColor.alpha()); + d_ptr->primarySurface->Flip(d_ptr->primarySurface, 0, d_ptr->flipFlags); +#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; @@ -1143,12 +1341,10 @@ bool QDirectFBScreen::initDevice() } #endif -#ifndef QT_NO_QWS_CURSOR -#if defined QT_NO_DIRECTFB_WM || defined QT_NO_DIRECTFB_LAYER - QScreenCursor::initSoftwareCursor(); -#else +#ifdef QT_DIRECTFB_CURSOR qt_screencursor = new QDirectFBScreenCursor; -#endif +#elif !defined QT_NO_QWS_CURSOR + QScreenCursor::initSoftwareCursor(); #endif return true; } @@ -1202,88 +1398,149 @@ QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const return QScreen::createSurface(key); } -// Normally, when using DirectFB to compose the windows (I.e. when -// QT_NO_DIRECTFB_WM isn't set), exposeRegion will simply return. If -// QT_NO_DIRECTFB_WM is set, exposeRegion will compose only non-directFB -// window surfaces. Normal, directFB surfaces are handled by DirectFB. -void QDirectFBScreen::exposeRegion(QRegion r, int changing) +#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) { -#ifdef QT_NO_DIRECTFB_WM - const QList<QWSWindow*> windows = QWSServer::instance()->clientWindows(); - if (changing < 0 || changing >= windows.size()) - return; + 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 - QWSWindow *win = windows.at(changing); - QWSWindowSurface *s = win->windowSurface(); r &= region(); - if (r.isEmpty()) + if (r.isEmpty()) { return; + } + r = r.boundingRect(); - const QRect brect = 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; + } - if (!s) { - solidFill(d_ptr->backgroundColor, r); - } else { - const QRect windowGeometry = s->geometry(); - const QRegion outsideWindow = r.subtracted(windowGeometry); - if (!outsideWindow.isEmpty()) { - solidFill(d_ptr->backgroundColor, outsideWindow); + 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; + } } - const QRegion insideWindow = r.intersected(windowGeometry); - if (!insideWindow.isEmpty()) { - QDirectFBWindowSurface *dfbWindowSurface = (s->key() == QLatin1String("directfb")) - ? static_cast<QDirectFBWindowSurface*>(s) : 0; - if (dfbWindowSurface) { - IDirectFBSurface *surface = dfbWindowSurface->directFBSurface(); - const int n = insideWindow.numRects(); - if (n == 1 || d_ptr->directFBFlags & BoundingRectFlip) { - const QRect source = (insideWindow.boundingRect().intersected(windowGeometry)).translated(-windowGeometry.topLeft()); - const DFBRectangle rect = { - source.x(), source.y(), source.width(), source.height() - }; - d_ptr->primarySurface->Blit(d_ptr->primarySurface, surface, &rect, - windowGeometry.x() + source.x(), - windowGeometry.y() + source.y()); - } else { - const QVector<QRect> rects = insideWindow.rects(); - QVarLengthArray<DFBRectangle, 16> dfbRectangles(n); - QVarLengthArray<DFBPoint, 16> dfbPoints(n); - - for (int i=0; i<n; ++i) { - const QRect source = (rects.at(i).intersected(windowGeometry)).translated(-windowGeometry.topLeft()); - DFBRectangle &rect = dfbRectangles[i]; - rect.x = source.x(); - rect.y = source.y(); - rect.w = source.width(); - rect.h = source.height(); - dfbPoints[i].x = (windowGeometry.x() + source.x()); - dfbPoints[i].y = (windowGeometry.y() + source.y()); - } - d_ptr->primarySurface->BatchBlit(d_ptr->primarySurface, surface, dfbRectangles.constData(), - dfbPoints.constData(), n); - } + ++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); + } + } + if (!region.isEmpty()) { + 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 ®ion = cmd.source; + const int rectCount = region.numRects(); + 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() && cursorRectangle.intersects(brect)) { + if (cursor->isVisible() && !cursor->isAccelerated() && r.intersects(cursorRectangle)) { const QImage image = cursor->image(); - IDirectFBSurface *surface = createDFBSurface(image, QDirectFBScreen::DontTrackSurface); - d_ptr->primarySurface->SetBlittingFlags(d_ptr->primarySurface, DSBLIT_BLEND_ALPHACHANNEL); - d_ptr->primarySurface->Blit(d_ptr->primarySurface, surface, 0, cursorRectangle.x(), cursorRectangle.y()); - surface->Release(surface); -#if (Q_DIRECTFB_VERSION >= 0x010000) - d_ptr->primarySurface->ReleaseSource(d_ptr->primarySurface); -#endif + 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()); } } - flipSurface(d_ptr->primarySurface, d_ptr->flipFlags, r, QPoint()); -#else - Q_UNUSED(r); - Q_UNUSED(changing); +#endif + flipSurface(primary, d_ptr->flipFlags, r, QPoint()); + primary->SetBlittingFlags(primary, DSBLIT_NOFX); #endif } @@ -1297,10 +1554,10 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) return; d_ptr->primarySurface->SetColor(d_ptr->primarySurface, - color.red(), color.green(), color.blue(), - color.alpha()); + color.red(), color.green(), color.blue(), + color.alpha()); const int n = region.numRects(); - if (n > 1) { + if (n == 1) { const QRect r = region.boundingRect(); d_ptr->primarySurface->FillRectangle(d_ptr->primarySurface, r.x(), r.y(), r.width(), r.height()); } else { @@ -1318,11 +1575,6 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) #endif } -void QDirectFBScreen::erase(const QRegion ®ion) -{ - solidFill(d_ptr->backgroundColor, region); -} - QImage::Format QDirectFBScreen::alphaPixmapFormat() const { return d_ptr->alphaPixmapFormat; @@ -1347,10 +1599,10 @@ bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *d return true; } -uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, uint flags, int *bpl) +uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl) { void *mem; - const DFBResult result = surface->Lock(surface, static_cast<DFBSurfaceLockFlags>(flags), static_cast<void**>(&mem), bpl); + const DFBResult result = surface->Lock(surface, flags, &mem, bpl); if (result != DFB_OK) { DirectFBError("QDirectFBScreen::lockSurface()", result); } @@ -1385,4 +1637,91 @@ void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags } } +#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 + +#ifndef QT_DIRECTFB_PLUGIN +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 +#endif + +QT_END_NAMESPACE + +#include "qdirectfbscreen.moc" +#endif // QT_NO_QWS_DIRECTFB diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 3f9248e..5e8c5c6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,14 +42,21 @@ #ifndef QDIRECTFBSCREEN_H #define QDIRECTFBSCREEN_H +#include <qglobal.h> +#ifndef QT_NO_QWS_DIRECTFB #include <QtGui/qscreen_qws.h> #include <directfb.h> #include <directfb_version.h> QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + QT_MODULE(Gui) +#if !defined QT_NO_DIRECTFB_SUBSURFACE && !defined QT_DIRECTFB_SUBSURFACE +#define QT_DIRECTFB_SUBSURFACE +#endif #if !defined QT_NO_DIRECTFB_LAYER && !defined QT_DIRECTFB_LAYER #define QT_DIRECTFB_LAYER #endif @@ -59,8 +66,17 @@ QT_MODULE(Gui) #if !defined QT_DIRECTFB_IMAGECACHE && !defined QT_NO_DIRECTFB_IMAGECACHE #define QT_NO_DIRECTFB_IMAGECACHE #endif -#if !defined QT_NO_DIRECTFB_PALETTE && !defined QT_DIRECTFB_PALETTE -#define QT_DIRECTFB_PALETTE +#if !defined QT_NO_DIRECTFB_IMAGEPROVIDER && !defined QT_DIRECTFB_IMAGEPROVIDER +#define QT_DIRECTFB_IMAGEPROVIDER +#endif +#if !defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE && !defined QT_NO_DIRECTFB_IMAGEPROVIDER_KEEPALIVE +#define QT_NO_DIRECTFB_IMAGEPROVIDER_KEEPALIVE +#endif +#if !defined QT_DIRECTFB_WINDOW_AS_CURSOR && !defined QT_NO_DIRECTFB_WINDOW_AS_CURSOR +#define QT_NO_DIRECTFB_WINDOW_AS_CURSOR +#endif +#if !defined QT_DIRECTFB_PALETTE && !defined QT_NO_DIRECTFB_PALETTE +#define QT_NO_DIRECTFB_PALETTE #endif #if !defined QT_NO_DIRECTFB_PREALLOCATED && !defined QT_DIRECTFB_PREALLOCATED #define QT_DIRECTFB_PREALLOCATED @@ -74,8 +90,27 @@ QT_MODULE(Gui) #if !defined QT_NO_DIRECTFB_OPAQUE_DETECTION && !defined QT_DIRECTFB_OPAQUE_DETECTION #define QT_DIRECTFB_OPAQUE_DETECTION #endif +#ifndef QT_NO_QWS_CURSOR +#if defined QT_DIRECTFB_WM && defined QT_DIRECTFB_WINDOW_AS_CURSOR +#define QT_DIRECTFB_CURSOR +#elif defined QT_DIRECTFB_LAYER +#define QT_DIRECTFB_CURSOR +#endif +#endif +#ifndef QT_DIRECTFB_CURSOR +#define QT_NO_DIRECTFB_CURSOR +#endif +#if defined QT_NO_DIRECTFB_LAYER && defined QT_DIRECTFB_WM +#error QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM +#endif +#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE && defined QT_NO_DIRECTFB_IMAGEPROVIDER +#error QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE requires QT_DIRECTFB_IMAGEPROVIDER to be defined +#endif +#if defined QT_DIRECTFB_WINDOW_AS_CURSOR && defined QT_NO_DIRECTFB_WM +#error QT_DIRECTFB_WINDOW_AS_CURSOR requires QT_DIRECTFB_WM to be defined +#endif -#define Q_DIRECTFB_VERSION ((DIRECTFB_MAJOR_VERSION << 16) | (DIRECTFB_MINOR_VERION << 8) | DIRECTFB_MICRO_VERSION) +#define Q_DIRECTFB_VERSION ((DIRECTFB_MAJOR_VERSION << 16) | (DIRECTFB_MINOR_VERSION << 8) | DIRECTFB_MICRO_VERSION) #define DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(F) \ static inline F operator~(F f) { return F(~int(f)); } \ @@ -86,6 +121,8 @@ QT_MODULE(Gui) DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBInputDeviceCapabilities); DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowDescriptionFlags); +DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowCapabilities); +DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBWindowOptions); DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceDescriptionFlags); DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceCapabilities); DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(DFBSurfaceLockFlags); @@ -132,8 +169,15 @@ public: return static_cast<QDirectFBScreen*>(inst); } + void waitIdle(); + IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const; +#ifdef QT_DIRECTFB_SUBSURFACE + IDirectFBSurface *subSurfaceForWidget(const QWidget *widget, const QRect &area = QRect()) const; +#endif IDirectFB *dfb(); -#ifdef QT_NO_DIRECTFB_WM +#ifdef QT_DIRECTFB_WM + IDirectFBWindow *windowForWidget(const QWidget *widget) const; +#else IDirectFBSurface *primarySurface(); #endif #ifndef QT_NO_DIRECTFB_LAYER @@ -142,38 +186,49 @@ public: // Track surface creation/release so we can release all on exit enum SurfaceCreationOption { - DontTrackSurface = 0, - TrackSurface = 1 + DontTrackSurface = 0x1, + TrackSurface = 0x2, + NoPreallocated = 0x4 }; Q_DECLARE_FLAGS(SurfaceCreationOptions, SurfaceCreationOption); IDirectFBSurface *createDFBSurface(const QImage &image, - SurfaceCreationOptions options); + QImage::Format format, + SurfaceCreationOptions options, + DFBResult *result = 0); IDirectFBSurface *createDFBSurface(const QSize &size, QImage::Format format, - SurfaceCreationOptions options); + SurfaceCreationOptions options, + DFBResult *result = 0); IDirectFBSurface *copyDFBSurface(IDirectFBSurface *src, QImage::Format format, - SurfaceCreationOptions options); - IDirectFBSurface *copyToDFBSurface(const QImage &image, - QImage::Format format, - SurfaceCreationOptions options); + SurfaceCreationOptions options, + DFBResult *result = 0); + IDirectFBSurface *createDFBSurface(DFBSurfaceDescription desc, + SurfaceCreationOptions options, + DFBResult *result); +#ifdef QT_DIRECTFB_SUBSURFACE + IDirectFBSurface *getSubSurface(IDirectFBSurface *surface, + const QRect &rect, + SurfaceCreationOptions options, + DFBResult *result); +#endif + void flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags, const QRegion ®ion, const QPoint &offset); void releaseDFBSurface(IDirectFBSurface *surface); - void erase(const QRegion ®ion); using QScreen::depth; static int depth(DFBSurfacePixelFormat format); + static int depth(QImage::Format format); static DFBSurfacePixelFormat getSurfacePixelFormat(QImage::Format format); - static DFBSurfaceDescription getSurfaceDescription(const QImage &image); static DFBSurfaceDescription getSurfaceDescription(const uint *buffer, int length); static QImage::Format getImageFormat(IDirectFBSurface *surface); static bool initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format); static inline bool isPremultiplied(QImage::Format format); - static inline bool hasAlpha(DFBSurfacePixelFormat format); - static inline bool hasAlpha(IDirectFBSurface *surface); + static inline bool hasAlphaChannel(DFBSurfacePixelFormat format); + static inline bool hasAlphaChannel(IDirectFBSurface *surface); QImage::Format alphaPixmapFormat() const; #ifndef QT_NO_DIRECTFB_PALETTE @@ -181,12 +236,12 @@ public: const QImage &image); #endif - static uchar *lockSurface(IDirectFBSurface *surface, uint flags, int *bpl = 0); + static uchar *lockSurface(IDirectFBSurface *surface, DFBSurfaceLockFlags flags, int *bpl = 0); +#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE + void setDirectFBImageProvider(IDirectFBImageProvider *provider); +#endif private: - IDirectFBSurface *createDFBSurface(DFBSurfaceDescription desc, - SurfaceCreationOptions options); QDirectFBScreenPrivate *d_ptr; - friend class SurfaceCache; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDirectFBScreen::SurfaceCreationOptions); @@ -207,7 +262,7 @@ inline bool QDirectFBScreen::isPremultiplied(QImage::Format format) return false; } -inline bool QDirectFBScreen::hasAlpha(DFBSurfacePixelFormat format) +inline bool QDirectFBScreen::hasAlphaChannel(DFBSurfacePixelFormat format) { switch (format) { case DSPF_ARGB1555: @@ -232,14 +287,18 @@ inline bool QDirectFBScreen::hasAlpha(DFBSurfacePixelFormat format) } } -inline bool QDirectFBScreen::hasAlpha(IDirectFBSurface *surface) +inline bool QDirectFBScreen::hasAlphaChannel(IDirectFBSurface *surface) { Q_ASSERT(surface); DFBSurfacePixelFormat format; surface->GetPixelFormat(surface, &format); - return QDirectFBScreen::hasAlpha(format); + return QDirectFBScreen::hasAlphaChannel(format); } +QT_END_NAMESPACE + QT_END_HEADER +#endif // QT_NO_QWS_DIRECTFB #endif // QDIRECTFBSCREEN_H + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp index 9fcb946..24e4599 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -43,6 +43,7 @@ #include <QtGui/qscreendriverplugin_qws.h> #include <QtCore/qstringlist.h> +#ifndef QT_NO_QWS_DIRECTFB class DirectFBScreenDriverPlugin : public QScreenDriverPlugin { @@ -73,3 +74,5 @@ QScreen* DirectFBScreenDriverPlugin::create(const QString& driver, } Q_EXPORT_PLUGIN2(qdirectfbscreen, DirectFBScreenDriverPlugin) + +#endif diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index 584f334..19103cb 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -43,15 +43,19 @@ #include "qdirectfbscreen.h" #include "qdirectfbpaintengine.h" +#include <private/qwidget_p.h> #include <qwidget.h> #include <qwindowsystem_qws.h> #include <qpaintdevice.h> #include <qvarlengtharray.h> -//#define QT_DIRECTFB_DEBUG_SURFACES 1 +#ifndef QT_NO_QWS_DIRECTFB + +QT_BEGIN_NAMESPACE QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) : QDirectFBPaintDevice(scr) + , sibling(0) #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) #endif @@ -70,6 +74,7 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) : QWSWindowSurface(widget), QDirectFBPaintDevice(scr) + , sibling(0) #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) #endif @@ -96,6 +101,8 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect QDirectFBWindowSurface::~QDirectFBWindowSurface() { + releaseSurface(); + // these are not tracked by QDirectFBScreen so we don't want QDirectFBPaintDevice to release it } bool QDirectFBWindowSurface::isValid() const @@ -103,20 +110,36 @@ bool QDirectFBWindowSurface::isValid() const return true; } -#ifndef QT_NO_DIRECTFB_WM -void QDirectFBWindowSurface::createWindow() +#ifdef QT_DIRECTFB_WM +void QDirectFBWindowSurface::raise() +{ + if (IDirectFBWindow *window = directFBWindow()) { + window->RaiseToTop(window); + } +} + +IDirectFBWindow *QDirectFBWindowSurface::directFBWindow() const +{ + return (dfbWindow ? dfbWindow : (sibling ? sibling->dfbWindow : 0)); +} + + +void QDirectFBWindowSurface::createWindow(const QRect &rect) { -#ifdef QT_NO_DIRECTFB_LAYER -#error QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM -#else IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); if (!layer) qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); DFBWindowDescription description; - description.caps = DWCAPS_NODECORATION; - description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT; + memset(&description, 0, sizeof(DFBWindowDescription)); + + description.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER; + description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT|DWDESC_HEIGHT|DWDESC_WIDTH|DWDESC_POSX|DWDESC_POSY; + description.posx = rect.x(); + description.posy = rect.y(); + description.width = rect.width(); + description.height = rect.height(); description.surface_caps = DSCAPS_NONE; if (screen->directFBFlags() & QDirectFBScreen::VideoOnly) description.surface_caps |= DSCAPS_VIDEOONLY; @@ -126,6 +149,7 @@ void QDirectFBWindowSurface::createWindow() description.surface_caps = DSCAPS_PREMULTIPLIED; DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); + if (result != DFB_OK) DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result); @@ -133,12 +157,10 @@ void QDirectFBWindowSurface::createWindow() dfbSurface->Release(dfbSurface); dfbWindow->GetSurface(dfbWindow, &dfbSurface); -#endif + updateFormat(); } -#endif // QT_NO_DIRECTFB_WM -#ifndef QT_NO_DIRECTFB_WM -static DFBResult setGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect) +static DFBResult setWindowGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect) { DFBResult result = DFB_OK; const bool isMove = old.isEmpty() || rect.topLeft() != old.topLeft(); @@ -165,14 +187,27 @@ static DFBResult setGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const #endif return result; } -#endif +#endif // QT_NO_DIRECTFB_WM void QDirectFBWindowSurface::setGeometry(const QRect &rect) { -#ifdef QT_NO_DIRECTFB_WM - IDirectFBSurface *primarySurface = screen->primarySurface(); - Q_ASSERT(primarySurface); + const QRect oldRect = geometry(); + if (oldRect == rect) + return; + + IDirectFBSurface *oldSurface = dfbSurface; + const bool sizeChanged = oldRect.size() != rect.size(); + if (sizeChanged) { + delete engine; + engine = 0; + unlockSurface(); +#ifdef QT_DIRECTFB_SUBSURFACE + releaseSubSurface(); #endif + releaseSurface(); + Q_ASSERT(!dfbSurface); + } + if (rect.isNull()) { #ifndef QT_NO_DIRECTFB_WM if (dfbWindow) { @@ -180,26 +215,25 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) dfbWindow = 0; } #endif - if (dfbSurface) { -#ifdef QT_NO_DIRECTFB_WM - if (dfbSurface != primarySurface) + Q_ASSERT(!dfbSurface); +#ifdef QT_DIRECTFB_SUBSURFACE + Q_ASSERT(!subSurface); #endif - dfbSurface->Release(dfbSurface); - dfbSurface = 0; - } - } else if (rect != geometry()) { - const QRect oldRect = geometry(); - DFBResult result = DFB_OK; - // If we're in a resize, the surface shouldn't be locked - Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size())); + } else { #ifdef QT_DIRECTFB_WM - if (!dfbWindow) - createWindow(); - ::setGeometry(dfbWindow, oldRect, rect); + if (!dfbWindow) { + createWindow(rect); + } else { + setWindowGeometry(dfbWindow, oldRect, rect); + Q_ASSERT(!sizeChanged || !dfbSurface); + if (sizeChanged) + dfbWindow->GetSurface(dfbWindow, &dfbSurface); + } #else + IDirectFBSurface *primarySurface = screen->primarySurface(); + DFBResult result = DFB_OK; if (mode == Primary) { - if (dfbSurface && dfbSurface != primarySurface) - dfbSurface->Release(dfbSurface); + Q_ASSERT(primarySurface); if (rect == screen->region().boundingRect()) { dfbSurface = primarySurface; } else { @@ -207,65 +241,41 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect) rect.width(), rect.height() }; result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); } - } else { - if (!dfbSurface || oldRect.size() != rect.size()) { - if (dfbSurface) - dfbSurface->Release(dfbSurface); + } else { // mode == Offscreen + if (!dfbSurface) { dfbSurface = screen->createDFBSurface(rect.size(), screen->pixelFormat(), QDirectFBScreen::DontTrackSurface); } - const QRegion region = QRegion(oldRect.isEmpty() ? screen->region() : QRegion(oldRect)).subtracted(rect); - screen->erase(region); - screen->flipSurface(primarySurface, flipFlags, region, QPoint()); } -#endif - if (size() != geometry().size()) { - delete engine; - engine = 0; - } - if (result != DFB_OK) DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); +#endif } + if (oldSurface != dfbSurface) + updateFormat(); + QWSWindowSurface::setGeometry(rect); } QByteArray QDirectFBWindowSurface::permanentState() const { - QByteArray array; -#ifdef QT_NO_DIRECTFB_WM - array.resize(sizeof(SurfaceFlags) + sizeof(IDirectFBSurface*)); -#else - array.resize(sizeof(SurfaceFlags)); -#endif - char *ptr = array.data(); - - *reinterpret_cast<SurfaceFlags*>(ptr) = surfaceFlags(); - ptr += sizeof(SurfaceFlags); - -#ifdef QT_NO_DIRECTFB_WM - *reinterpret_cast<IDirectFBSurface**>(ptr) = dfbSurface; -#endif - return array; + QByteArray state(sizeof(this), 0); + *reinterpret_cast<const QDirectFBWindowSurface**>(state.data()) = this; + return state; } void QDirectFBWindowSurface::setPermanentState(const QByteArray &state) { - SurfaceFlags flags; - const char *ptr = state.constData(); - - flags = *reinterpret_cast<const SurfaceFlags*>(ptr); - setSurfaceFlags(flags); - -#ifdef QT_NO_DIRECTFB_WM - ptr += sizeof(SurfaceFlags); - dfbSurface = *reinterpret_cast<IDirectFBSurface* const*>(ptr); -#endif + if (state.size() == sizeof(this)) { + sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData()); + } } static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int dx, int dy) { const DFBRectangle rect = { r.x(), r.y(), r.width(), r.height() }; surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy); + const DFBRegion region = { rect.x + dx, rect.y + dy, r.right() + dx, r.bottom() + dy }; + surface->Flip(surface, ®ion, DSFLIP_BLIT); } bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) @@ -274,12 +284,12 @@ bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) return false; dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); if (region.numRects() == 1) { - ::scrollSurface(dfbSurface, region.boundingRect(), dx, dy); + scrollSurface(dfbSurface, region.boundingRect(), dx, dy); } else { const QVector<QRect> rects = region.rects(); const int n = rects.size(); for (int i=0; i<n; ++i) { - ::scrollSurface(dfbSurface, rects.at(i), dx, dy); + scrollSurface(dfbSurface, rects.at(i), dx, dy); } } return true; @@ -314,93 +324,48 @@ inline bool isWidgetOpaque(const QWidget *w) return false; } - -void QDirectFBWindowSurface::flush(QWidget *, const QRegion ®ion, +void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) { - // hw: make sure opacity information is updated before compositing - if (QWidget *win = window()) { + QWidget *win = window(); + if (!win) + return; - const bool opaque = isWidgetOpaque(win); - if (opaque != isOpaque()) { - SurfaceFlags flags = surfaceFlags(); - if (opaque) { - flags |= Opaque; - } else { - flags &= ~Opaque; - } - setSurfaceFlags(flags); + QWExtra *extra = qt_widget_private(widget)->extraData(); + if (extra && extra->proxyWidget) + return; + + // hw: make sure opacity information is updated before compositing + const bool opaque = isWidgetOpaque(win); + if (opaque != isOpaque()) { + SurfaceFlags flags = surfaceFlags(); + if (opaque) { + flags |= Opaque; + } else { + flags &= ~Opaque; } + setSurfaceFlags(flags); + } #ifndef QT_NO_DIRECTFB_WM - const quint8 winOpacity = quint8(win->windowOpacity() * 255); - quint8 opacity; + const quint8 winOpacity = quint8(win->windowOpacity() * 255); + quint8 opacity; - if (dfbWindow) { - dfbWindow->GetOpacity(dfbWindow, &opacity); - if (winOpacity != opacity) - dfbWindow->SetOpacity(dfbWindow, winOpacity); - } -#endif + if (dfbWindow) { + dfbWindow->GetOpacity(dfbWindow, &opacity); + if (winOpacity != opacity) + dfbWindow->SetOpacity(dfbWindow, winOpacity); } +#endif const QRect windowGeometry = QDirectFBWindowSurface::geometry(); #ifdef QT_NO_DIRECTFB_WM - IDirectFBSurface *primarySurface = screen->primarySurface(); if (mode == Offscreen) { - primarySurface->SetBlittingFlags(primarySurface, DSBLIT_NOFX); - const QRect windowRect(0, 0, windowGeometry.width(), windowGeometry.height()); - const int n = region.numRects(); - if (n == 1 || boundingRectFlip ) { - const QRect regionBoundingRect = region.boundingRect().translated(offset); - const QRect source = windowRect & regionBoundingRect; - const DFBRectangle rect = { - source.x(), source.y(), source.width(), source.height() - }; - primarySurface->Blit(primarySurface, dfbSurface, &rect, - windowGeometry.x() + source.x(), - windowGeometry.y() + source.y()); - } else { - const QVector<QRect> rects = region.rects(); - QVarLengthArray<DFBRectangle, 16> dfbRectangles(n); - QVarLengthArray<DFBPoint, 16> dfbPoints(n); - - for (int i=0; i<n; ++i) { - const QRect &r = rects.at(i).translated(offset); - const QRect source = windowRect & r; - DFBRectangle &rect = dfbRectangles[i]; - rect.x = source.x(); - rect.y = source.y(); - rect.w = source.width(); - rect.h = source.height(); - dfbPoints[i].x = (windowGeometry.x() + source.x()); - dfbPoints[i].y = (windowGeometry.y() + source.y()); - } - primarySurface->BatchBlit(primarySurface, dfbSurface, dfbRectangles.constData(), - dfbPoints.constData(), n); - } - } - - if (QScreenCursor *cursor = QScreenCursor::instance()) { - const QRect cursorRectangle = cursor->boundingRect(); - if (cursor->isVisible() && !cursor->isAccelerated() - && region.intersects(cursorRectangle.translated(-(offset + windowGeometry.topLeft())))) { - const QImage image = cursor->image(); + screen->exposeRegion(region.translated(offset + geometry().topLeft()), 0); - IDirectFBSurface *surface = screen->createDFBSurface(image, QDirectFBScreen::DontTrackSurface); - primarySurface->SetBlittingFlags(primarySurface, DSBLIT_BLEND_ALPHACHANNEL); - primarySurface->Blit(primarySurface, surface, 0, cursorRectangle.x(), cursorRectangle.y()); - surface->Release(surface); -#if (Q_DIRECTFB_VERSION >= 0x010000) - primarySurface->ReleaseSource(primarySurface); -#endif - } - } - if (mode == Offscreen) { - screen->flipSurface(primarySurface, flipFlags, region, offset + windowGeometry.topLeft()); } else #endif - screen->flipSurface(dfbSurface, flipFlags, region, offset); + screen->flipSurface(dfbSurface, flipFlags, region, offset); #ifdef QT_DIRECTFB_TIMING enum { Secs = 3 }; @@ -413,51 +378,75 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion ®ion, #endif } - void QDirectFBWindowSurface::beginPaint(const QRegion &) { - if (!engine) + if (!engine) { engine = new QDirectFBPaintEngine(this); + } } void QDirectFBWindowSurface::endPaint(const QRegion &) { -#ifdef QT_DIRECTFB_DEBUG_SURFACES - if (bufferImages.count()) { - qDebug("QDirectFBWindowSurface::endPaint() this=%p", this); - - foreach(QImage* bufferImg, bufferImages) - qDebug(" Deleting buffer image %p", bufferImg); - } +#ifdef QT_NO_DIRECTFB_SUBSURFACE + unlockSurface(); #endif +} - qDeleteAll(bufferImages); - bufferImages.clear(); - unlockDirectFB(); +IDirectFBSurface *QDirectFBWindowSurface::directFBSurface() const +{ + if (!dfbSurface && sibling && sibling->dfbSurface) + return sibling->dfbSurface; + return dfbSurface; } -QImage *QDirectFBWindowSurface::buffer(const QWidget *widget) +IDirectFBSurface *QDirectFBWindowSurface::surfaceForWidget(const QWidget *widget, QRect *rect) const { - if (!lockedImage) + Q_ASSERT(widget); + if (!dfbSurface) { + if (sibling && (!sibling->sibling || sibling->dfbSurface)) + return sibling->surfaceForWidget(widget, rect); return 0; + } + QWidget *win = window(); + Q_ASSERT(win); + if (rect) { + if (win == widget) { + *rect = widget->rect(); + } else { + *rect = QRect(widget->mapTo(win, QPoint(0, 0)), widget->size()); + } + } - const QRect rect = QRect(offset(widget), widget->size()) - & lockedImage->rect(); - if (rect.isEmpty()) - return 0; + Q_ASSERT(win == widget || win->isAncestorOf(widget)); + return dfbSurface; +} - QImage *img = new QImage(lockedImage->scanLine(rect.y()) - + rect.x() * (lockedImage->depth() / 8), - rect.width(), rect.height(), - lockedImage->bytesPerLine(), - lockedImage->format()); - bufferImages.append(img); +void QDirectFBWindowSurface::updateFormat() +{ + imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid; +} -#ifdef QT_DIRECTFB_DEBUG_SURFACES - qDebug("QDirectFBWindowSurface::buffer() Created & returned %p", img); +void QDirectFBWindowSurface::releaseSurface() +{ + if (dfbSurface) { +#ifdef QT_NO_DIRECTFB_SUBSURFACE + if (lockFlgs) + unlockSurface(); +#endif +#ifdef QT_NO_DIRECTFB_WM + Q_ASSERT(screen->primarySurface()); + if (dfbSurface != screen->primarySurface()) #endif - return img; + dfbSurface->Release(dfbSurface); + dfbSurface = 0; + } } + +QT_END_NAMESPACE + +#endif // QT_NO_QWS_DIRECTFB + + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index 64b1920..0dd3a3b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2009 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. @@ -9,8 +10,8 @@ ** 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 either Technology Preview License Agreement or the -** Beta Release License Agreement. +** 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 @@ -20,21 +21,20 @@ ** 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.0, included in the file LGPL_EXCEPTION.txt in this -** package. +** 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. +** +** +** +** +** +** ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. ** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -46,9 +46,10 @@ #include "qdirectfbpaintdevice.h" #include "qdirectfbscreen.h" +#ifndef QT_NO_QWS_DIRECTFB + #include <private/qpaintengine_raster_p.h> #include <private/qwindowsurface_qws_p.h> -#include <directfb.h> #ifdef QT_DIRECTFB_TIMING #include <qdatetime.h> @@ -56,6 +57,8 @@ QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + QT_MODULE(Gui) class QDirectFBWindowSurface : public QWSWindowSurface, public QDirectFBPaintDevice @@ -65,6 +68,9 @@ public: QDirectFBWindowSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen *scr, QWidget *widget); ~QDirectFBWindowSurface(); +#ifdef QT_DIRECTFB_WM + void raise(); +#endif bool isValid() const; void setGeometry(const QRect &rect); @@ -85,21 +91,26 @@ public: void beginPaint(const QRegion &); void endPaint(const QRegion &); - QImage *buffer(const QWidget *widget); -private: -#ifndef QT_NO_DIRECTFB_WM - void createWindow(); - IDirectFBWindow *dfbWindow; + IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const; + IDirectFBSurface *directFBSurface() const; +#ifdef QT_DIRECTFB_WM + IDirectFBWindow *directFBWindow() const; #endif +private: + void updateFormat(); + void releaseSurface(); + QDirectFBWindowSurface *sibling; -#ifdef QT_NO_DIRECTFB_WM +#ifdef QT_DIRECTFB_WM + void createWindow(const QRect &rect); + IDirectFBWindow *dfbWindow; +#else enum Mode { Primary, Offscreen } mode; #endif - QList<QImage*> bufferImages; DFBSurfaceFlipFlags flipFlags; bool boundingRectFlip; #ifdef QT_DIRECTFB_TIMING @@ -108,6 +119,10 @@ private: #endif }; +QT_END_NAMESPACE + QT_END_HEADER +#endif // QT_NO_QWS_DIRECTFB + #endif // QDIRECFBWINDOWSURFACE_H |