From c614e71cdd4047bb49ccde2f94c9d622f5071fc3 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 13 Dec 2011 12:02:33 +0100 Subject: directfb: Backport the work from QtBase to Qt 4.8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is copying the files (minus the API changes) to Qt 4.8. It fixes memory leaks, adds DirectFB based image decoding, prepares EGL integration/ Merge-request: 1492 Reviewed-by: Jørgen Lind --- src/plugins/platforms/directfb/directfb.pro | 6 +- src/plugins/platforms/directfb/main.cpp | 22 ++- .../platforms/directfb/qdirectfbblitter.cpp | 166 +++++++++++++++++---- src/plugins/platforms/directfb/qdirectfbblitter.h | 34 ++++- .../platforms/directfb/qdirectfbconvenience.cpp | 37 ++++- .../platforms/directfb/qdirectfbconvenience.h | 44 +++++- src/plugins/platforms/directfb/qdirectfbcursor.cpp | 34 +++-- src/plugins/platforms/directfb/qdirectfbcursor.h | 16 +- .../platforms/directfb/qdirectfbglcontext.cpp | 4 + src/plugins/platforms/directfb/qdirectfbinput.cpp | 86 +++++------ src/plugins/platforms/directfb/qdirectfbinput.h | 24 ++- .../platforms/directfb/qdirectfbintegration.cpp | 81 +++++----- .../platforms/directfb/qdirectfbintegration.h | 44 ++---- src/plugins/platforms/directfb/qdirectfbscreen.cpp | 72 +++++++++ src/plugins/platforms/directfb/qdirectfbscreen.h | 82 ++++++++++ src/plugins/platforms/directfb/qdirectfbwindow.cpp | 118 +++++++++------ src/plugins/platforms/directfb/qdirectfbwindow.h | 12 +- .../platforms/directfb/qdirectfbwindowsurface.cpp | 42 ++---- .../platforms/directfb/qdirectfbwindowsurface.h | 11 +- 19 files changed, 653 insertions(+), 282 deletions(-) create mode 100644 src/plugins/platforms/directfb/qdirectfbscreen.cpp create mode 100644 src/plugins/platforms/directfb/qdirectfbscreen.h diff --git a/src/plugins/platforms/directfb/directfb.pro b/src/plugins/platforms/directfb/directfb.pro index 65c49e3..aaf4057 100644 --- a/src/plugins/platforms/directfb/directfb.pro +++ b/src/plugins/platforms/directfb/directfb.pro @@ -20,7 +20,8 @@ SOURCES = main.cpp \ qdirectfbinput.cpp \ qdirectfbcursor.cpp \ qdirectfbwindow.cpp \ - qdirectfbglcontext.cpp + qdirectfbglcontext.cpp \ + qdirectfbscreen.cpp HEADERS = qdirectfbintegration.h \ qdirectfbwindowsurface.h \ qdirectfbblitter.h \ @@ -28,7 +29,8 @@ HEADERS = qdirectfbintegration.h \ qdirectfbinput.h \ qdirectfbcursor.h \ qdirectfbwindow.h \ - qdirectfbglcontext.h + qdirectfbglcontext.h \ + qdirectfbscreen.h include(../fontdatabases/genericunix/genericunix.pri) target.path += $$[QT_INSTALL_PLUGINS]/platforms diff --git a/src/plugins/platforms/directfb/main.cpp b/src/plugins/platforms/directfb/main.cpp index 312fc41..da37b0a 100644 --- a/src/plugins/platforms/directfb/main.cpp +++ b/src/plugins/platforms/directfb/main.cpp @@ -44,6 +44,16 @@ QT_BEGIN_NAMESPACE +#ifdef DIRECTFB_GL_EGL +#define QT_EGL_BACKEND_STRING(list) list << "directfbegl"; +#define QT_EGL_BACKEND_CREATE(list, out) \ + if (list.toLower() == "directfbegl") \ + out = new QDirectFbIntegrationEGL; +#else +#define QT_EGL_BACKEND_STRING(list) +#define QT_EGL_BACKEND_CREATE(system, out) +#endif + class QDirectFbIntegrationPlugin : public QPlatformIntegrationPlugin { public: @@ -55,16 +65,24 @@ QStringList QDirectFbIntegrationPlugin::keys() const { QStringList list; list << "directfb"; + QT_EGL_BACKEND_STRING(list); return list; } QPlatformIntegration * QDirectFbIntegrationPlugin::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); + QDirectFbIntegration *integration = 0; + if (system.toLower() == "directfb") - return new QDirectFbIntegration; + integration = new QDirectFbIntegration; + QT_EGL_BACKEND_CREATE(system, integration) + + if (!integration) + return 0; - return 0; + integration->initialize(); + return integration; } Q_EXPORT_PLUGIN2(directfb, QDirectFbIntegrationPlugin) diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.cpp b/src/plugins/platforms/directfb/qdirectfbblitter.cpp index 83c27d1..af060aa 100644 --- a/src/plugins/platforms/directfb/qdirectfbblitter.cpp +++ b/src/plugins/platforms/directfb/qdirectfbblitter.cpp @@ -45,23 +45,29 @@ #include #include +#include #include +QT_BEGIN_NAMESPACE + +static QBlittable::Capabilities dfb_blitter_capabilities() +{ + return QBlittable::Capabilities(QBlittable::SolidRectCapability + |QBlittable::SourcePixmapCapability + |QBlittable::SourceOverPixmapCapability + |QBlittable::SourceOverScaledPixmapCapability); +} + QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, IDirectFBSurface *surface) - : QBlittable(rect, QBlittable::Capabilities(QBlittable::SolidRectCapability - |QBlittable::SourcePixmapCapability - |QBlittable::SourceOverPixmapCapability - |QBlittable::SourceOverScaledPixmapCapability)) + : QBlittable(rect, dfb_blitter_capabilities()) + , m_surface(surface) { - m_surface = surface; + m_surface->AddRef(m_surface.data()); } QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, bool alpha) - : QBlittable(rect, QBlittable::Capabilities(QBlittable::SolidRectCapability - |QBlittable::SourcePixmapCapability - |QBlittable::SourceOverPixmapCapability - |QBlittable::SourceOverScaledPixmapCapability)) + : QBlittable(rect, dfb_blitter_capabilities()) { DFBSurfaceDescription surfaceDesc; memset(&surfaceDesc,0,sizeof(DFBSurfaceDescription)); @@ -70,34 +76,48 @@ QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, bool alpha) if (alpha) { surfaceDesc.caps = DSCAPS_PREMULTIPLIED; - surfaceDesc.pixelformat = DSPF_ARGB; + surfaceDesc.pixelformat = QDirectFbBlitter::alphaPixmapFormat(); surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT); } else { surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT); - surfaceDesc.pixelformat = DSPF_RGB32; + surfaceDesc.pixelformat = QDirectFbBlitter::pixmapFormat(); } IDirectFB *dfb = QDirectFbConvenience::dfbInterface(); - dfb->CreateSurface(dfb , &surfaceDesc, &m_surface); - m_surface->Clear(m_surface, 0, 0, 0, 0); + dfb->CreateSurface(dfb , &surfaceDesc, m_surface.outPtr()); + m_surface->Clear(m_surface.data(), 0, 0, 0, 0); } QDirectFbBlitter::~QDirectFbBlitter() { unlock(); - m_surface->Release(m_surface); +} + +DFBSurfacePixelFormat QDirectFbBlitter::alphaPixmapFormat() +{ + return DSPF_ARGB; +} + +DFBSurfacePixelFormat QDirectFbBlitter::pixmapFormat() +{ + return DSPF_RGB32; +} + +DFBSurfacePixelFormat QDirectFbBlitter::selectPixmapFormat(bool withAlpha) +{ + return withAlpha ? alphaPixmapFormat() : pixmapFormat(); } void QDirectFbBlitter::fillRect(const QRectF &rect, const QColor &color) { - m_surface->SetColor(m_surface, color.red(), color.green(), color.blue(), color.alpha()); + m_surface->SetColor(m_surface.data(), color.red(), color.green(), color.blue(), color.alpha()); // When the blitter api supports non opaque blits, also remember to change // qpixmap_blitter.cpp::fill // DFBSurfaceDrawingFlags drawingFlags = color.alpha() ? DSDRAW_BLEND : DSDRAW_NOFX; // m_surface->SetDrawingFlags(m_surface, drawingFlags); - m_surface->SetDrawingFlags(m_surface, DSDRAW_NOFX); - m_surface->FillRectangle(m_surface, rect.x(), rect.y(), + m_surface->SetDrawingFlags(m_surface.data(), DSDRAW_NOFX); + m_surface->FillRectangle(m_surface.data(), rect.x(), rect.y(), rect.width(), rect.height()); } @@ -110,7 +130,7 @@ void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, con QDirectFbBlitter *dfbBlitter = static_cast(blitPm->blittable()); dfbBlitter->unlock(); - IDirectFBSurface *s = dfbBlitter->m_surface; + IDirectFBSurface *s = dfbBlitter->m_surface.data(); DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX; DFBSurfacePorterDuffRule porterDuff = DSPD_SRC; @@ -119,18 +139,18 @@ void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, con porterDuff = DSPD_SRC_OVER; } - m_surface->SetBlittingFlags(m_surface, DFBSurfaceBlittingFlags(blittingFlags)); - m_surface->SetPorterDuff(m_surface,porterDuff); - m_surface->SetDstBlendFunction(m_surface,DSBF_INVSRCALPHA); + m_surface->SetBlittingFlags(m_surface.data(), DFBSurfaceBlittingFlags(blittingFlags)); + m_surface->SetPorterDuff(m_surface.data(), porterDuff); + m_surface->SetDstBlendFunction(m_surface.data(), DSBF_INVSRCALPHA); const DFBRectangle sRect = { srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height() }; DFBResult result; if (rect.width() == srcRect.width() && rect.height() == srcRect.height()) - result = m_surface->Blit(m_surface, s, &sRect, rect.x(), rect.y()); + result = m_surface->Blit(m_surface.data(), s, &sRect, rect.x(), rect.y()); else { const DFBRectangle dRect = { rect.x(), rect.y(), rect.width(), rect.height() }; - result = m_surface->StretchBlit(m_surface, s, &sRect, &dRect); + result = m_surface->StretchBlit(m_surface.data(), s, &sRect, &dRect); } if (result != DFB_OK) DirectFBError("QDirectFBBlitter::drawPixmap()", result); @@ -143,15 +163,15 @@ QImage *QDirectFbBlitter::doLock() void *mem; int bpl; - const DFBResult result = m_surface->Lock(m_surface, DFBSurfaceLockFlags(DSLF_WRITE|DSLF_READ), static_cast(&mem), &bpl); + const DFBResult result = m_surface->Lock(m_surface.data(), DFBSurfaceLockFlags(DSLF_WRITE|DSLF_READ), static_cast(&mem), &bpl); if (result == DFB_OK) { DFBSurfacePixelFormat dfbFormat; DFBSurfaceCapabilities dfbCaps; - m_surface->GetPixelFormat(m_surface,&dfbFormat); - m_surface->GetCapabilities(m_surface,&dfbCaps); + m_surface->GetPixelFormat(m_surface.data(), &dfbFormat); + m_surface->GetCapabilities(m_surface.data(), &dfbCaps); QImage::Format format = QDirectFbConvenience::imageFormatFromSurfaceFormat(dfbFormat, dfbCaps); int w, h; - m_surface->GetSize(m_surface,&w,&h); + m_surface->GetSize(m_surface.data(), &w, &h); m_image = QImage(static_cast(mem),w,h,bpl,format); } else { DirectFBError("Failed to lock image", result); @@ -160,7 +180,97 @@ QImage *QDirectFbBlitter::doLock() return &m_image; } +bool QDirectFbBlitterPlatformPixmap::fromDataBufferDescription(const DFBDataBufferDescription &dataBufferDescription) +{ + DFBResult result; + IDirectFB *dfb = QDirectFbConvenience::dfbInterface(); + + // Create a data buffer + QDirectFBPointer dataBuffer; + result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, dataBuffer.outPtr()); + if (result != DFB_OK) { + DirectFBError(QDFB_PRETTY, result); + return false; + } + + // Create the image provider + QDirectFBPointer provider; + result = dataBuffer->CreateImageProvider(dataBuffer.data(), provider.outPtr()); + if (result != DFB_OK) { + DirectFBError(QDFB_PRETTY, result); + return false; + } + + // Extract image information + DFBImageDescription imageDescription; + result = provider->GetImageDescription(provider.data(), &imageDescription); + if (result != DFB_OK) { + DirectFBError(QDFB_PRETTY, result); + return false; + } + + // Can we handle this directlu? + if (imageDescription.caps & DICAPS_COLORKEY) + return false; + + DFBSurfaceDescription surfaceDescription; + result = provider->GetSurfaceDescription(provider.data(), &surfaceDescription); + if (result != DFB_OK) { + DirectFBError(QDFB_PRETTY, result); + return false; + } + + m_alpha = imageDescription.caps & DICAPS_ALPHACHANNEL; + resize(surfaceDescription.width, surfaceDescription.height); + // TODO: FIXME; update d + + + result = provider->RenderTo(provider.data(), dfbBlitter()->dfbSurface(), 0); + if (result != DFB_OK) { + DirectFBError(QDFB_PRETTY, result); + return false; + } + + return true; +} + +bool QDirectFbBlitterPlatformPixmap::fromFile(const QString &filename, const char *format, + Qt::ImageConversionFlags flags) +{ + // If we can't find the file, pass it on to the base class as it is + // trying harder by appending various extensions to the path. + if (!QFile::exists(filename)) + return QBlittablePixmapData::fromFile(filename, format, flags); + + // Stop if there is a requirement for colors + if (flags != Qt::AutoColor) + return QBlittablePixmapData::fromFile(filename, format, flags); + + // Deal with resources + 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(data.constData()), data.size(), format, flags); + } + + // Try to use directfb to load it. + DFBDataBufferDescription description; + description.flags = DBDESC_FILE; + const QByteArray fileNameData = filename.toLocal8Bit(); + description.file = fileNameData.constData(); + if (fromDataBufferDescription(description)) + return true; + + // Fallback + return QBlittablePixmapData::fromFile(filename, format, flags); +} + void QDirectFbBlitter::doUnlock() { - m_surface->Unlock(m_surface); + m_surface->Unlock(m_surface.data()); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbblitter.h b/src/plugins/platforms/directfb/qdirectfbblitter.h index 5a2b77f..fe39aaf 100644 --- a/src/plugins/platforms/directfb/qdirectfbblitter.h +++ b/src/plugins/platforms/directfb/qdirectfbblitter.h @@ -48,6 +48,8 @@ #include +QT_BEGIN_NAMESPACE + class QDirectFbBlitter : public QBlittable { public: @@ -58,25 +60,51 @@ public: virtual void fillRect(const QRectF &rect, const QColor &color); virtual void drawPixmap(const QRectF &rect, const QPixmap &pixmap, const QRectF &subrect); + IDirectFBSurface *dfbSurface() const; + + static DFBSurfacePixelFormat alphaPixmapFormat(); + static DFBSurfacePixelFormat pixmapFormat(); + static DFBSurfacePixelFormat selectPixmapFormat(bool withAlpha); + protected: virtual QImage *doLock(); virtual void doUnlock(); - IDirectFBSurface *m_surface; + QDirectFBPointer m_surface; QImage m_image; friend class QDirectFbConvenience; }; -class QDirectFbBlitterPixmapData : public QBlittablePixmapData +class QDirectFbBlitterPlatformPixmap : public QBlittablePixmapData { public: QBlittable *createBlittable(const QSize &size, bool alpha) const; + + QDirectFbBlitter *dfbBlitter() const; + + virtual bool fromFile(const QString &filename, const char *format, + Qt::ImageConversionFlags flags); + +private: + bool fromDataBufferDescription(const DFBDataBufferDescription &); }; -inline QBlittable *QDirectFbBlitterPixmapData::createBlittable(const QSize& size, bool alpha) const +inline QBlittable *QDirectFbBlitterPlatformPixmap::createBlittable(const QSize& size, bool alpha) const { return new QDirectFbBlitter(size, alpha); } +inline QDirectFbBlitter *QDirectFbBlitterPlatformPixmap::dfbBlitter() const +{ + return static_cast(blittable()); +} + +inline IDirectFBSurface *QDirectFbBlitter::dfbSurface() const +{ + return m_surface.data(); +} + +QT_END_NAMESPACE + #endif // QDIRECTFBBLITTER_H diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp index 37810dc..83c71b3 100644 --- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp +++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp @@ -41,16 +41,22 @@ #include "qdirectfbconvenience.h" #include "qdirectfbblitter.h" +#include "qdirectfbscreen.h" #include +#include +#include + +QT_BEGIN_NAMESPACE + IDirectFB *QDirectFbConvenience::dfbInterface() { static IDirectFB *dfb = 0; if (!dfb) { DFBResult result = DirectFBCreate(&dfb); if (result != DFB_OK) { - DirectFBError("QDirectFBConvenience: error creating DirectFB interface",result); + DirectFBErrorFatal("QDirectFBConvenience: error creating DirectFB interface", result); return 0; } } @@ -61,10 +67,9 @@ IDirectFBDisplayLayer *QDirectFbConvenience::dfbDisplayLayer(int display) { IDirectFBDisplayLayer *layer; DFBResult result = QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(),display,&layer); - if (result != DFB_OK) { - DirectFBError("QDirectFbConvenience: " - "Unable to get primary display layer!", result); - } + if (result != DFB_OK) + DirectFBErrorFatal("QDirectFbConvenience: " + "Unable to get primary display layer!", result); return layer; } @@ -106,13 +111,17 @@ int QDirectFbConvenience::colorDepthForSurface(const DFBSurfacePixelFormat forma return ((0x1f << 7) & format) >> 7; } -IDirectFBSurface *QDirectFbConvenience::dfbSurfaceForPixmapData(QPixmapData *pixmapData) +/** + * This is borrowing the reference of the QDirectFbBlitter. You may not store this + * pointer as a class member but must only use it locally. + */ +IDirectFBSurface *QDirectFbConvenience::dfbSurfaceForPlatformPixmap(QPixmapData *handle) { - QBlittablePixmapData *blittablePmData = static_cast(pixmapData); + QBlittablePixmapData *blittablePmData = static_cast(handle); if (blittablePmData) { QBlittable *blittable = blittablePmData->blittable(); QDirectFbBlitter *dfbBlitter = static_cast(blittable); - return dfbBlitter->m_surface; + return dfbBlitter->m_surface.data(); } return 0; } @@ -374,3 +383,15 @@ QDirectFbKeyMap::QDirectFbKeyMap() insert(DIKS_CURLY_BRACKET_RIGHT , Qt::Key_BraceRight); insert(DIKS_TILDE , Qt::Key_AsciiTilde); } + +QDirectFbScreen *toDfbScreen(QWidget *window) +{ + return static_cast(QPlatformScreen::platformScreenForWidget(window)); +} + +IDirectFBDisplayLayer *toDfbLayer(QPlatformScreen *screen) +{ + return static_cast(screen)->dfbLayer(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.h b/src/plugins/platforms/directfb/qdirectfbconvenience.h index c82bea8..d009393 100644 --- a/src/plugins/platforms/directfb/qdirectfbconvenience.h +++ b/src/plugins/platforms/directfb/qdirectfbconvenience.h @@ -49,6 +49,11 @@ #include +QT_BEGIN_NAMESPACE + +class QDirectFbScreen; +class QPlatformScreen; + class QDirectFbKeyMap: public QHash { public: @@ -67,7 +72,7 @@ public: static IDirectFB *dfbInterface(); static IDirectFBDisplayLayer *dfbDisplayLayer(int display = DLID_PRIMARY); - static IDirectFBSurface *dfbSurfaceForPixmapData(QPixmapData *); + static IDirectFBSurface *dfbSurfaceForPlatformPixmap(QPixmapData *); static Qt::MouseButton mouseButton(DFBInputDeviceButtonIdentifier identifier); static Qt::MouseButtons mouseButtons(DFBInputDeviceButtonMask mask); @@ -81,4 +86,41 @@ private: friend class QDirectFbIntegration; }; +template struct QDirectFBInterfaceCleanupHandler +{ + static void cleanup(T *t) + { + if (!t) + return; + t->Release(t); + } +}; + +template +class QDirectFBPointer : public QScopedPointer > +{ +public: + QDirectFBPointer(T *t = 0) + : QScopedPointer >(t) + {} + + T** outPtr() + { + this->reset(0); + return &this->d; + } +}; + +// Helper conversions from internal to DFB types +QDirectFbScreen *toDfbScreen(QWidget *window); +IDirectFBDisplayLayer *toDfbLayer(QPlatformScreen *screen); + +#define QDFB_STRINGIFY(x) #x +#define QDFB_TOSTRING(x) QDFB_STRINGIFY(x) +#define QDFB_PRETTY \ + (__FILE__ ":" QDFB_TOSTRING(__LINE__)) + +QT_END_NAMESPACE + + #endif // QDIRECTFBCONVENIENCE_H diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.cpp b/src/plugins/platforms/directfb/qdirectfbcursor.cpp index 8a38bc4..ea9be84 100644 --- a/src/plugins/platforms/directfb/qdirectfbcursor.cpp +++ b/src/plugins/platforms/directfb/qdirectfbcursor.cpp @@ -42,26 +42,25 @@ #include "qdirectfbcursor.h" #include "qdirectfbconvenience.h" +QT_BEGIN_NAMESPACE -QDirectFBCursor::QDirectFBCursor(QPlatformScreen* screen) : - QPlatformCursor(screen), surface(0) +QDirectFBCursor::QDirectFBCursor(QPlatformScreen *screen) + : QPlatformCursor(screen) { - QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(),DLID_PRIMARY, &m_layer); - image = new QPlatformCursorImage(0, 0, 0, 0, 0, 0); + m_image.reset(new QPlatformCursorImage(0, 0, 0, 0, 0, 0)); } -void QDirectFBCursor::changeCursor(QCursor * cursor, QWidget * widget) +void QDirectFBCursor::changeCursor(QCursor *cursor, QWidget *) { - Q_UNUSED(widget); int xSpot; int ySpot; QPixmap map; if (cursor->shape() != Qt::BitmapCursor) { - image->set(cursor->shape()); - xSpot = image->hotspot().x(); - ySpot = image->hotspot().y(); - QImage *i = image->image(); + m_image->set(cursor->shape()); + xSpot = m_image->hotspot().x(); + ySpot = m_image->hotspot().y(); + QImage *i = m_image->image(); map = QPixmap::fromImage(*i); } else { QPoint point = cursor->hotSpot(); @@ -70,11 +69,18 @@ void QDirectFBCursor::changeCursor(QCursor * cursor, QWidget * widget) map = cursor->pixmap(); } - IDirectFBSurface *surface = QDirectFbConvenience::dfbSurfaceForPixmapData(map.pixmapData()); + DFBResult res; + IDirectFBDisplayLayer *layer = toDfbLayer(screen); + IDirectFBSurface* surface(QDirectFbConvenience::dfbSurfaceForPlatformPixmap(map.pixmapData())); - if (m_layer->SetCooperativeLevel(m_layer, DLSCL_ADMINISTRATIVE) != DFB_OK) { + res = layer->SetCooperativeLevel(layer, DLSCL_ADMINISTRATIVE); + if (res != DFB_OK) { + DirectFBError("Failed to set DLSCL_ADMINISTRATIVE", res); return; } - m_layer->SetCursorShape( m_layer, surface, xSpot, ySpot); - m_layer->SetCooperativeLevel(m_layer, DLSCL_SHARED); + + layer->SetCursorShape(layer, surface, xSpot, ySpot); + layer->SetCooperativeLevel(layer, DLSCL_SHARED); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbcursor.h b/src/plugins/platforms/directfb/qdirectfbcursor.h index b148de5..2f8efba 100644 --- a/src/plugins/platforms/directfb/qdirectfbcursor.h +++ b/src/plugins/platforms/directfb/qdirectfbcursor.h @@ -44,20 +44,24 @@ #include #include + +#include "qdirectfbconvenience.h" + +QT_BEGIN_NAMESPACE + class QDirectFbScreen; class QDirectFbBlitter; class QDirectFBCursor : public QPlatformCursor { public: - QDirectFBCursor(QPlatformScreen *screem); - void changeCursor(QCursor * cursor, QWidget * widget); + QDirectFBCursor(QPlatformScreen *screen); + void changeCursor(QCursor *cursor, QWidget *window); private: - IDirectFBDisplayLayer * m_layer; - IDirectFBSurface * surface; - QPlatformCursorImage * image; - QDirectFbBlitter *blitter; + QScopedPointer m_image; }; +QT_END_NAMESPACE + #endif // QDIRECTFBCURSOR_H diff --git a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp index aca28f1..4111774 100644 --- a/src/plugins/platforms/directfb/qdirectfbglcontext.cpp +++ b/src/plugins/platforms/directfb/qdirectfbglcontext.cpp @@ -45,6 +45,8 @@ #include +QT_BEGIN_NAMESPACE + QDirectFbGLContext::QDirectFbGLContext(IDirectFBGL *glContext) : m_dfbGlContext(glContext) { @@ -99,3 +101,5 @@ QPlatformWindowFormat QDirectFbGLContext::platformWindowFormat() const { return m_windowFormat; } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbinput.cpp b/src/plugins/platforms/directfb/qdirectfbinput.cpp index d35cea5..34dbc9d 100644 --- a/src/plugins/platforms/directfb/qdirectfbinput.cpp +++ b/src/plugins/platforms/directfb/qdirectfbinput.cpp @@ -47,65 +47,71 @@ #include #include #include -#include #include -QDirectFbInput::QDirectFbInput(QObject *parent) - : QObject(parent), m_shouldStop(false) -{ - m_dfbInterface = QDirectFbConvenience::dfbInterface(); +QT_BEGIN_NAMESPACE - DFBResult ok = m_dfbInterface->CreateEventBuffer(m_dfbInterface,&m_eventBuffer); +QDirectFbInput::QDirectFbInput(IDirectFB *dfb, IDirectFBDisplayLayer *dfbLayer) + : m_dfbInterface(dfb) + , m_dfbDisplayLayer(dfbLayer) + , m_shouldStop(false) +{ + DFBResult ok = m_dfbInterface->CreateEventBuffer(m_dfbInterface, m_eventBuffer.outPtr()); if (ok != DFB_OK) DirectFBError("Failed to initialise eventbuffer", ok); - - m_dfbInterface->GetDisplayLayer(m_dfbInterface,DLID_PRIMARY, &m_dfbDisplayLayer); - } -void QDirectFbInput::runInputEventLoop() +void QDirectFbInput::run() { - while (true) { - m_eventBuffer->WaitForEvent(m_eventBuffer); - if (m_shouldStop) { - m_waitStop.release(); - break; - } - handleEvents(); + while (!m_shouldStop) { + if (m_eventBuffer->WaitForEvent(m_eventBuffer.data()) == DFB_OK) + handleEvents(); } } void QDirectFbInput::stopInputEventLoop() { m_shouldStop = true; - m_waitStop.acquire(); + m_eventBuffer->WakeUp(m_eventBuffer.data()); } -void QDirectFbInput::addWindow(DFBWindowID id, QWidget *tlw) +void QDirectFbInput::addWindow(IDirectFBWindow *window, QWidget *platformWindow) { - m_tlwMap.insert(id,tlw); - IDirectFBWindow *window; - m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,id,&window); + DFBResult res; + DFBWindowID id; - window->AttachEventBuffer(window,m_eventBuffer); + res = window->GetID(window, &id); + if (res != DFB_OK) { + DirectFBError("QDirectFbInput::addWindow", res); + return; + } + + m_tlwMap.insert(id, platformWindow); + window->AttachEventBuffer(window, m_eventBuffer.data()); } -void QDirectFbInput::removeWindow(WId wId) +void QDirectFbInput::removeWindow(IDirectFBWindow *window) { - IDirectFBWindow *window; - m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,wId, &window); + DFBResult res; + DFBWindowID id; - window->DetachEventBuffer(window,m_eventBuffer); - m_tlwMap.remove(wId); + res = window->GetID(window, &id); + if (res != DFB_OK) { + DirectFBError("QDirectFbInput::removeWindow", res); + return; + } + + window->DetachEventBuffer(window, m_eventBuffer.data()); + m_tlwMap.remove(id); } void QDirectFbInput::handleEvents() { - DFBResult hasEvent = m_eventBuffer->HasEvent(m_eventBuffer); + DFBResult hasEvent = m_eventBuffer->HasEvent(m_eventBuffer.data()); while(hasEvent == DFB_OK){ DFBEvent event; - DFBResult ok = m_eventBuffer->GetEvent(m_eventBuffer,&event); + DFBResult ok = m_eventBuffer->GetEvent(m_eventBuffer.data(), &event); if (ok != DFB_OK) DirectFBError("Failed to get event",ok); if (event.clazz == DFEC_WINDOW) { @@ -131,7 +137,7 @@ void QDirectFbInput::handleEvents() } - hasEvent = m_eventBuffer->HasEvent(m_eventBuffer); + hasEvent = m_eventBuffer->HasEvent(m_eventBuffer.data()); } } @@ -141,17 +147,12 @@ void QDirectFbInput::handleMouseEvents(const DFBEvent &event) QPoint globalPos = globalPoint(event); Qt::MouseButtons buttons = QDirectFbConvenience::mouseButtons(event.window.buttons); - IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer(); - IDirectFBWindow *window; - layer->GetWindow(layer,event.window.window_id,&window); + QDirectFBPointer layer(QDirectFbConvenience::dfbDisplayLayer()); + QDirectFBPointer window; + layer->GetWindow(layer.data(), event.window.window_id, window.outPtr()); long timestamp = (event.window.timestamp.tv_sec*1000) + (event.window.timestamp.tv_usec/1000); - if (event.window.type == DWET_BUTTONDOWN) { - window->GrabPointer(window); - } else if (event.window.type == DWET_BUTTONUP) { - window->UngrabPointer(window); - } QWidget *tlw = m_tlwMap.value(event.window.window_id); QWindowSystemInterface::handleMouseEvent(tlw, timestamp, p, globalPos, buttons); } @@ -199,10 +200,11 @@ void QDirectFbInput::handleEnterLeaveEvents(const DFBEvent &event) inline QPoint QDirectFbInput::globalPoint(const DFBEvent &event) const { - IDirectFBWindow *window; - m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer,event.window.window_id,&window); + QDirectFBPointer window; + m_dfbDisplayLayer->GetWindow(m_dfbDisplayLayer, event.window.window_id, window.outPtr()); int x,y; - window->GetPosition(window,&x,&y); + window->GetPosition(window.data(), &x, &y); return QPoint(event.window.cx +x, event.window.cy + y); } +QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbinput.h b/src/plugins/platforms/directfb/qdirectfbinput.h index 3b8008f..698ee3a 100644 --- a/src/plugins/platforms/directfb/qdirectfbinput.h +++ b/src/plugins/platforms/directfb/qdirectfbinput.h @@ -42,30 +42,30 @@ #ifndef QDIRECTFBINPUT_H #define QDIRECTFBINPUT_H -#include -#include +#include #include #include #include #include -#include +#include "qdirectfbconvenience.h" -class QDirectFbInput : public QObject +class QDirectFbInput : public QThread { Q_OBJECT public: - QDirectFbInput(QObject *parent); - void addWindow(DFBWindowID id, QWidget *tlw); - void removeWindow(WId wId); + QDirectFbInput(IDirectFB *dfb, IDirectFBDisplayLayer *dfbLayer); + void addWindow(IDirectFBWindow *window, QWidget *platformWindow); + void removeWindow(IDirectFBWindow *window); -public slots: - void runInputEventLoop(); void stopInputEventLoop(); - void handleEvents(); + +protected: + void run(); private: + void handleEvents(); void handleMouseEvents(const DFBEvent &event); void handleWheelEvent(const DFBEvent &event); void handleKeyEvents(const DFBEvent &event); @@ -75,11 +75,9 @@ private: IDirectFB *m_dfbInterface; IDirectFBDisplayLayer *m_dfbDisplayLayer; - IDirectFBEventBuffer *m_eventBuffer; + QDirectFBPointer m_eventBuffer; bool m_shouldStop; - QSemaphore m_waitStop; - QHashm_tlwMap; }; diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp index 06b0b51..15f0036 100644 --- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp +++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp @@ -46,43 +46,27 @@ #include "qdirectfbcursor.h" #include "qdirectfbwindow.h" -#include "qgenericunixfontdatabase.h" - -#include -#include - #include -#include +#include #include #include -QT_BEGIN_NAMESPACE - -QDirectFbScreen::QDirectFbScreen(int display) - :QPlatformScreen() -{ - m_layer = QDirectFbConvenience::dfbDisplayLayer(display); - m_layer->SetCooperativeLevel(m_layer,DLSCL_SHARED); - - DFBDisplayLayerConfig config; - m_layer->GetConfiguration(m_layer, &config); +#include "qgenericunixfontdatabase.h" - m_format = QDirectFbConvenience::imageFormatFromSurfaceFormat(config.pixelformat, config.surface_caps); - m_geometry = QRect(0,0,config.width,config.height); - const int dpi = 72; - const qreal inch = 25.4; - m_depth = QDirectFbConvenience::colorDepthForSurface(config.pixelformat); - m_physicalSize = QSize(qRound(config.width * inch / dpi), qRound(config.height *inch / dpi)); +QT_BEGIN_NAMESPACE - cursor = new QDirectFBCursor(this); -} +QDirectFbIntegration::QDirectFbIntegration() + : m_fontDb(new QGenericUnixFontDatabase()) +{} -QDirectFbScreen::~QDirectFbScreen() +void QDirectFbIntegration::initialize() { + initializeDirectFB(); + initializeScreen(); + initializeInput(); } -QDirectFbIntegration::QDirectFbIntegration() - : mFontDb(new QGenericUnixFontDatabase()) +void QDirectFbIntegration::initializeDirectFB() { const QStringList args = QCoreApplication::arguments(); int argc = args.size(); @@ -96,26 +80,31 @@ QDirectFbIntegration::QDirectFbIntegration() DirectFBError("QDirectFBScreen: error initializing DirectFB", result); } + + for (int i = 0; i < argc; ++i) + delete[] argv[i]; delete[] argv; + // This must happen after DirectFBInit. + m_dfb.reset(QDirectFbConvenience::dfbInterface()); +} - QDirectFbScreen *primaryScreen = new QDirectFbScreen(0); - mScreens.append(primaryScreen); +void QDirectFbIntegration::initializeScreen() +{ + m_primaryScreen.reset(new QDirectFbScreen(0)); + mScreens.append(m_primaryScreen.data()); +} - mInputRunner = new QThread; - mInput = new QDirectFbInput(0); - mInput->moveToThread(mInputRunner); - QObject::connect(mInputRunner,SIGNAL(started()),mInput,SLOT(runInputEventLoop())); - mInputRunner->start(); +void QDirectFbIntegration::initializeInput() +{ + m_input.reset(new QDirectFbInput(m_dfb.data(), m_primaryScreen->dfbLayer())); + m_input->start(); } QDirectFbIntegration::~QDirectFbIntegration() { - mInput->stopInputEventLoop(); - mInputRunner->quit(); - mInputRunner->wait(); - delete mInputRunner; - delete mInput; + m_input->stopInputEventLoop(); + m_input->wait(); } QPixmapData *QDirectFbIntegration::createPixmapData(QPixmapData::PixelType type) const @@ -123,24 +112,22 @@ QPixmapData *QDirectFbIntegration::createPixmapData(QPixmapData::PixelType type) if (type == QPixmapData::BitmapType) return new QRasterPixmapData(type); else - return new QDirectFbBlitterPixmapData; + return new QDirectFbBlitterPlatformPixmap; } -QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWidget *widget, WId winId) const +QPlatformWindow *QDirectFbIntegration::createPlatformWindow(QWidget *window, WId) const { - Q_UNUSED(winId); - QDirectFbInput *input = const_cast(mInput);//gah - return new QDirectFbWindow(widget,input); + return new QDirectFbWindow(window,m_input.data()); } -QWindowSurface *QDirectFbIntegration::createWindowSurface(QWidget *widget, WId winId) const +QWindowSurface *QDirectFbIntegration::createWindowSurface(QWidget *window, WId) const { - return new QDirectFbWindowSurface(widget,winId); + return new QDirectFbWindowSurface(window); } QPlatformFontDatabase *QDirectFbIntegration::fontDatabase() const { - return mFontDb; + return m_fontDb.data(); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h index 0e8337a..93e3d60 100644 --- a/src/plugins/platforms/directfb/qdirectfbintegration.h +++ b/src/plugins/platforms/directfb/qdirectfbintegration.h @@ -43,6 +43,7 @@ #define QPLATFORMINTEGRATION_DIRECTFB_H #include "qdirectfbinput.h" +#include "qdirectfbscreen.h" #include #include @@ -51,32 +52,6 @@ QT_BEGIN_NAMESPACE class QThread; -class QDirectFBCursor; - -class QDirectFbScreen : public QPlatformScreen -{ -Q_OBJECT -public: - QDirectFbScreen(int display); - ~QDirectFbScreen(); - - QRect geometry() const { return m_geometry; } - int depth() const { return m_depth; } - QImage::Format format() const { return m_format; } - QSize physicalSize() const { return m_physicalSize; } - -public: - QRect m_geometry; - int m_depth; - QImage::Format m_format; - QSize m_physicalSize; - - IDirectFBDisplayLayer *m_layer; - -private: - QDirectFBCursor * cursor; - -}; class QDirectFbIntegration : public QPlatformIntegration { @@ -92,11 +67,20 @@ public: QPlatformFontDatabase *fontDatabase() const; -private: + void initialize(); + +protected: + virtual void initializeDirectFB(); + virtual void initializeScreen(); + virtual void initializeInput(); + +protected: QList mScreens; - QDirectFbInput *mInput; - QThread *mInputRunner; - QPlatformFontDatabase *mFontDb; + QDirectFBPointer m_dfb; + QScopedPointer m_primaryScreen; + QScopedPointer m_input; + QScopedPointer m_inputRunner; + QScopedPointer m_fontDb; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbscreen.cpp b/src/plugins/platforms/directfb/qdirectfbscreen.cpp new file mode 100644 index 0000000..1d4b701 --- /dev/null +++ b/src/plugins/platforms/directfb/qdirectfbscreen.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdirectfbscreen.h" +#include "qdirectfbcursor.h" + +QT_BEGIN_NAMESPACE + +QDirectFbScreen::QDirectFbScreen(int display) + : QPlatformScreen() + , m_layer(QDirectFbConvenience::dfbDisplayLayer(display)) +{ + m_layer->SetCooperativeLevel(m_layer.data(), DLSCL_SHARED); + + DFBDisplayLayerConfig config; + m_layer->GetConfiguration(m_layer.data(), &config); + + m_format = QDirectFbConvenience::imageFormatFromSurfaceFormat(config.pixelformat, config.surface_caps); + m_geometry = QRect(0, 0, config.width, config.height); + const int dpi = 72; + const qreal inch = 25.4; + m_depth = QDirectFbConvenience::colorDepthForSurface(config.pixelformat); + m_physicalSize = QSize(config.width, config.height) * inch / dpi; + + m_cursor.reset(new QDirectFBCursor(this)); +} + +IDirectFBDisplayLayer *QDirectFbScreen::dfbLayer() const +{ + return m_layer.data(); +} + + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbscreen.h b/src/plugins/platforms/directfb/qdirectfbscreen.h new file mode 100644 index 0000000..1ec3a48 --- /dev/null +++ b/src/plugins/platforms/directfb/qdirectfbscreen.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDIRECTFBSCREEN_H +#define QDIRECTFBSCREEN_H + +#include "qdirectfbconvenience.h" +#include "qdirectfbcursor.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + + +class QDirectFbScreen : public QPlatformScreen +{ +public: + QDirectFbScreen(int display); + + QRect geometry() const { return m_geometry; } + int depth() const { return m_depth; } + QImage::Format format() const { return m_format; } + QSize physicalSize() const { return m_physicalSize; } + + // DirectFb helpers + IDirectFBDisplayLayer *dfbLayer() const; + +public: + QRect m_geometry; + int m_depth; + QImage::Format m_format; + QSize m_physicalSize; + + QDirectFBPointer m_layer; + +private: + QScopedPointer m_cursor; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.cpp b/src/plugins/platforms/directfb/qdirectfbwindow.cpp index d2c411e..0b6be91 100644 --- a/src/plugins/platforms/directfb/qdirectfbwindow.cpp +++ b/src/plugins/platforms/directfb/qdirectfbwindow.cpp @@ -40,21 +40,23 @@ ****************************************************************************/ #include "qdirectfbwindow.h" +#include "qdirectfbwindowsurface.h" #include "qdirectfbinput.h" -#include "qdirectfbglcontext.h" - -#include +#include "qdirectfbscreen.h" -#include "qdirectfbwindowsurface.h" #include +QT_BEGIN_NAMESPACE + QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler) - : QPlatformWindow(tlw), m_inputHandler(inputhandler), m_context(0) + : QPlatformWindow(tlw), m_inputHandler(inputhandler) { - IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer(); DFBDisplayLayerConfig layerConfig; - layer->GetConfiguration(layer,&layerConfig); + IDirectFBDisplayLayer *layer; + + layer = toDfbScreen(tlw)->dfbLayer(); + toDfbScreen(tlw)->dfbLayer()->GetConfiguration(layer, &layerConfig); DFBWindowDescription description; memset(&description,0,sizeof(DFBWindowDescription)); @@ -63,10 +65,10 @@ QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler) |DWDESC_OPTIONS #endif |DWDESC_CAPS); - description.width = tlw->rect().width(); - description.height = tlw->rect().height(); - description.posx = tlw->rect().x(); - description.posy = tlw->rect().y(); + description.width = tlw->width(); + description.height = tlw->height(); + description.posx = tlw->x(); + description.posy = tlw->y(); if (layerConfig.surface_caps & DSCAPS_PREMULTIPLIED) description.surface_caps = DSCAPS_PREMULTIPLIED; @@ -78,34 +80,32 @@ QDirectFbWindow::QDirectFbWindow(QWidget *tlw, QDirectFbInput *inputhandler) description.caps = DFBWindowCapabilities(DWCAPS_DOUBLEBUFFER|DWCAPS_ALPHACHANNEL); description.surface_caps = DSCAPS_PREMULTIPLIED; - DFBResult result = layer->CreateWindow(layer,&description,&m_dfbWindow); + DFBResult result = layer->CreateWindow(layer, &description, m_dfbWindow.outPtr()); if (result != DFB_OK) { DirectFBError("QDirectFbGraphicsSystemScreen: failed to create window",result); } - m_dfbWindow->SetOpacity(m_dfbWindow,0xff); + m_dfbWindow->SetOpacity(m_dfbWindow.data(), 0xff); setVisible(widget()->isVisible()); - DFBWindowID id; - m_dfbWindow->GetID(m_dfbWindow, &id); - m_inputHandler->addWindow(id,tlw); + m_inputHandler->addWindow(m_dfbWindow.data(), tlw); } QDirectFbWindow::~QDirectFbWindow() { - m_inputHandler->removeWindow(winId()); - m_dfbWindow->Destroy(m_dfbWindow); + m_inputHandler->removeWindow(m_dfbWindow.data()); + m_dfbWindow->Destroy(m_dfbWindow.data()); } void QDirectFbWindow::setGeometry(const QRect &rect) { bool isMoveOnly = (rect.topLeft() != geometry().topLeft()) && (rect.size() == geometry().size()); + QPlatformWindow::setGeometry(rect); if (widget()->isVisible() && !(widget()->testAttribute(Qt::WA_DontShowOnScreen))) { - m_dfbWindow->SetBounds(m_dfbWindow, rect.x(),rect.y(), + m_dfbWindow->SetBounds(m_dfbWindow.data(), rect.x(),rect.y(), rect.width(), rect.height()); - //Hack. When moving since the WindowSurface of a window becomes invalid when moved if (isMoveOnly) { //if resize then windowsurface is updated. widget()->windowSurface()->resize(rect.size()); @@ -117,7 +117,7 @@ void QDirectFbWindow::setGeometry(const QRect &rect) void QDirectFbWindow::setOpacity(qreal level) { const quint8 windowOpacity = quint8(level * 0xff); - m_dfbWindow->SetOpacity(m_dfbWindow,windowOpacity); + m_dfbWindow->SetOpacity(m_dfbWindow.data(), windowOpacity); } void QDirectFbWindow::setVisible(bool visible) @@ -125,14 +125,14 @@ void QDirectFbWindow::setVisible(bool visible) if (visible) { int x = geometry().x(); int y = geometry().y(); - m_dfbWindow->MoveTo(m_dfbWindow,x,y); + m_dfbWindow->MoveTo(m_dfbWindow.data(), x, y); } else { - IDirectFBDisplayLayer *displayLayer; - QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(),DLID_PRIMARY,&displayLayer); + QDirectFBPointer displayLayer; + QDirectFbConvenience::dfbInterface()->GetDisplayLayer(QDirectFbConvenience::dfbInterface(), DLID_PRIMARY, displayLayer.outPtr()); DFBDisplayLayerConfig config; - displayLayer->GetConfiguration(displayLayer,&config); - m_dfbWindow->MoveTo(m_dfbWindow,config.width+1,config.height + 1); + displayLayer->GetConfiguration(displayLayer.data(), &config); + m_dfbWindow->MoveTo(m_dfbWindow.data(), config. width + 1, config.height + 1); } } @@ -141,51 +141,73 @@ Qt::WindowFlags QDirectFbWindow::setWindowFlags(Qt::WindowFlags flags) switch (flags & Qt::WindowType_Mask) { case Qt::ToolTip: { DFBWindowOptions options; - m_dfbWindow->GetOptions(m_dfbWindow,&options); + m_dfbWindow->GetOptions(m_dfbWindow.data(), &options); options = DFBWindowOptions(options | DWOP_GHOST); - m_dfbWindow->SetOptions(m_dfbWindow,options); + m_dfbWindow->SetOptions(m_dfbWindow.data(), options); break; } default: break; } - m_dfbWindow->SetStackingClass(m_dfbWindow, flags & Qt::WindowStaysOnTopHint ? DWSC_UPPER : DWSC_MIDDLE); + m_dfbWindow->SetStackingClass(m_dfbWindow.data(), flags & Qt::WindowStaysOnTopHint ? DWSC_UPPER : DWSC_MIDDLE); return flags; } void QDirectFbWindow::raise() { - m_dfbWindow->RaiseToTop(m_dfbWindow); + m_dfbWindow->RaiseToTop(m_dfbWindow.data()); } void QDirectFbWindow::lower() { - m_dfbWindow->LowerToBottom(m_dfbWindow); + m_dfbWindow->LowerToBottom(m_dfbWindow.data()); } WId QDirectFbWindow::winId() const { DFBWindowID id; - m_dfbWindow->GetID(m_dfbWindow, &id); + m_dfbWindow->GetID(m_dfbWindow.data(), &id); return WId(id); } -QPlatformGLContext *QDirectFbWindow::glContext() const +bool QDirectFbWindow::setKeyboardGrabEnabled(bool grab) { - if (!m_context) { - IDirectFBSurface *surface; - DFBResult result = m_dfbWindow->GetSurface(m_dfbWindow,&surface); - if (result != DFB_OK) { - qWarning("could not retrieve surface in QDirectFbWindow::glContext()"); - return 0; - } - IDirectFBGL *gl; - result = surface->GetGL(surface,&gl); - if (result != DFB_OK) { - qWarning("could not retrieve IDirectFBGL in QDirectFbWindow::glContext()"); - return 0; - } - const_cast(this)->m_context = new QDirectFbGLContext(gl); + DFBResult res; + + if (grab) + res = m_dfbWindow->GrabKeyboard(m_dfbWindow.data()); + else + res = m_dfbWindow->UngrabKeyboard(m_dfbWindow.data()); + + return res == DFB_OK; +} + +bool QDirectFbWindow::setMouseGrabEnabled(bool grab) +{ + DFBResult res; + + if (grab) + res = m_dfbWindow->GrabPointer(m_dfbWindow.data()); + else + res = m_dfbWindow->UngrabPointer(m_dfbWindow.data()); + + return res == DFB_OK; +} + +IDirectFBWindow *QDirectFbWindow::dfbWindow() const +{ + return m_dfbWindow.data(); +} + +IDirectFBSurface *QDirectFbWindow::dfbSurface() +{ + if (!m_dfbSurface) { + DFBResult res = m_dfbWindow->GetSurface(m_dfbWindow.data(), m_dfbSurface.outPtr()); + if (res != DFB_OK) + DirectFBError(QDFB_PRETTY, res); } - return m_context; + + return m_dfbSurface.data(); } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbwindow.h b/src/plugins/platforms/directfb/qdirectfbwindow.h index 4f839a0..349d8c8 100644 --- a/src/plugins/platforms/directfb/qdirectfbwindow.h +++ b/src/plugins/platforms/directfb/qdirectfbwindow.h @@ -61,17 +61,21 @@ public: void setVisible(bool visible); Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags); + bool setKeyboardGrabEnabled(bool grab); + bool setMouseGrabEnabled(bool grab); void raise(); void lower(); WId winId() const; - QPlatformGLContext *glContext() const; + IDirectFBWindow *dfbWindow() const; + + // helper to get access to DirectFB types + IDirectFBSurface *dfbSurface(); private: - IDirectFBWindow *m_dfbWindow; + QDirectFBPointer m_dfbSurface; + QDirectFBPointer m_dfbWindow; QDirectFbInput *m_inputHandler; - - QPlatformGLContext *m_context; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp b/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp index 730f01f..bf98e1d 100644 --- a/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/platforms/directfb/qdirectfbwindowsurface.cpp @@ -43,39 +43,29 @@ #include "qdirectfbintegration.h" #include "qdirectfbblitter.h" #include "qdirectfbconvenience.h" +#include "qdirectfbwindow.h" #include #include QT_BEGIN_NAMESPACE -QDirectFbWindowSurface::QDirectFbWindowSurface(QWidget *window, WId wId) - : QWindowSurface(window), m_pixmap(0), m_pmdata(0), m_dfbSurface(0) +QDirectFbWindowSurface::QDirectFbWindowSurface(QWidget *window) + : QWindowSurface(window), m_pixmap(0), m_pmdata(0) { + IDirectFBWindow *dfbWindow = static_cast(window->platformWindow())->dfbWindow(); + dfbWindow->GetSurface(dfbWindow, m_dfbSurface.outPtr()); - IDirectFBDisplayLayer *layer = QDirectFbConvenience::dfbDisplayLayer(); - - DFBWindowID id(wId); - IDirectFBWindow *dfbWindow; - - layer->GetWindow(layer,id,&dfbWindow); - - dfbWindow->GetSurface(dfbWindow,&m_dfbSurface); //WRONGSIZE - QDirectFbBlitter *blitter = new QDirectFbBlitter(window->rect().size(), m_dfbSurface); - m_pmdata = new QDirectFbBlitterPixmapData; + QDirectFbBlitter *blitter = new QDirectFbBlitter(window->size(), m_dfbSurface.data()); + m_pmdata = new QDirectFbBlitterPlatformPixmap; m_pmdata->setBlittable(blitter); - m_pixmap = new QPixmap(m_pmdata); -} - -QDirectFbWindowSurface::~QDirectFbWindowSurface() -{ - delete m_pixmap; + m_pixmap.reset(new QPixmap(m_pmdata)); } QPaintDevice *QDirectFbWindowSurface::paintDevice() { - return m_pixmap; + return m_pixmap.data(); } void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) @@ -87,17 +77,13 @@ void QDirectFbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const for (int i = 0 ; i < rects.size(); i++) { const QRect rect = rects.at(i); DFBRegion dfbReg = { rect.x() + offset.x(),rect.y() + offset.y(),rect.right() + offset.x(),rect.bottom() + offset.y()}; - m_dfbSurface->Flip(m_dfbSurface, &dfbReg, DFBSurfaceFlipFlags(DSFLIP_BLIT|DSFLIP_ONSYNC)); + m_dfbSurface->Flip(m_dfbSurface.data(), &dfbReg, DFBSurfaceFlipFlags(DSFLIP_BLIT|DSFLIP_ONSYNC)); } } void QDirectFbWindowSurface::resize(const QSize &size) { - QWindowSurface::resize(size); - - //Have to add 1 ref ass it will be removed by deleting the old blitter in setBlittable - m_dfbSurface->AddRef(m_dfbSurface); - QDirectFbBlitter *blitter = new QDirectFbBlitter(size,m_dfbSurface); + QDirectFbBlitter *blitter = new QDirectFbBlitter(size, m_dfbSurface.data()); m_pmdata->setBlittable(blitter); } @@ -115,14 +101,14 @@ bool QDirectFbWindowSurface::scroll(const QRegion &area, int dx, int dy) if (!m_dfbSurface || area.isEmpty()) return false; - m_dfbSurface->SetBlittingFlags(m_dfbSurface, DSBLIT_NOFX); + m_dfbSurface->SetBlittingFlags(m_dfbSurface.data(), DSBLIT_NOFX); if (area.rectCount() == 1) { - scrollSurface(m_dfbSurface, area.boundingRect(), dx, dy); + scrollSurface(m_dfbSurface.data(), area.boundingRect(), dx, dy); } else { const QVector rects = area.rects(); const int n = rects.size(); for (int i=0; i #include - #include +#include "qdirectfbconvenience.h" + QT_BEGIN_NAMESPACE class QDirectFbWindowSurface : public QWindowSurface { public: - QDirectFbWindowSurface(QWidget *window, WId wid); - ~QDirectFbWindowSurface(); + QDirectFbWindowSurface(QWidget *window); QPaintDevice *paintDevice(); void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); @@ -66,10 +66,9 @@ public: private: void lockSurfaceToImage(); - QPixmap *m_pixmap; + QScopedPointer m_pixmap; QBlittablePixmapData *m_pmdata; - - IDirectFBSurface *m_dfbSurface; + QDirectFBPointer m_dfbSurface; }; QT_END_NAMESPACE -- cgit v0.12