diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-12-15 00:05:09 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-12-15 00:05:09 (GMT) |
commit | ae81a6d27fe090b63fa04ddcb0424e2058a83110 (patch) | |
tree | d044164a9f4aaa3ae875c2c6859573fc1259168d | |
parent | 1a5d32b9729d887ef9e25f6994e5f78466333d6a (diff) | |
parent | 8d856c470fd4a5abea3e0047c2837a7e45831812 (diff) | |
download | Qt-ae81a6d27fe090b63fa04ddcb0424e2058a83110.zip Qt-ae81a6d27fe090b63fa04ddcb0424e2058a83110.tar.gz Qt-ae81a6d27fe090b63fa04ddcb0424e2058a83110.tar.bz2 |
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qt-water-team
* 'master' of git://scm.dev.nokia.troll.no/qt/qt-water-team:
Default to QDir::homePath() in Symbian native file dialogs
directfb: Backport the work from QtBase to Qt 4.8
[blitter] Work on tst_QPixmap::clear()
[blitter] Use QScopedPointer for the engine and blittable
[blitter] Generate a new serial number when resizing the
[blitter] Fix memory leak in the blitter paintengine
Fix NTLM authentication with email address
Fix null pointer dereference in NTLM authentication
25 files changed, 714 insertions, 319 deletions
diff --git a/src/gui/dialogs/qfiledialog_symbian.cpp b/src/gui/dialogs/qfiledialog_symbian.cpp index 1ffbf1d..01c7b9b 100644 --- a/src/gui/dialogs/qfiledialog_symbian.cpp +++ b/src/gui/dialogs/qfiledialog_symbian.cpp @@ -143,8 +143,8 @@ static QString launchSymbianDialog(const QString dialogCaption, const QString st tryCount = 0; } else { // Symbian native file dialog doesn't allow accessing files outside C:/Data - // It will always leave in that case, so default into QDir::rootPath() in error cases. - QString dir = QDir::toNativeSeparators(QDir::rootPath()); + // It will always leave in that case, so default into QDir::homePath() in error cases. + QString dir = QDir::toNativeSeparators(QDir::homePath()); startFolder = qt_QString2TPtrC(dir); } } diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index f3a4318..c73e6a9 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -57,7 +57,8 @@ QT_BEGIN_NAMESPACE static int global_ser_no = 0; QBlittablePixmapData::QBlittablePixmapData() - : QPixmapData(QPixmapData::PixmapType,BlitterClass), m_engine(0), m_blittable(0) + : QPixmapData(QPixmapData::PixmapType,BlitterClass) + , m_alpha(false) #ifdef QT_BLITTER_RASTEROVERLAY ,m_rasterOverlay(0), m_unmergedCopy(0) #endif //QT_BLITTER_RASTEROVERLAY @@ -67,8 +68,6 @@ QBlittablePixmapData::QBlittablePixmapData() QBlittablePixmapData::~QBlittablePixmapData() { - delete m_blittable; - delete m_engine; #ifdef QT_BLITTER_RASTEROVERLAY delete m_rasterOverlay; delete m_unmergedCopy; @@ -79,31 +78,30 @@ QBlittable *QBlittablePixmapData::blittable() const { if (!m_blittable) { QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this); - that->m_blittable = this->createBlittable(QSize(w,h)); + that->m_blittable.reset(this->createBlittable(QSize(w,h), m_alpha)); } - return m_blittable; + return m_blittable.data(); } void QBlittablePixmapData::setBlittable(QBlittable *blittable) { resize(blittable->size().width(),blittable->size().height()); - m_blittable = blittable; + m_blittable.reset(blittable); } void QBlittablePixmapData::resize(int width, int height) { - delete m_blittable; - m_blittable = 0; - delete m_engine; - m_engine = 0; + m_blittable.reset(0); + m_engine.reset(0); #ifdef Q_WS_QPA d = QApplicationPrivate::platformIntegration()->screens().at(0)->depth(); #endif w = width; h = height; is_null = (w <= 0 || h <= 0); + setSerialNumber(++global_ser_no); } int QBlittablePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const @@ -139,7 +137,16 @@ void QBlittablePixmapData::fill(const QColor &color) if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) { blittable()->unlock(); blittable()->fillRect(QRectF(0,0,w,h),color); - }else { + } else { + // Need to be backed with an alpha channel now. It would be nice + // if we could just change the format, e.g. when going from + // RGB32 -> ARGB8888. + if (color.alpha() != 255 && !hasAlphaChannel()) { + m_blittable.reset(0); + m_engine.reset(0); + m_alpha = true; + } + uint pixel; switch (blittable()->lock()->format()) { case QImage::Format_ARGB32_Premultiplied: @@ -185,6 +192,7 @@ bool QBlittablePixmapData::hasAlphaChannel() const void QBlittablePixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags) { + m_alpha = image.hasAlphaChannel(); resize(image.width(),image.height()); markRasterOverlay(QRect(0,0,w,h)); QImage *thisImg = buffer(); @@ -208,9 +216,9 @@ QPaintEngine *QBlittablePixmapData::paintEngine() const { if (!m_engine) { QBlittablePixmapData *that = const_cast<QBlittablePixmapData *>(this); - that->m_engine = new QBlitterPaintEngine(that); + that->m_engine.reset(new QBlitterPaintEngine(that)); } - return m_engine; + return m_engine.data(); } #ifdef QT_BLITTER_RASTEROVERLAY diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h index 07791e5..4742a83 100644 --- a/src/gui/image/qpixmap_blitter_p.h +++ b/src/gui/image/qpixmap_blitter_p.h @@ -55,7 +55,7 @@ public: QBlittablePixmapData(); ~QBlittablePixmapData(); - virtual QBlittable *createBlittable(const QSize &size) const = 0; + virtual QBlittable *createBlittable(const QSize &size, bool alpha) const = 0; QBlittable *blittable() const; void setBlittable(QBlittable *blittable); @@ -83,8 +83,9 @@ public: #endif //QT_BLITTER_RASTEROVERLAY protected: - QBlitterPaintEngine *m_engine; - QBlittable *m_blittable; + QScopedPointer<QBlitterPaintEngine> m_engine; + QScopedPointer<QBlittable> m_blittable; + bool m_alpha; #ifdef QT_BLITTER_RASTEROVERLAY QImage *m_rasterOverlay; diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp index 75efa20..69f0301 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -198,8 +198,8 @@ public: hasXForm(false) { - raster = new QRasterPaintEngine(p->buffer()); - capabillities = new CapabilitiesToStateMask(pmData->blittable()->capabilities()); + raster.reset(new QRasterPaintEngine(p->buffer())); + capabillities.reset(new CapabilitiesToStateMask(pmData->blittable()->capabilities())); } inline void lock() { @@ -279,12 +279,12 @@ public: raster->d_func()->systemStateChanged(); } - QRasterPaintEngine *raster; + QScopedPointer<QRasterPaintEngine> raster; QBlittablePixmapData *pmData; bool isBlitterLocked; - CapabilitiesToStateMask *capabillities; + QScopedPointer<CapabilitiesToStateMask> capabillities; uint hasXForm; }; @@ -655,7 +655,7 @@ void QBlitterPaintEngine::setState(QPainterState *s) inline QRasterPaintEngine *QBlitterPaintEngine::raster() const { Q_D(const QBlitterPaintEngine); - return d->raster; + return d->raster.data(); } QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccessauthenticationmanager.cpp b/src/network/access/qnetworkaccessauthenticationmanager.cpp index 1b15cf9..b618ccc 100644 --- a/src/network/access/qnetworkaccessauthenticationmanager.cpp +++ b/src/network/access/qnetworkaccessauthenticationmanager.cpp @@ -283,9 +283,12 @@ QNetworkAccessAuthenticationManager::fetchCachedCredentials(const QUrl &url, QNetworkAuthenticationCache *auth = static_cast<QNetworkAuthenticationCache *>(authenticationCache.requestEntryNow(cacheKey)); - QNetworkAuthenticationCredential cred = *auth->findClosestMatch(url.path()); + QNetworkAuthenticationCredential *cred = auth->findClosestMatch(url.path()); + QNetworkAuthenticationCredential ret; + if (cred) + ret = *cred; authenticationCache.releaseEntry(cacheKey); - return cred; + return ret; } void QNetworkAccessAuthenticationManager::clearCache() diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 0423e22..7b63567 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -220,12 +220,6 @@ void QAuthenticator::setUser(const QString &user) d->userDomain = user.left(separatorPosn); d->extractedUser = user.mid(separatorPosn + 1); d->user = user; - } else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) { - //domain name is present - d->realm.clear(); - d->userDomain = user.mid(separatorPosn + 1); - d->extractedUser = user.left(separatorPosn); - d->user = user; } else { d->extractedUser = user; d->user = user; @@ -1381,8 +1375,9 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas int offset = QNtlmPhase3BlockBase::Size; Q_ASSERT(QNtlmPhase3BlockBase::Size == sizeof(QNtlmPhase3BlockBase)); - - if(ctx->userDomain.isEmpty()) { + + // for kerberos style user@domain logins, NTLM domain string should be left empty + if (ctx->userDomain.isEmpty() && !ctx->extractedUser.contains(QLatin1Char('@'))) { offset = qEncodeNtlmString(pb.domain, offset, ch.targetNameStr, unicode); pb.domainStr = ch.targetNameStr; } else { 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 86a8bf7..af060aa 100644 --- a/src/plugins/platforms/directfb/qdirectfbblitter.cpp +++ b/src/plugins/platforms/directfb/qdirectfbblitter.cpp @@ -45,48 +45,79 @@ #include <QtGui/private/qpixmap_blitter_p.h> #include <QDebug> +#include <QFile> #include <directfb.h> +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) { - if (surface) { - m_surface = surface; - } else { - DFBSurfaceDescription surfaceDesc; - memset(&surfaceDesc,0,sizeof(DFBSurfaceDescription)); - surfaceDesc.width = rect.width(); - surfaceDesc.height = rect.height(); + m_surface->AddRef(m_surface.data()); +} + +QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, bool alpha) + : QBlittable(rect, dfb_blitter_capabilities()) +{ + DFBSurfaceDescription surfaceDesc; + memset(&surfaceDesc,0,sizeof(DFBSurfaceDescription)); + surfaceDesc.width = rect.width(); + surfaceDesc.height = rect.height(); + + 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); - - IDirectFB *dfb = QDirectFbConvenience::dfbInterface(); - dfb->CreateSurface(dfb,&surfaceDesc, &m_surface); - m_surface->Clear(m_surface,0,0,0,0); + } else { + surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT); + surfaceDesc.pixelformat = QDirectFbBlitter::pixmapFormat(); } + + IDirectFB *dfb = QDirectFbConvenience::dfbInterface(); + 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()); } @@ -99,7 +130,7 @@ void QDirectFbBlitter::drawPixmap(const QRectF &rect, const QPixmap &pixmap, con QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(blitPm->blittable()); dfbBlitter->unlock(); - IDirectFBSurface *s = dfbBlitter->m_surface; + IDirectFBSurface *s = dfbBlitter->m_surface.data(); DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX; DFBSurfacePorterDuffRule porterDuff = DSPD_SRC; @@ -108,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); @@ -132,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<void**>(&mem), &bpl); + const DFBResult result = m_surface->Lock(m_surface.data(), DFBSurfaceLockFlags(DSLF_WRITE|DSLF_READ), static_cast<void**>(&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<uchar *>(mem),w,h,bpl,format); } else { DirectFBError("Failed to lock image", result); @@ -149,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<IDirectFBDataBuffer> dataBuffer; + result = dfb->CreateDataBuffer(dfb, &dataBufferDescription, dataBuffer.outPtr()); + if (result != DFB_OK) { + DirectFBError(QDFB_PRETTY, result); + return false; + } + + // Create the image provider + QDirectFBPointer<IDirectFBImageProvider> 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<const uchar*>(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 16d7599..fe39aaf 100644 --- a/src/plugins/platforms/directfb/qdirectfbblitter.h +++ b/src/plugins/platforms/directfb/qdirectfbblitter.h @@ -48,29 +48,63 @@ #include <directfb.h> +QT_BEGIN_NAMESPACE + class QDirectFbBlitter : public QBlittable { public: - QDirectFbBlitter(const QSize &size, IDirectFBSurface *surface = 0); + QDirectFbBlitter(const QSize &size, IDirectFBSurface *surface); + QDirectFbBlitter(const QSize &size, bool alpha); virtual ~QDirectFbBlitter(); 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<IDirectFBSurface> m_surface; QImage m_image; friend class QDirectFbConvenience; }; -class QDirectFbBlitterPixmapData : public QBlittablePixmapData +class QDirectFbBlitterPlatformPixmap : public QBlittablePixmapData { public: - QBlittable *createBlittable(const QSize &size) const { return new QDirectFbBlitter(size); } + 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 *QDirectFbBlitterPlatformPixmap::createBlittable(const QSize& size, bool alpha) const +{ + return new QDirectFbBlitter(size, alpha); +} + +inline QDirectFbBlitter *QDirectFbBlitterPlatformPixmap::dfbBlitter() const +{ + return static_cast<QDirectFbBlitter*>(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 <private/qpixmap_blitter_p.h> +#include <QtGui/QWidget> +#include <QtGui/QScreen> + +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<QBlittablePixmapData *>(pixmapData); + QBlittablePixmapData *blittablePmData = static_cast<QBlittablePixmapData *>(handle); if (blittablePmData) { QBlittable *blittable = blittablePmData->blittable(); QDirectFbBlitter *dfbBlitter = static_cast<QDirectFbBlitter *>(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<QDirectFbScreen*>(QPlatformScreen::platformScreenForWidget(window)); +} + +IDirectFBDisplayLayer *toDfbLayer(QPlatformScreen *screen) +{ + return static_cast<QDirectFbScreen*>(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 <directfb.h> +QT_BEGIN_NAMESPACE + +class QDirectFbScreen; +class QPlatformScreen; + class QDirectFbKeyMap: public QHash<DFBInputDeviceKeySymbol, Qt::Key> { 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 <typename T> struct QDirectFBInterfaceCleanupHandler +{ + static void cleanup(T *t) + { + if (!t) + return; + t->Release(t); + } +}; + +template <typename T> +class QDirectFBPointer : public QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> > +{ +public: + QDirectFBPointer(T *t = 0) + : QScopedPointer<T, QDirectFBInterfaceCleanupHandler<T> >(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 <QPlatformCursor> #include <directfb.h> + +#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<QPlatformCursorImage> 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 <QDebug> +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 <QWindowSystemInterface> #include <QMouseEvent> #include <QEvent> -#include <QApplication> #include <directfb.h> -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<IDirectFBDisplayLayer> layer(QDirectFbConvenience::dfbDisplayLayer()); + QDirectFBPointer<IDirectFBWindow> 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<IDirectFBWindow> 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 <QSemaphore> -#include <QObject> +#include <QThread> #include <QHash> #include <QPoint> #include <QEvent> #include <QtGui/qwindowdefs.h> -#include <directfb.h> +#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<IDirectFBEventBuffer> m_eventBuffer; bool m_shouldStop; - QSemaphore m_waitStop; - QHash<DFBWindowID,QWidget *>m_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 <private/qwindowsurface_raster_p.h> -#include <private/qpixmap_raster_p.h> - #include <QtGui/private/qpixmap_blitter_p.h> -#include <QtGui/private/qpixmapdata_p.h> +#include <QtGui/private/qpixmap_raster_p.h> #include <QtCore/QCoreApplication> #include <QtCore/QThread> -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<QDirectFbInput *>(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 <QtGui/QPlatformIntegration> #include <directfb.h> @@ -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<QPlatformScreen *> mScreens; - QDirectFbInput *mInput; - QThread *mInputRunner; - QPlatformFontDatabase *mFontDb; + QDirectFBPointer<IDirectFB> m_dfb; + QScopedPointer<QDirectFbScreen> m_primaryScreen; + QScopedPointer<QDirectFbInput> m_input; + QScopedPointer<QThread> m_inputRunner; + QScopedPointer<QPlatformFontDatabase> 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 <QtGui/QPlatformIntegration> + +#include <directfb.h> + +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<IDirectFBDisplayLayer> m_layer; + +private: + QScopedPointer<QDirectFBCursor> 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 <QWidget> +#include "qdirectfbscreen.h" -#include "qdirectfbwindowsurface.h" #include <directfb.h> +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<IDirectFBDisplayLayer> 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<QDirectFbWindow *>(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<IDirectFBSurface> m_dfbSurface; + QDirectFBPointer<IDirectFBWindow> 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 <private/qpixmap_blitter_p.h> #include <QtCore/qdebug.h> 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<QDirectFbWindow *>(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<QRect> rects = area.rects(); const int n = rects.size(); for (int i=0; i<n; ++i) { - scrollSurface(m_dfbSurface, rects.at(i), dx, dy); + scrollSurface(m_dfbSurface.data(), rects.at(i), dx, dy); } } return true; diff --git a/src/plugins/platforms/directfb/qdirectfbwindowsurface.h b/src/plugins/platforms/directfb/qdirectfbwindowsurface.h index 7f1140d..dd0354d 100644 --- a/src/plugins/platforms/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/platforms/directfb/qdirectfbwindowsurface.h @@ -44,16 +44,16 @@ #include <QtGui/private/qwindowsurface_p.h> #include <private/qpixmap_blitter_p.h> - #include <directfb.h> +#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<QPixmap> m_pixmap; QBlittablePixmapData *m_pmdata; - - IDirectFBSurface *m_dfbSurface; + QDirectFBPointer<IDirectFBSurface> m_dfbSurface; }; QT_END_NAMESPACE |