summaryrefslogtreecommitdiffstats
path: root/src/plugins/gfxdrivers/directfb
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gfxdrivers/directfb')
-rw-r--r--src/plugins/gfxdrivers/directfb/directfb.pro37
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp38
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.h41
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp55
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbmouse.h41
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp156
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h62
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp264
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h40
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp272
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h58
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp933
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h135
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreenplugin.cpp33
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp361
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h61
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 &region, 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 &region, 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 &region = 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 &region)
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 &region)
#endif
}
-void QDirectFBScreen::erase(const QRegion &region)
-{
- 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 &region, const QPoint &offset);
void releaseDFBSurface(IDirectFBSurface *surface);
- void erase(const QRegion &region);
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, &region, DSFLIP_BLIT);
}
bool QDirectFBWindowSurface::scroll(const QRegion &region, int dx, int dy)
@@ -274,12 +284,12 @@ bool QDirectFBWindowSurface::scroll(const QRegion &region, 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 &region,
+void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion &region,
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 &region,
#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