summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp59
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp31
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbscreen.h3
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp67
-rw-r--r--src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h3
5 files changed, 87 insertions, 76 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
index 70a6e02..146a920 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp
@@ -209,66 +209,60 @@ bool QDirectFBPixmapData::fromData(const uchar *buffer, uint len, const char *fo
return QPixmapData::fromData(buffer, len, format, flags);
}
-template <typename T> class QDirectFBPointer
+template <typename T> struct QDirectFBInterfaceCleanupHandler
{
-public:
- QDirectFBPointer(T *tt = 0) : t(tt) {}
- ~QDirectFBPointer() { if (t) t->Release(t); }
-
- inline T* operator->() { return t; }
- inline operator T*() { return t; }
-
- inline T** operator&() { return &t; }
- inline bool operator!() const { return !t; }
- inline T *data() { return t; }
- inline const T *data() const { return t; }
+ static void cleanup(T *t) { if (t) t->Release(t); }
+};
- T *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);
- QDirectFBPointer<IDirectFBDataBuffer> dataBuffer;
DFBResult result = DFB_OK;
- if ((result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, &dataBuffer)) != DFB_OK) {
+ IDirectFBDataBuffer *dataBufferPtr;
+ if ((result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, &dataBufferPtr)) != DFB_OK) {
DirectFBError("QDirectFBPixmapData::fromDataBufferDescription()", result);
return false;
}
+ QDirectFBPointer<IDirectFBDataBuffer> dataBuffer(dataBufferPtr);
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- IDirectFBImageProvider *provider = 0;
-#else
- QDirectFBPointer<IDirectFBImageProvider> provider;
-#endif
- if ((result = dataBuffer->CreateImageProvider(dataBuffer, &provider)) != DFB_OK) {
+ IDirectFBImageProvider *providerPtr;
+ if ((result = dataBuffer->CreateImageProvider(dataBuffer.data(), &providerPtr)) != DFB_OK) {
DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't create image provider", result);
return false;
}
-#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
- screen->setDirectFBImageProvider(provider);
-#endif
+ QDirectFBPointer<IDirectFBImageProvider> provider(providerPtr);
+
DFBSurfaceDescription surfaceDescription;
- if ((result = provider->GetSurfaceDescription(provider, &surfaceDescription)) != DFB_OK) {
+ if ((result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription)) != DFB_OK) {
DirectFBError("QDirectFBPixmapData::fromDataBufferDescription(): Can't get surface description", result);
return false;
}
- QDirectFBPointer<IDirectFBSurface> surfaceFromDescription = screen->createDFBSurface(surfaceDescription, QDirectFBScreen::DontTrackSurface, &result);
+ 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, surfaceFromDescription, 0);
+ 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, &imageDescription);
+ result = provider->GetImageDescription(provider.data(), &imageDescription);
if (result != DFB_OK) {
DirectFBError("QDirectFBPixmapData::fromSurfaceDescription(): Can't get image description", result);
return false;
@@ -285,7 +279,7 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti
DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX;
if (imageDescription.caps & DICAPS_COLORKEY) {
blittingFlags |= DSBLIT_SRC_COLORKEY;
- result = surfaceFromDescription->SetSrcColorKey(surfaceFromDescription,
+ result = surfaceFromDescription->SetSrcColorKey(surfaceFromDescription.data(),
imageDescription.colorkey_r,
imageDescription.colorkey_g,
imageDescription.colorkey_b);
@@ -305,7 +299,7 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti
return false;
}
- result = dfbSurface->Blit(dfbSurface, surfaceFromDescription, 0, 0, 0);
+ 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
@@ -324,6 +318,11 @@ bool QDirectFBPixmapData::fromDataBufferDescription(const DFBDataBufferDescripti
#if (Q_DIRECTFB_VERSION >= 0x010000)
dfbSurface->ReleaseSource(dfbSurface);
#endif
+#if defined QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE
+ screen->setDirectFBImageProvider(providerPtr);
+ provider.take();
+#endif
+
return true;
}
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
index dbe8926..1bf74d4 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp
@@ -1557,5 +1557,36 @@ void QDirectFBScreen::setDirectFBImageProvider(IDirectFBImageProvider *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 8ec91c7..8af4e0f 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h
@@ -152,6 +152,9 @@ 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();
#ifdef QT_NO_DIRECTFB_WM
IDirectFBSurface *primarySurface();
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
index 2f240fb..9de1ca5 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp
@@ -48,8 +48,6 @@
#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
@@ -245,22 +243,19 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect)
QByteArray QDirectFBWindowSurface::permanentState() const
{
- QByteArray state;
#ifdef QT_DIRECTFB_WM
- QDataStream ds(&state, QIODevice::WriteOnly);
- ds << reinterpret_cast<quintptr>(this);
-#endif
+ QByteArray state(sizeof(this), 0);
+ *reinterpret_cast<const QDirectFBWindowSurface**>(state.data()) = this;
return state;
+#endif
+ return QByteArray();
}
void QDirectFBWindowSurface::setPermanentState(const QByteArray &state)
{
#ifdef QT_DIRECTFB_WM
- if (state.size() == sizeof(quintptr)) {
- QDataStream ds(state);
- quintptr ptr;
- ds >> ptr;
- sibling = reinterpret_cast<QDirectFBWindowSurface*>(ptr);
+ if (state.size() == sizeof(this)) {
+ sibling = *reinterpret_cast<QDirectFBWindowSurface *const*>(state.constData());
}
#else
Q_UNUSED(state);
@@ -418,7 +413,6 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion &region,
#endif
}
-
void QDirectFBWindowSurface::beginPaint(const QRegion &)
{
if (!engine)
@@ -427,43 +421,28 @@ void QDirectFBWindowSurface::beginPaint(const QRegion &)
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()
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
index 0da3a98..dafc478 100644
--- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
+++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h
@@ -88,7 +88,7 @@ public:
void beginPaint(const QRegion &);
void endPaint(const QRegion &);
- QImage *buffer(const QWidget *widget);
+ IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const;
private:
void updateFormat();
#ifdef QT_DIRECTFB_WM
@@ -104,7 +104,6 @@ private:
} mode;
#endif
- QList<QImage*> bufferImages;
DFBSurfaceFlipFlags flipFlags;
bool boundingRectFlip;
#ifdef QT_DIRECTFB_TIMING