summaryrefslogtreecommitdiffstats
path: root/src/plugins/gfxdrivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/gfxdrivers')
-rw-r--r--src/plugins/gfxdrivers/directfb/directfb.pro3
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp37
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h5
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp97
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h1
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp244
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h33
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp694
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h95
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp179
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h18
-rw-r--r--src/plugins/gfxdrivers/hybrid/hybridscreen.cpp4
-rw-r--r--src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp2
-rw-r--r--src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp4
14 files changed, 956 insertions, 460 deletions
diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro
index 5c60b2f..c5da3df 100644
--- a/src/plugins/gfxdrivers/directfb/directfb.pro
+++ b/src/plugins/gfxdrivers/directfb/directfb.pro
@@ -6,6 +6,9 @@ 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_WINDOW_AS_CURSOR
+#DEFINES += QT_NO_DIRECTFB_IMAGEPROVIDER
+#DEFINES += QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
#DEFINES += QT_DIRECTFB_IMAGECACHE
#DEFINES += QT_NO_DIRECTFB_WM
#DEFINES += QT_NO_DIRECTFB_LAYER
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
index 3f114ab..dec4bdd 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp
@@ -47,7 +47,8 @@
QDirectFBPaintDevice::QDirectFBPaintDevice(QDirectFBScreen *scr)
: QCustomRasterPaintDevice(0), dfbSurface(0), lockedImage(0), screen(scr),
- lock(DFBSurfaceLockFlags(0)), mem(0), engine(0)
+ bpl(-1), lockFlgs(DFBSurfaceLockFlags(0)), mem(0), engine(0),
+ imageFormat(QImage::Format_Invalid)
{}
QDirectFBPaintDevice::~QDirectFBPaintDevice()
@@ -56,28 +57,25 @@ QDirectFBPaintDevice::~QDirectFBPaintDevice()
delete engine;
}
-
IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const
{
return dfbSurface;
}
-
void QDirectFBPaintDevice::lockDirectFB(DFBSurfaceLockFlags flags)
{
- if (!(lock & flags)) {
- if (lock)
+ if (!(lockFlgs & flags)) {
+ if (lockFlgs)
unlockDirectFB();
mem = QDirectFBScreen::lockSurface(dfbSurface, flags, &bpl);
Q_ASSERT(mem);
const QSize s = size();
lockedImage = new QImage(mem, s.width(), s.height(), bpl,
QDirectFBScreen::getImageFormat(dfbSurface));
- lock = flags;
+ lockFlgs = flags;
}
}
-
void QDirectFBPaintDevice::unlockDirectFB()
{
if (!lockedImage || !QDirectFBScreen::instance())
@@ -87,29 +85,26 @@ void QDirectFBPaintDevice::unlockDirectFB()
delete lockedImage;
lockedImage = 0;
mem = 0;
- lock = DFBSurfaceLockFlags(0);
+ lockFlgs = DFBSurfaceLockFlags(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);
+ that->lockDirectFB(DSLF_READ|DSLF_WRITE);
Q_ASSERT(bpl != -1);
}
return bpl;
@@ -128,18 +123,14 @@ int QDirectFBPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
if (!dfbSurface)
return 0;
- int w, h;
- dfbSurface->GetSize(dfbSurface, &w, &h);
-
switch (metric) {
case QPaintDevice::PdmWidth:
- return w;
case QPaintDevice::PdmHeight:
- return h;
+ return (metric == PdmWidth ? size().width() : size().height());
case QPaintDevice::PdmWidthMM:
- return (w * 1000) / dotsPerMeterX();
+ return (size().width() * 1000) / dotsPerMeterX();
case QPaintDevice::PdmHeightMM:
- return (h * 1000) / dotsPerMeterY();
+ return (size().height() * 1000) / dotsPerMeterY();
case QPaintDevice::PdmPhysicalDpiX:
case QPaintDevice::PdmDpiX:
return (dotsPerMeterX() * 254) / 10000; // 0.0254 meters-per-inch
@@ -147,11 +138,9 @@ 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)
+ if (lockedImage)
return lockedImage->numColors();
DFBResult result;
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
index b089980..ca958c8 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h
@@ -68,7 +68,7 @@ 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:
@@ -86,9 +86,10 @@ protected:
QImage *lockedImage;
QDirectFBScreen *screen;
int bpl;
- DFBSurfaceLockFlags lock;
+ DFBSurfaceLockFlags lockFlgs;
uchar *mem;
QDirectFBPaintEngine *engine;
+ QImage::Format imageFormat;
private:
Q_DISABLE_COPY(QDirectFBPaintDevice);
};
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
index c8e1081..337e75a 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp
@@ -53,6 +53,7 @@
#include <qmath.h>
#include <private/qpixmapdata_p.h>
#include <private/qpixmap_raster_p.h>
+#include <private/qimagepixmapcleanuphooks_p.h>
class SurfaceCache;
class QDirectFBPaintEnginePrivate : public QRasterPaintEnginePrivate
@@ -118,13 +119,14 @@ private:
IDirectFB *fb;
quint8 opacity;
- bool dirtyClip;
ClipType clipType;
QDirectFBPaintDevice *dfbDevice;
uint compositionModeStatus;
- QDirectFBPaintEngine *q;
+ bool inClip;
QRect currentClip;
+
+ QDirectFBPaintEngine *q;
friend class QDirectFBPaintEngine;
};
@@ -235,7 +237,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: \
@@ -296,8 +298,8 @@ bool QDirectFBPaintEngine::end()
void QDirectFBPaintEngine::clipEnabledChanged()
{
Q_D(QDirectFBPaintEngine);
- d->dirtyClip = true;
QRasterPaintEngine::clipEnabledChanged();
+ d->updateClip();
}
void QDirectFBPaintEngine::penChanged()
@@ -340,26 +342,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)
@@ -370,7 +395,6 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
if (brush == Qt::NoBrush && pen == Qt::NoPen)
return;
- d->updateClip();
if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
|| (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
|| !d->simplePen
@@ -400,7 +424,6 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
if (brush == Qt::NoBrush && pen == Qt::NoPen)
return;
- d->updateClip();
if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
|| (d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
|| !d->simplePen
@@ -425,7 +448,6 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
{
Q_D(QDirectFBPaintEngine);
- d->updateClip();
if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
|| !d->simplePen
@@ -447,7 +469,6 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
{
Q_D(QDirectFBPaintEngine);
- d->updateClip();
if (!(d->compositionModeStatus & QDirectFBPaintEnginePrivate::PorterDuff_SupportedPrimitives)
|| !d->simplePen
@@ -490,7 +511,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)
@@ -512,7 +532,7 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
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)
@@ -533,14 +553,15 @@ 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) {
+ || 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 = static_cast<QDirectFBPixmapData*>(pixmap.pixmapData())->buffer(DSLF_READ);
d->lock();
@@ -568,14 +589,14 @@ 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);
d->lock();
@@ -585,7 +606,7 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r,
QRasterPaintEngine::drawTiledPixmap(r, pix, offset);
} else {
d->unlock();
- d->drawTiledPixmap(r, pixmap, offset);
+ CLIPPED_PAINT(d->drawTiledPixmap(r, pixmap, offset));
}
}
@@ -673,7 +694,6 @@ 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: {
@@ -692,7 +712,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;
}
@@ -717,7 +738,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) {
@@ -728,8 +748,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
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()));
}
}
@@ -754,9 +773,7 @@ void QDirectFBPaintEngine::initImageCache(int size)
{
Q_ASSERT(size >= 0);
imageCache.setMaxCost(size);
- typedef void (*_qt_image_cleanup_hook_64)(qint64);
- extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64;
- qt_image_cleanup_hook_64 = ::cachedImageCleanupHook;
+ QImagePixmapCleanupHooks::instance()->addImageHook(cachedImageCleanupHook);
}
#endif // QT_DIRECTFB_IMAGECACHE
@@ -766,9 +783,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;
@@ -830,6 +847,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:
@@ -915,9 +939,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;
@@ -931,7 +955,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);
@@ -979,7 +1003,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();
@@ -1072,9 +1095,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) {
@@ -1096,14 +1117,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)
@@ -1114,7 +1133,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");
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h
index 3f6df57..51468ad 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.h
@@ -101,6 +101,7 @@ 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);
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index 4d909f2..2e3d32d 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -45,13 +45,14 @@
#include "qdirectfbpaintengine.h"
#include <QtGui/qbitmap.h>
+#include <QtCore/qfile.h>
#include <directfb.h>
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);
}
@@ -70,16 +71,21 @@ void QDirectFBPixmapData::resize(int width, int height)
return;
}
- format = screen->pixelFormat();
- dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height),
- format,
- QDirectFBScreen::TrackSurface);
+ imageFormat = screen->pixelFormat();
+ dfbSurface = screen->createDFBSurface(QSize(width, height),
+ imageFormat,
+ QDirectFBScreen::TrackSurface);
+ d = QDirectFBScreen::depth(imageFormat);
alpha = false;
if (!dfbSurface) {
invalidate();
qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface");
return;
}
+
+ w = width;
+ h = height;
+ is_null = (w <= 0 || h <= 0);
setSerialNumber(++global_ser_no);
}
@@ -162,33 +168,200 @@ bool QDirectFBPixmapData::hasAlphaChannel(const QImage &img)
#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;
+ }
+
+ QDirectFBPointer<IDirectFBSurface> surfaceFromDescription;
+ surfaceFromDescription.reset(screen->createDFBSurface(surfaceDescription, QDirectFBScreen::DontTrackSurface, &result));
+ if (!surfaceFromDescription) {
+ DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't create surface", result);
+ return false;
+ }
+
+ result = provider->RenderTo(provider.data(), surfaceFromDescription.data(), 0);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't render to surface", 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);
+ if (alpha)
+ dfbSurface->Clear(dfbSurface, 0, 0, 0, 0);
+
+ DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX;
+ if (imageDescription.caps & DICAPS_COLORKEY) {
+ blittingFlags |= DSBLIT_SRC_COLORKEY;
+ result = surfaceFromDescription->SetSrcColorKey(surfaceFromDescription.data(),
+ imageDescription.colorkey_r,
+ imageDescription.colorkey_g,
+ imageDescription.colorkey_b);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::fromSurfaceDescription: Can't set src color key", result);
+ invalidate(); // release dfbSurface
+ return false;
+ }
+ }
+ if (imageDescription.caps & DICAPS_ALPHACHANNEL) {
+ blittingFlags |= DSBLIT_BLEND_ALPHACHANNEL;
+ }
+ result = dfbSurface->SetBlittingFlags(dfbSurface, blittingFlags);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::fromSurfaceDescription: Can't set blitting flags", result);
+ invalidate(); // release dfbSurface
+ return false;
+ }
+
+ result = dfbSurface->Blit(dfbSurface, surfaceFromDescription.data(), 0, 0, 0);
+ if (result != DFB_OK) {
+ DirectFBError("QDirectFBPixmapData::fromSurfaceDescription: Can't blit to surface", result);
+ invalidate(); // release dfbSurface
+ return false;
+ }
+ if (blittingFlags != DSBLIT_NOFX) {
+ dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX);
+ }
+
+
+ w = surfaceDescription.width;
+ h = surfaceDescription.height;
+ is_null = (w <= 0 || h <= 0);
+ d = QDirectFBScreen::depth(imageFormat);
+ setSerialNumber(++global_ser_no);
+#if (Q_DIRECTFB_VERSION >= 0x010000)
+ dfbSurface->ReleaseSource(dfbSurface);
+#endif
+#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ screen->setDirectFBImageProvider(providerPtr);
+ provider.take();
#endif
- const QImage img = (i.depth() == 1 ? i.convertToFormat(screen->alphaPixmapFormat()) : i);
- if (img.hasAlphaChannel()
+
+ return true;
+}
+
+#endif
+
+void QDirectFBPixmapData::fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags)
+{
+ if (image.depth() == 1) {
+ fromImage(image.convertToFormat(screen->alphaPixmapFormat()), flags);
+ return;
+ }
+
+ if (image.hasAlphaChannel()
#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION
- && (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(img))
+ && (flags & Qt::NoOpaqueDetection || QDirectFBPixmapData::hasAlphaChannel(image))
#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);
+
+ dfbSurface = screen->createDFBSurface(image, imageFormat, QDirectFBScreen::TrackSurface|QDirectFBScreen::NoPreallocated);
if (!dfbSurface) {
qWarning("QDirectFBPixmapData::fromImage()");
invalidate();
return;
}
+ w = image.width();
+ h = image.height();
+ is_null = (w <= 0 || h <= 0);
+ 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)
@@ -199,14 +372,15 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
}
unlockDirectFB();
- IDirectFBSurface *src = static_cast<const QDirectFBPixmapData*>(data)->directFBSurface();
+ const QDirectFBPixmapData *otherData = static_cast<const QDirectFBPixmapData*>(data);
+ 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()");
@@ -222,6 +396,10 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect)
}
const DFBRectangle blitRect = { rect.x(), rect.y(),
rect.width(), rect.height() };
+ w = rect.width();
+ h = rect.height();
+ d = otherData->d;
+ is_null = (w <= 0 || h <= 0);
DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0);
#if (Q_DIRECTFB_VERSION >= 0x010000)
dfbSurface->ReleaseSource(dfbSurface);
@@ -260,11 +438,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) {
@@ -294,9 +473,6 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
}
that->unlockDirectFB();
- int w, h;
- dfbSurface->GetSize(dfbSurface, &w, &h);
-
const QSize size = transform.mapRect(QRect(0, 0, w, h)).size();
if (size.isEmpty())
return QPixmap();
@@ -308,7 +484,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);
@@ -317,6 +493,10 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform,
const DFBRectangle destRect = { 0, 0, size.width(), size.height() };
data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect);
+ data->w = size.width();
+ data->h = size.height();
+ data->is_null = (data->w <= 0 || data->h <= 0);
+
#if (Q_DIRECTFB_VERSION >= 0x010000)
data->dfbSurface->ReleaseSource(data->dfbSurface);
#endif
@@ -333,7 +513,7 @@ QImage QDirectFBPixmapData::toImage() const
// DirectFB not to move the surface to videomemory. When that
// happens we can use this (hopefully faster) codepath
#ifndef QT_NO_DIRECTFB_PREALLOCATED
- QImage ret(size(), QDirectFBScreen::getImageFormat(dfbSurface));
+ QImage ret(w, h, QDirectFBScreen::getImageFormat(dfbSurface));
if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) {
if (hasAlphaChannel()) {
imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL);
@@ -383,8 +563,14 @@ QImage * QDirectFBPixmapData::buffer(DFBSurfaceLockFlags lockFlags)
void QDirectFBPixmapData::invalidate()
{
+ if (dfbSurface) {
+ screen->releaseDFBSurface(dfbSurface);
+ dfbSurface = 0;
+ }
setSerialNumber(0);
alpha = false;
- format = QImage::Format_Invalid;
+ d = w = h = 0;
+ is_null = true;
+ imageFormat = QImage::Format_Invalid;
}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
index 710e4b9..8bf1e73 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h
@@ -60,25 +60,34 @@ public:
~QDirectFBPixmapData();
// Re-implemented from QPixmapData:
- void resize(int width, int height);
- void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
- void copy(const QPixmapData *data, const QRect &rect);
- void fill(const QColor &color);
- inline bool hasAlphaChannel() const { return alpha; }
- QPixmap transformed(const QTransform &matrix,
- Qt::TransformationMode mode) const;
- QImage toImage() const;
- QPaintEngine* paintEngine() const;
+ 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,
+ Qt::TransformationMode mode) const;
+ 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
- int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);}
- inline QImage::Format pixelFormat() const { return format; }
+ 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;
};
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index 1844c0d..8be0355 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -56,21 +56,29 @@
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;
- IDirectFBSurface *dfbSurface;
DFBSurfaceFlipFlags flipFlags;
+ QDirectFBScreen::DirectFBFlags directFBFlags;
+ QImage::Format alphaPixmapFormat;
+ IDirectFBScreen *dfbScreen;
+#ifdef QT_NO_DIRECTFB_WM
+ IDirectFBSurface *primarySurface;
+#endif
#ifndef QT_NO_DIRECTFB_LAYER
IDirectFBDisplayLayer *dfbLayer;
#endif
- IDirectFBScreen *dfbScreen;
-
QSet<IDirectFBSurface*> allocatedSurfaces;
#ifndef QT_NO_DIRECTFB_MOUSE
@@ -79,31 +87,43 @@ public:
#ifndef QT_NO_DIRECTFB_KEYBOARD
QDirectFBKeyboardHandler *keyboard;
#endif
- QDirectFBScreen::DirectFBFlags directFBFlags;
- QImage::Format alphaPixmapFormat;
+#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ IDirectFBImageProvider *imageProvider;
+#endif
QColor backgroundColor;
QDirectFBScreen *q;
};
+#include "qdirectfbscreen.moc"
+
QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *qptr)
- : QWSGraphicsSystem(qptr), dfb(0), dfbSurface(0), flipFlags(DSFLIP_NONE)
+ : QWSGraphicsSystem(qptr), dfb(0), flipFlags(DSFLIP_NONE),
+ directFBFlags(QDirectFBScreen::NoFlags), alphaPixmapFormat(QImage::Format_Invalid),
+ dfbScreen(0)
+#ifdef QT_NO_DIRECTFB_WM
+ , primarySurface(0)
+#endif
#ifndef QT_NO_DIRECTFB_LAYER
, dfbLayer(0)
#endif
- , dfbScreen(0)
#ifndef QT_NO_DIRECTFB_MOUSE
, mouse(0)
#endif
#ifndef QT_NO_DIRECTFB_KEYBOARD
, keyboard(0)
#endif
- , directFBFlags(QDirectFBScreen::NoFlags)
- , alphaPixmapFormat(QImage::Format_Invalid)
+#if defined QT_DIRECTFB_IMAGEPROVIDER && defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ , imageProvider(0)
+#endif
, 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()
@@ -114,13 +134,19 @@ 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);
}
- if (dfbSurface)
- dfbSurface->Release(dfbSurface);
+#ifdef QT_NO_DIRECTFB_WM
+ if (primarySurface)
+ primarySurface->Release(primarySurface);
+#endif
#ifndef QT_NO_DIRECTFB_LAYER
if (dfbLayer)
@@ -134,64 +160,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)
@@ -207,7 +246,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));
@@ -216,12 +256,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) {
@@ -283,68 +325,6 @@ IDirectFBSurface *QDirectFBScreen::createDFBSurface(DFBSurfaceDescription desc,
return newSurface;
}
-IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img,
- QImage::Format pixmapFormat,
- SurfaceCreationOptions options)
-{
- 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(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);
- }
-#endif
- return dfbSurface;
-}
-
void QDirectFBScreen::releaseDFBSurface(IDirectFBSurface *surface)
{
Q_ASSERT(QDirectFBScreen::instance());
@@ -366,10 +346,12 @@ IDirectFB *QDirectFBScreen::dfb()
return d_ptr->dfb;
}
-IDirectFBSurface *QDirectFBScreen::dfbSurface()
+#ifdef QT_NO_DIRECTFB_WM
+IDirectFBSurface *QDirectFBScreen::primarySurface()
{
- return d_ptr->dfbSurface;
+ return d_ptr->primarySurface;
}
+#endif
#ifndef QT_NO_DIRECTFB_LAYER
IDirectFBDisplayLayer *QDirectFBScreen::dfbDisplayLayer()
@@ -456,36 +438,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)
{
@@ -501,7 +453,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
@@ -542,7 +494,15 @@ void QDirectFBScreen::setSurfaceColorTable(IDirectFBSurface *surface,
#endif // QT_NO_DIRECTFB_PALETTE
-#if !defined(QT_NO_DIRECTFB_LAYER) && !defined(QT_NO_QWS_CURSOR)
+#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
+
+#if defined QT_DIRECTFB_CURSOR
class Q_GUI_EXPORT QDirectFBScreenCursor : public QScreenCursor
{
public:
@@ -552,6 +512,11 @@ public:
virtual void show();
virtual void hide();
private:
+#ifdef QT_DIRECTFB_WINDOW_AS_CURSOR
+ ~QDirectFBScreenCursor();
+ bool createWindow();
+ IDirectFBWindow *window;
+#endif
IDirectFBDisplayLayer *layer;
};
@@ -567,11 +532,95 @@ 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_OPTIONS|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();
+ description.options = DWOP_GHOST|DWOP_ALPHACHANNEL;
+ 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()
@@ -579,6 +628,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: "
@@ -594,6 +644,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
}
}
@@ -607,7 +666,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);
@@ -617,6 +682,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
}
}
@@ -633,12 +707,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);
@@ -648,17 +725,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))
@@ -713,6 +826,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,]*)$"));
@@ -739,6 +888,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)
@@ -747,6 +908,7 @@ QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType typ
return new QDirectFBPixmapData(q, type);
}
+#if (Q_DIRECTFB_VERSION >= 0x000923)
#ifdef QT_NO_DEBUG
struct FlagDescription;
static const FlagDescription *accelerationDescriptions = 0;
@@ -804,9 +966,6 @@ static const FlagDescription drawDescriptions[] = {
};
#endif
-
-
-#if (Q_DIRECTFB_VERSION >= 0x000923)
static const QByteArray flagDescriptions(uint mask, const FlagDescription *flags)
{
#ifdef QT_NO_DEBUG
@@ -865,6 +1024,36 @@ 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;
@@ -925,7 +1114,9 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
DFBSurfaceDescription description;
memset(&description, 0, sizeof(DFBSurfaceDescription));
+ IDirectFBSurface *surface;
+#ifdef QT_NO_DIRECTFB_WM
description.flags = DSDESC_CAPS;
if (::setIntOption(displayArgs, QLatin1String("width"), &description.width))
description.flags |= DSDESC_WIDTH;
@@ -954,17 +1145,28 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
}
// We don't track the primary surface as it's released in disconnect
- d_ptr->dfbSurface = createDFBSurface(description, DontTrackSurface);
- if (!d_ptr->dfbSurface) {
+ d_ptr->primarySurface = createDFBSurface(description, DontTrackSurface, &result);
+ if (!d_ptr->primarySurface) {
DirectFBError("QDirectFBScreen: error creating primary surface",
result);
return false;
}
+ surface = d_ptr->primarySurface;
+#else
+ description.flags = DSDESC_WIDTH|DSDESC_HEIGHT;
+ description.width = description.height = 1;
+ surface = createDFBSurface(description, DontTrackSurface, &result);
+ if (!surface) {
+ DirectFBError("QDirectFBScreen: error creating surface", result);
+ return false;
+ }
+#endif
// Work out what format we're going to use for surfaces with an alpha channel
- d_ptr->alphaPixmapFormat = QDirectFBScreen::getImageFormat(d_ptr->dfbSurface);
- setPixelFormat(d_ptr->alphaPixmapFormat);
- switch (d_ptr->alphaPixmapFormat) {
+ QImage::Format pixelFormat = QDirectFBScreen::getImageFormat(surface);
+ d_ptr->alphaPixmapFormat = pixelFormat;
+
+ switch (pixelFormat) {
case QImage::Format_RGB666:
d_ptr->alphaPixmapFormat = QImage::Format_ARGB6666_Premultiplied;
break;
@@ -972,9 +1174,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;
@@ -996,31 +1198,11 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
// works already
break;
}
- d_ptr->dfbSurface->GetSize(d_ptr->dfbSurface, &w, &h);
-
+ setPixelFormat(pixelFormat);
+ QScreen::d = ::depth(pixelFormat);
data = 0;
lstep = 0;
size = 0;
- dw = w;
- dh = h;
-
- DFBSurfacePixelFormat format;
- result = d_ptr->dfbSurface->GetPixelFormat(d_ptr->dfbSurface, &format);
- if (result == DFB_OK)
- QScreen::d = depth(format);
- else
- DirectFBError("QDirectFBScreen: error getting surface format", result);
-
- setPixelFormat(getImageFormat(d_ptr->dfbSurface));
-
- physWidth = physHeight = -1;
- ::setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth);
- ::setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight);
- const int dpi = 72;
- if (physWidth < 0)
- physWidth = qRound(dw * 25.4 / dpi);
- if (physHeight < 0)
- physHeight = qRound(dh * 25.4 / dpi);
#ifndef QT_NO_DIRECTFB_LAYER
result = d_ptr->dfb->GetDisplayLayer(d_ptr->dfb, DLID_PRIMARY,
@@ -1039,12 +1221,35 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
"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);
+ return false;
+ }
+
+ dw = w;
+ dh = h;
+
+ Q_ASSERT(dw != 0 && dh != 0);
+
+ physWidth = physHeight = -1;
+ ::setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth);
+ ::setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight);
+ const int dpi = 72;
+ if (physWidth < 0)
+ physWidth = qRound(dw * 25.4 / dpi);
+ if (physHeight < 0)
+ physHeight = qRound(dh * 25.4 / dpi);
setGraphicsSystem(d_ptr);
#if (Q_DIRECTFB_VERSION >= 0x000923)
if (displayArgs.contains(QLatin1String("debug"), Qt::CaseInsensitive))
- printDirectFBInfo(d_ptr->dfb, d_ptr->dfbSurface);
+ printDirectFBInfo(d_ptr->dfb, surface);
+#endif
+#ifndef QT_NO_DIRECTFB_WM
+ surface->Release(surface);
#endif
QRegExp backgroundColorRegExp("bgcolor=?(.+)");
@@ -1060,8 +1265,14 @@ bool QDirectFBScreen::connect(const QString &displaySpec)
void QDirectFBScreen::disconnect()
{
- d_ptr->dfbSurface->Release(d_ptr->dfbSurface);
- d_ptr->dfbSurface = 0;
+#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ if (d_ptr->imageProvider)
+ d_ptr->imageProvider->Release(d_ptr->imageProvider);
+#endif
+#ifdef QT_NO_DIRECTFB_WM
+ d_ptr->primarySurface->Release(d_ptr->primarySurface);
+ d_ptr->primarySurface = 0;
+#endif
foreach (IDirectFBSurface *surf, d_ptr->allocatedSurfaces)
surf->Release(surf);
@@ -1157,25 +1368,9 @@ QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const
// 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.
-static inline bool needExposeRegion()
-{
-#ifdef QT_NO_DIRECTFB_WM
- return true;
-#endif
-#ifdef QT_NO_DIRECTFB_LAYER
-#ifndef QT_NO_QWS_CURSOR
- return true;
-#endif
-#endif
- return false;
-}
-
void QDirectFBScreen::exposeRegion(QRegion r, int changing)
{
- if (!needExposeRegion()) {
- return;
- }
-
+#ifdef QT_NO_DIRECTFB_WM
const QList<QWSWindow*> windows = QWSServer::instance()->clientWindows();
if (changing < 0 || changing >= windows.size())
return;
@@ -1209,9 +1404,9 @@ void QDirectFBScreen::exposeRegion(QRegion r, int changing)
const DFBRectangle rect = {
source.x(), source.y(), source.width(), source.height()
};
- d_ptr->dfbSurface->Blit(d_ptr->dfbSurface, surface, &rect,
- windowGeometry.x() + source.x(),
- windowGeometry.y() + source.y());
+ 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);
@@ -1227,8 +1422,8 @@ void QDirectFBScreen::exposeRegion(QRegion r, int changing)
dfbPoints[i].x = (windowGeometry.x() + source.x());
dfbPoints[i].y = (windowGeometry.y() + source.y());
}
- d_ptr->dfbSurface->BatchBlit(d_ptr->dfbSurface, surface, dfbRectangles.constData(),
- dfbPoints.constData(), n);
+ d_ptr->primarySurface->BatchBlit(d_ptr->primarySurface, surface, dfbRectangles.constData(),
+ dfbPoints.constData(), n);
}
}
}
@@ -1238,30 +1433,38 @@ void QDirectFBScreen::exposeRegion(QRegion r, int changing)
const QRect cursorRectangle = cursor->boundingRect();
if (cursor->isVisible() && !cursor->isAccelerated() && cursorRectangle.intersects(brect)) {
const QImage image = cursor->image();
- IDirectFBSurface *surface = createDFBSurface(image, QDirectFBScreen::DontTrackSurface);
- d_ptr->dfbSurface->SetBlittingFlags(d_ptr->dfbSurface, DSBLIT_BLEND_ALPHACHANNEL);
- d_ptr->dfbSurface->Blit(d_ptr->dfbSurface, surface, 0, cursorRectangle.x(), cursorRectangle.y());
+ IDirectFBSurface *surface = createDFBSurface(image, image.format(), 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->dfbSurface->ReleaseSource(d_ptr->dfbSurface);
+ d_ptr->primarySurface->ReleaseSource(d_ptr->primarySurface);
#endif
}
}
- flipSurface(d_ptr->dfbSurface, d_ptr->flipFlags, r, QPoint());
+ flipSurface(d_ptr->primarySurface, d_ptr->flipFlags, r, QPoint());
+#else
+ Q_UNUSED(r);
+ Q_UNUSED(changing);
+#endif
}
void QDirectFBScreen::solidFill(const QColor &color, const QRegion &region)
{
+#ifdef QT_DIRECTFB_WM
+ Q_UNUSED(color);
+ Q_UNUSED(region);
+#else
if (region.isEmpty())
return;
- d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface,
+ d_ptr->primarySurface->SetColor(d_ptr->primarySurface,
color.red(), color.green(), color.blue(),
color.alpha());
const int n = region.numRects();
if (n > 1) {
const QRect r = region.boundingRect();
- d_ptr->dfbSurface->FillRectangle(d_ptr->dfbSurface, r.x(), r.y(), r.width(), r.height());
+ d_ptr->primarySurface->FillRectangle(d_ptr->primarySurface, r.x(), r.y(), r.width(), r.height());
} else {
const QVector<QRect> rects = region.rects();
QVarLengthArray<DFBRectangle, 32> rectArray(n);
@@ -1272,8 +1475,9 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion &region)
rectArray[i].w = r.width();
rectArray[i].h = r.height();
}
- d_ptr->dfbSurface->FillRectangles(d_ptr->dfbSurface, rectArray.constData(), n);
+ d_ptr->primarySurface->FillRectangles(d_ptr->primarySurface, rectArray.constData(), n);
}
+#endif
}
void QDirectFBScreen::erase(const QRegion &region)
@@ -1305,10 +1509,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);
}
@@ -1343,4 +1547,46 @@ 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
+
+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;
+}
+
+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;
+}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
index ebe40b1..df0eea4 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
@@ -50,6 +50,49 @@ QT_BEGIN_HEADER
QT_MODULE(Gui)
+#if !defined QT_NO_DIRECTFB_LAYER && !defined QT_DIRECTFB_LAYER
+#define QT_DIRECTFB_LAYER
+#endif
+#if !defined QT_NO_DIRECTFB_WM && !defined QT_DIRECTFB_WM
+#define QT_DIRECTFB_WM
+#endif
+#if !defined QT_DIRECTFB_IMAGECACHE && !defined QT_NO_DIRECTFB_IMAGECACHE
+#define QT_NO_DIRECTFB_IMAGECACHE
+#endif
+#if !defined QT_DIRECTFB_NO_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_NO_DIRECTFB_PALETTE && !defined QT_DIRECTFB_PALETTE
+#define QT_DIRECTFB_PALETTE
+#endif
+#if !defined QT_NO_DIRECTFB_PREALLOCATED && !defined QT_DIRECTFB_PREALLOCATED
+#define QT_DIRECTFB_PREALLOCATED
+#endif
+#if !defined QT_NO_DIRECTFB_MOUSE && !defined QT_DIRECTFB_MOUSE
+#define QT_DIRECTFB_MOUSE
+#endif
+#if !defined QT_NO_DIRECTFB_KEYBOARD && !defined QT_DIRECTFB_KEYBOARD
+#define QT_DIRECTFB_KEYBOARD
+#endif
+#if !defined QT_NO_DIRECTFB_OPAQUE_DETECTION && !defined QT_DIRECTFB_OPAQUE_DETECTION
+#define QT_DIRECTFB_OPAQUE_DETECTION
+#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 DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(F) \
@@ -61,6 +104,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);
@@ -107,45 +152,57 @@ public:
return static_cast<QDirectFBScreen*>(inst);
}
+ IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const;
+ IDirectFBSurface *subSurfaceForWidget(const QWidget *widget, const QRect &area = QRect()) const;
+
IDirectFB *dfb();
- IDirectFBSurface *dfbSurface();
+#ifdef QT_NO_DIRECTFB_WM
+ IDirectFBSurface *primarySurface();
+#endif
#ifndef QT_NO_DIRECTFB_LAYER
IDirectFBDisplayLayer *dfbDisplayLayer();
#endif
// 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);
+
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
@@ -153,12 +210,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);
@@ -179,7 +236,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:
@@ -204,12 +261,12 @@ 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_HEADER
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
index 8718e5a..a05ad21 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
@@ -48,21 +48,17 @@
#include <qpaintdevice.h>
#include <qvarlengtharray.h>
-//#define QT_DIRECTFB_DEBUG_SURFACES 1
-
QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr)
: QDirectFBPaintDevice(scr)
#ifndef QT_NO_DIRECTFB_WM
, dfbWindow(0)
+ , sibling(0)
#endif
- , engineHeight(-1)
, flipFlags(flip)
, boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
{
#ifdef QT_NO_DIRECTFB_WM
mode = Offscreen;
-#else
- mode = Window;
#endif
setSurfaceFlags(Opaque | Buffered);
#ifdef QT_DIRECTFB_TIMING
@@ -75,22 +71,23 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect
: QWSWindowSurface(widget), QDirectFBPaintDevice(scr)
#ifndef QT_NO_DIRECTFB_WM
, dfbWindow(0)
+ , sibling(0)
#endif
- , engineHeight(-1)
, flipFlags(flip)
, boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip)
{
+#ifdef QT_NO_DIRECTFB_WM
if (widget && widget->testAttribute(Qt::WA_PaintOnScreen)) {
setSurfaceFlags(Opaque | RegionReserved);
mode = Primary;
} else {
-#ifdef QT_NO_DIRECTFB_WM
mode = Offscreen;
-#else
- mode = Window;
-#endif
setSurfaceFlags(Opaque | Buffered);
}
+#else
+ setSurfaceFlags(Opaque | Buffered);
+#endif
+
#ifdef QT_DIRECTFB_TIMING
frames = 0;
timer.start();
@@ -101,6 +98,17 @@ QDirectFBWindowSurface::~QDirectFBWindowSurface()
{
}
+#ifdef QT_DIRECTFB_WM
+void QDirectFBWindowSurface::raise()
+{
+ if (dfbWindow) {
+ dfbWindow->RaiseToTop(dfbWindow);
+ } else if (sibling && (!sibling->sibling || sibling->dfbWindow)) {
+ sibling->raise();
+ }
+}
+#endif
+
bool QDirectFBWindowSurface::isValid() const
{
return true;
@@ -109,15 +117,12 @@ bool QDirectFBWindowSurface::isValid() const
#ifndef QT_NO_DIRECTFB_WM
void QDirectFBWindowSurface::createWindow()
{
-#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.caps = DWCAPS_NODECORATION|DWCAPS_DOUBLEBUFFER;
description.flags = DWDESC_CAPS|DWDESC_SURFACE_CAPS|DWDESC_PIXELFORMAT;
description.surface_caps = DSCAPS_NONE;
@@ -129,6 +134,7 @@ void QDirectFBWindowSurface::createWindow()
description.surface_caps = DSCAPS_PREMULTIPLIED;
DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow);
+
if (result != DFB_OK)
DirectFBErrorFatal("QDirectFBWindowSurface::createWindow", result);
@@ -136,7 +142,7 @@ void QDirectFBWindowSurface::createWindow()
dfbSurface->Release(dfbSurface);
dfbWindow->GetSurface(dfbWindow, &dfbSurface);
-#endif
+ updateFormat();
}
#endif // QT_NO_DIRECTFB_WM
@@ -172,8 +178,11 @@ static DFBResult setGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const
void QDirectFBWindowSurface::setGeometry(const QRect &rect)
{
- IDirectFBSurface *primarySurface = screen->dfbSurface();
+ IDirectFBSurface *oldSurface = dfbSurface;
+#ifdef QT_NO_DIRECTFB_WM
+ IDirectFBSurface *primarySurface = screen->primarySurface();
Q_ASSERT(primarySurface);
+#endif
if (rect.isNull()) {
#ifndef QT_NO_DIRECTFB_WM
if (dfbWindow) {
@@ -182,9 +191,10 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect)
}
#endif
if (dfbSurface) {
- if (dfbSurface != primarySurface) {
+#ifdef QT_NO_DIRECTFB_WM
+ if (dfbSurface != primarySurface)
+#endif
dfbSurface->Release(dfbSurface);
- }
dfbSurface = 0;
}
} else if (rect != geometry()) {
@@ -192,8 +202,12 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect)
DFBResult result = DFB_OK;
// If we're in a resize, the surface shouldn't be locked
Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size()));
- switch (mode) {
- case Primary:
+#ifdef QT_DIRECTFB_WM
+ if (!dfbWindow)
+ createWindow();
+ ::setGeometry(dfbWindow, oldRect, rect);
+#else
+ if (mode == Primary) {
if (dfbSurface && dfbSurface != primarySurface)
dfbSurface->Release(dfbSurface);
if (rect == screen->region().boundingRect()) {
@@ -203,16 +217,7 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect)
rect.width(), rect.height() };
result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface);
}
- break;
- case Window:
-#ifndef QT_NO_DIRECTFB_WM
- if (!dfbWindow)
- createWindow();
- ::setGeometry(dfbWindow, oldRect, rect);
- // ### do I need to release and get the surface again here?
-#endif
- break;
- case Offscreen: {
+ } else {
if (!dfbSurface || oldRect.size() != rect.size()) {
if (dfbSurface)
dfbSurface->Release(dfbSurface);
@@ -221,46 +226,39 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect)
const QRegion region = QRegion(oldRect.isEmpty() ? screen->region() : QRegion(oldRect)).subtracted(rect);
screen->erase(region);
screen->flipSurface(primarySurface, flipFlags, region, QPoint());
- break; }
+ }
+#endif
+ if (size() != geometry().size()) {
+ delete engine;
+ engine = 0;
}
if (result != DFB_OK)
DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result);
}
-
+ 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));
+#ifdef QT_DIRECTFB_WM
+ QByteArray state(sizeof(this), 0);
+ *reinterpret_cast<const QDirectFBWindowSurface**>(state.data()) = this;
+ return state;
#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;
+ return QByteArray();
}
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);
+#ifdef QT_DIRECTFB_WM
+ if (state.size() == sizeof(this)) {
+ sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData());
+ }
+#else
+ Q_UNUSED(state);
#endif
}
@@ -347,7 +345,8 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion &region,
}
const QRect windowGeometry = QDirectFBWindowSurface::geometry();
- IDirectFBSurface *primarySurface = screen->dfbSurface();
+#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());
@@ -388,7 +387,7 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion &region,
&& region.intersects(cursorRectangle.translated(-(offset + windowGeometry.topLeft())))) {
const QImage image = cursor->image();
- IDirectFBSurface *surface = screen->createDFBSurface(image, QDirectFBScreen::DontTrackSurface);
+ IDirectFBSurface *surface = screen->createDFBSurface(image, image.format(), QDirectFBScreen::DontTrackSurface);
primarySurface->SetBlittingFlags(primarySurface, DSBLIT_BLEND_ALPHACHANNEL);
primarySurface->Blit(primarySurface, surface, 0, cursorRectangle.x(), cursorRectangle.y());
surface->Release(surface);
@@ -399,9 +398,9 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion &region,
}
if (mode == Offscreen) {
screen->flipSurface(primarySurface, flipFlags, region, offset + windowGeometry.topLeft());
- } else {
- screen->flipSurface(dfbSurface, flipFlags, region, offset);
- }
+ } else
+#endif
+ screen->flipSurface(dfbSurface, flipFlags, region, offset);
#ifdef QT_DIRECTFB_TIMING
enum { Secs = 3 };
@@ -414,55 +413,39 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion &region,
#endif
}
-
void QDirectFBWindowSurface::beginPaint(const QRegion &)
{
- const int h = height();
- if (h > engineHeight) {
- engineHeight = h;
- delete 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);
- }
-#endif
-
- qDeleteAll(bufferImages);
- bufferImages.clear();
unlockDirectFB();
}
-
-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;
-
- const QRect rect = QRect(offset(widget), widget->size())
- & lockedImage->rect();
- if (rect.isEmpty())
- return 0;
-
- QImage *img = new QImage(lockedImage->scanLine(rect.y())
- + rect.x() * (lockedImage->depth() / 8),
- rect.width(), rect.height(),
- lockedImage->bytesPerLine(),
- lockedImage->format());
- bufferImages.append(img);
-
-#ifdef QT_DIRECTFB_DEBUG_SURFACES
- qDebug("QDirectFBWindowSurface::buffer() Created & returned %p", img);
-#endif
-
- return img;
+ }
+ 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());
+ }
+ }
+ Q_ASSERT(win == widget || widget->isAncestorOf(win));
+ return dfbSurface;
}
+void QDirectFBWindowSurface::updateFormat()
+{
+ imageFormat = dfbSurface ? QDirectFBScreen::getImageFormat(dfbSurface) : QImage::Format_Invalid;
+}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
index c8190b6..a2861e5 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
@@ -65,6 +65,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 +88,20 @@ public:
void beginPaint(const QRegion &);
void endPaint(const QRegion &);
- QImage *buffer(const QWidget *widget);
+ IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const;
private:
-#ifndef QT_NO_DIRECTFB_WM
+ void updateFormat();
+#ifdef QT_DIRECTFB_WM
void createWindow();
IDirectFBWindow *dfbWindow;
-#endif
- int engineHeight;
-
+ QDirectFBWindowSurface *sibling;
+#else
enum Mode {
Primary,
- Offscreen,
- Window
+ Offscreen
} mode;
+#endif
- QList<QImage*> bufferImages;
DFBSurfaceFlipFlags flipFlags;
bool boundingRectFlip;
#ifdef QT_DIRECTFB_TIMING
diff --git a/src/plugins/gfxdrivers/hybrid/hybridscreen.cpp b/src/plugins/gfxdrivers/hybrid/hybridscreen.cpp
index 03aa038..1d1b8b9 100644
--- a/src/plugins/gfxdrivers/hybrid/hybridscreen.cpp
+++ b/src/plugins/gfxdrivers/hybrid/hybridscreen.cpp
@@ -103,11 +103,11 @@ bool HybridScreen::connect(const QString &displaySpec)
{
QString dspec = displaySpec;
if (dspec.startsWith(QLatin1String("hybrid:"), Qt::CaseInsensitive))
- dspec = dspec.mid(QString(QLatin1String("hybrid:")).size());
+ dspec = dspec.mid(QString::fromLatin1("hybrid:").size());
else if (dspec.compare(QLatin1String("hybrid"), Qt::CaseInsensitive) == 0)
dspec = QString();
- const QString displayIdSpec = QString(QLatin1String(" :%1")).arg(displayId);
+ const QString displayIdSpec = QString::fromLatin1(" :%1").arg(displayId);
if (dspec.endsWith(displayIdSpec))
dspec = dspec.left(dspec.size() - displayIdSpec.size());
diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
index 9067de9..1326261 100644
--- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
+++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp
@@ -104,7 +104,7 @@ bool PvrEglScreen::connect(const QString &displaySpec)
break;
case PVR2D_ARGB8888:
d = 32;
- setPixelFormat(QImage::Format_ARGB32);
+ setPixelFormat(QImage::Format_ARGB32_Premultiplied);
break;
default:
pvrQwsDisplayClose();
diff --git a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp b/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp
index d003e9b..2b88268 100644
--- a/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp
+++ b/src/plugins/gfxdrivers/vnc/qscreenvnc_qws.cpp
@@ -2100,11 +2100,11 @@ bool QVNCScreen::connect(const QString &displaySpec)
{
QString dspec = displaySpec;
if (dspec.startsWith(QLatin1String("vnc:"), Qt::CaseInsensitive))
- dspec = dspec.mid(QString(QLatin1String("vnc:")).size());
+ dspec = dspec.mid(QString::fromLatin1("vnc:").size());
else if (dspec.compare(QLatin1String("vnc"), Qt::CaseInsensitive) == 0)
dspec = QString();
- const QString displayIdSpec = QString(QLatin1String(" :%1")).arg(displayId);
+ const QString displayIdSpec = QString::fromLatin1(" :%1").arg(displayId);
if (dspec.endsWith(displayIdSpec))
dspec = dspec.left(dspec.size() - displayIdSpec.size());