From 95baddfc2f5dc719188f52519c95206959983206 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 09:47:19 -0700 Subject: Rewrite QDFBScreen::exposeRegion This code should be a noop in the case where one has a proper dfb cursor and proper dfb window handling. This was the only case it actually worked. This patch makes it work for a screen cursor rendered by Qt and sets exposeRegion up to work for using an offscreen backing store. Since one can't query the background color set by directfb this patch also adds a connect option to set the background color. This is needed for erasing the background when the mouse cursor moves. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 286 +++++++++------------ src/plugins/gfxdrivers/directfb/qdirectfbscreen.h | 14 +- 2 files changed, 124 insertions(+), 176 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 0928643..88e304c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -70,7 +70,6 @@ public: IDirectFBDisplayLayer *dfbLayer; #endif IDirectFBScreen *dfbScreen; - QRegion prevExpose; QSet allocatedSurfaces; @@ -82,6 +81,7 @@ public: #endif QDirectFBScreen::DirectFBFlags directFBFlags; QImage::Format alphaPixmapFormat; + QColor backgroundColor; }; QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *screen) @@ -1047,6 +1047,14 @@ bool QDirectFBScreen::connect(const QString &displaySpec) printDirectFBInfo(d_ptr->dfb, d_ptr->dfbSurface); #endif + QRegExp backgroundColorRegExp("bgcolor=?(.+)"); + backgroundColorRegExp.setCaseSensitivity(Qt::CaseInsensitive); + if (displayArgs.indexOf(backgroundColorRegExp) != -1) { + d_ptr->backgroundColor.setNamedColor(backgroundColorRegExp.cap(1)); + } + if (!d_ptr->backgroundColor.isValid()) + d_ptr->backgroundColor = Qt::green; + return true; } @@ -1087,7 +1095,7 @@ bool QDirectFBScreen::initDevice() #endif #ifndef QT_NO_QWS_CURSOR -#ifdef QT_NO_DIRECTFB_LAYER +#ifdef QT_NO_DIRECTFB_WM QScreenCursor::initSoftwareCursor(); #else qt_screencursor = new QDirectFBScreenCursor; @@ -1145,203 +1153,119 @@ QWSWindowSurface *QDirectFBScreen::createSurface(const QString &key) const return QScreen::createSurface(key); } -void QDirectFBScreen::compose(const QRegion ®ion) -{ - const QList windows = QWSServer::instance()->clientWindows(); - - QRegion blitRegion = region; - QRegion blendRegion; - - d_ptr->dfbSurface->SetBlittingFlags(d_ptr->dfbSurface, DSBLIT_NOFX); - - // blit opaque region - for (int i = 0; i < windows.size(); ++i) { - QWSWindow *win = windows.at(i); - QWSWindowSurface *surface = win->windowSurface(); - if (!surface) - continue; - - const QRegion r = win->allocatedRegion() & blitRegion; - if (r.isEmpty()) - continue; - - blitRegion -= r; - - if (surface->isRegionReserved()) { - // nothing - } else if (win->isOpaque()) { - const QPoint offset = win->requestedRegion().boundingRect().topLeft(); - - if (surface->key() == QLatin1String("directfb")) { - QDirectFBWindowSurface *s = static_cast(surface); - blit(s->directFBSurface(), offset, r); - } else { - blit(surface->image(), offset, r); - } - } else { - blendRegion += r; - } - if (blitRegion.isEmpty()) - break; - } - - { // fill background - const QRegion fill = blitRegion + blendRegion; - if (!fill.isEmpty()) { - const QColor color = QWSServer::instance()->backgroundBrush().color(); - solidFill(color, fill); - blitRegion = QRegion(); - } - } - - if (blendRegion.isEmpty()) - return; - - // blend non-opaque region - for (int i = windows.size() - 1; i >= 0; --i) { - QWSWindow *win = windows.at(i); - QWSWindowSurface *surface = win->windowSurface(); - if (!surface) - continue; - - const QRegion r = win->allocatedRegion() & blendRegion; - if (r.isEmpty()) - continue; - - DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; - if (!win->isOpaque()) { - flags |= DSBLIT_BLEND_ALPHACHANNEL; - const uint opacity = win->opacity(); - if (opacity < 255) { - flags |= DSBLIT_BLEND_COLORALPHA; - d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface, 0xff, 0xff, 0xff, opacity); - } - } - d_ptr->dfbSurface->SetBlittingFlags(d_ptr->dfbSurface, flags); - - const QPoint offset = win->requestedRegion().boundingRect().topLeft(); - - if (surface->key() == QLatin1String("directfb")) { - QDirectFBWindowSurface *s = static_cast(surface); - blit(s->directFBSurface(), offset, r); - } else { - blit(surface->image(), offset, r); - } - } -#if (Q_DIRECTFB_VERSION >= 0x010000) - d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface); -#endif -} - // Normally, when using DirectFB to compose the windows (I.e. when // QT_NO_DIRECTFB_WM isn't set), exposeRegion will simply return. If // QT_NO_DIRECTFB_WM is set, exposeRegion will compose only non-directFB // window surfaces. Normal, directFB surfaces are handled by DirectFB. +static inline bool needExposeRegion() +{ +#ifdef QT_NO_DIRECTFB_WM + return true; +#endif +#ifdef QT_NO_DIRECTFB_LAYER +#ifndef QT_NO_QWS_CURSOR + return true; +#endif +#endif + return false; +} + void QDirectFBScreen::exposeRegion(QRegion r, int changing) { + if (!needExposeRegion()) { + return; + } + const QList windows = QWSServer::instance()->clientWindows(); if (changing < 0 || changing >= windows.size()) return; -#ifndef QT_NO_DIRECTFB_WM + QWSWindow *win = windows.at(changing); QWSWindowSurface *s = win->windowSurface(); - if (s && s->key() == QLatin1String("directfb")) - return; -#endif - r &= region(); if (r.isEmpty()) return; - if (d_ptr->flipFlags & DSFLIP_BLIT) { - const QRect brect = r.boundingRect(); - DFBRegion dfbRegion = { brect.left(), brect.top(), - brect.right(), brect.bottom() }; - compose(r); - d_ptr->dfbSurface->Flip(d_ptr->dfbSurface, &dfbRegion, - d_ptr->flipFlags); + const QRect brect = r.boundingRect(); + + if (!s) { + solidFill(d_ptr->backgroundColor, r); } else { - compose(r + d_ptr->prevExpose); - d_ptr->dfbSurface->Flip(d_ptr->dfbSurface, 0, d_ptr->flipFlags); + const QRect windowGeometry = s->geometry(); + const QRegion outsideWindow = r.subtracted(windowGeometry); + if (!outsideWindow.isEmpty()) { + solidFill(d_ptr->backgroundColor, outsideWindow); + } + const QRegion insideWindow = r.intersected(windowGeometry); + if (!insideWindow.isEmpty()) { + QDirectFBWindowSurface *dfbWindowSurface = (s->key() == QLatin1String("directfb")) + ? static_cast(s) : 0; + if (dfbWindowSurface) { + IDirectFBSurface *surface = dfbWindowSurface->directFBSurface(); + if (d_ptr->directFBFlags & BoundingRectFlip || insideWindow.numRects() == 1) { + const QRect source = (insideWindow.boundingRect().intersected(windowGeometry)).translated(-windowGeometry.topLeft()); + const DFBRectangle rect = { + source.x(), source.y(), source.width(), source.height() + }; + d_ptr->dfbSurface->Blit(d_ptr->dfbSurface, surface, &rect, + windowGeometry.x() + source.x(), + windowGeometry.y() + source.y()); + } else { + const QVector rects = insideWindow.rects(); + const int count = rects.size(); + Q_ASSERT(count > 1); + for (int i=0; idfbSurface->Blit(d_ptr->dfbSurface, surface, &rect, + windowGeometry.x() + source.x(), + windowGeometry.y() + source.y()); + } + } + } + } } - d_ptr->prevExpose = r; -} - -void QDirectFBScreen::blit(const QImage &img, const QPoint &topLeft, - const QRegion ®) -{ - IDirectFBSurface *src = createDFBSurface(img, QDirectFBScreen::DontTrackSurface); - if (!src) { - qWarning("QDirectFBScreen::blit(): Error creating surface"); - return; - } - blit(src, topLeft, reg); + if (QScreenCursor *cursor = QScreenCursor::instance()) { + const QRect cursorRectangle = cursor->boundingRect(); + if (cursor->isVisible() && !cursor->isAccelerated() && cursorRectangle.intersects(brect)) { + const QImage image = cursor->image(); + IDirectFBSurface *surface = createDFBSurface(image, QDirectFBScreen::DontTrackSurface); + d_ptr->dfbSurface->SetBlittingFlags(d_ptr->dfbSurface, DSBLIT_BLEND_ALPHACHANNEL); + d_ptr->dfbSurface->Blit(d_ptr->dfbSurface, surface, 0, cursorRectangle.x(), cursorRectangle.y()); + surface->Release(surface); #if (Q_DIRECTFB_VERSION >= 0x010000) - d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface); + d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface); #endif - src->Release(src); -} - -void QDirectFBScreen::blit(IDirectFBSurface *src, const QPoint &topLeft, - const QRegion ®ion) -{ - const QVector rs = region.translated(-offset()).rects(); - const int size = rs.size(); - const QPoint tl = topLeft - offset(); - - QVarLengthArray rects(size); - QVarLengthArray points(size); - - int n = 0; - for (int i = 0; i < size; ++i) { - const QRect r = rs.at(i); - if (!r.isValid()) - continue; - rects[n].x = r.x() - tl.x(); - rects[n].y = r.y() - tl.y(); - rects[n].w = r.width(); - rects[n].h = r.height(); - points[n].x = r.x(); - points[n].y = r.y(); - ++n; + } } - - d_ptr->dfbSurface->BatchBlit(d_ptr->dfbSurface, src, rects.data(), - points.data(), n); + flipSurface(d_ptr->dfbSurface, d_ptr->flipFlags, r, QPoint()); } -// This function is only ever called by QScreen::drawBackground which -// is only ever called by QScreen::compose which is never called with -// DirectFB so it's really a noop. void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) { if (region.isEmpty()) return; - if (QDirectFBScreen::getImageFormat(d_ptr->dfbSurface) == QImage::Format_RGB32) { - data = QDirectFBScreen::lockSurface(d_ptr->dfbSurface, DSLF_WRITE, &lstep); - if (!data) - return; - - QScreen::solidFill(color, region); - d_ptr->dfbSurface->Unlock(d_ptr->dfbSurface); - data = 0; - lstep = 0; - } else { - d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface, - color.red(), color.green(), color.blue(), - color.alpha()); - const QVector rects = region.rects(); - for (int i=0; idfbSurface->FillRectangle(d_ptr->dfbSurface, - r.x(), r.y(), r.width(), r.height()); - } + d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface, + color.red(), color.green(), color.blue(), + color.alpha()); + const QVector rects = region.rects(); + for (int i=0; idfbSurface->FillRectangle(d_ptr->dfbSurface, + r.x(), r.y(), r.width(), r.height()); } } +void QDirectFBScreen::erase(const QRegion ®ion) +{ + solidFill(d_ptr->backgroundColor, region); +} + QImage::Format QDirectFBScreen::alphaPixmapFormat() const { return d_ptr->alphaPixmapFormat; @@ -1377,3 +1301,31 @@ uchar *QDirectFBScreen::lockSurface(IDirectFBSurface *surface, uint flags, int * return reinterpret_cast(mem); } + +void QDirectFBScreen::flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags, + const QRegion ®ion, const QPoint &offset) +{ + if (!(flipFlags & DSFLIP_BLIT)) { + surface->Flip(surface, 0, flipFlags); + } else { + if (!(d_ptr->directFBFlags & BoundingRectFlip) && region.numRects() > 1) { + const QVector rects = region.rects(); + const DFBSurfaceFlipFlags nonWaitFlags = flipFlags & ~DSFLIP_WAIT; + for (int i=0; iFlip(surface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags); + } + } else { + const QRect r = region.boundingRect(); + const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), + r.x() + r.width() + offset.x(), + r.y() + r.height() + offset.y() }; + surface->Flip(surface, &dfbReg, flipFlags); + } + } +} + + diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 090a685..c128932 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -52,7 +52,6 @@ QT_MODULE(Gui) #define Q_DIRECTFB_VERSION ((DIRECTFB_MAJOR_VERSION << 16) | (DIRECTFB_MINOR_VERION << 8) | DIRECTFB_MICRO_VERSION) -#include #define DIRECTFB_DECLARE_OPERATORS_FOR_FLAGS(F) \ static inline F operator~(F f) { return F(~int(f)); } \ static inline F operator&(F left, F right) { return F(int(left) & int(right)); } \ @@ -94,7 +93,6 @@ public: void shutdownDevice(); void exposeRegion(QRegion r, int changing); - void blit(const QImage &img, const QPoint &topLeft, const QRegion ®ion); void scroll(const QRegion ®ion, const QPoint &offset); void solidFill(const QColor &color, const QRegion ®ion); @@ -131,9 +129,12 @@ public: QImage::Format format, SurfaceCreationOptions options); IDirectFBSurface *copyToDFBSurface(const QImage &image, - QImage::Format format, - SurfaceCreationOptions options); + QImage::Format format, + SurfaceCreationOptions options); + void flipSurface(IDirectFBSurface *surface, DFBSurfaceFlipFlags flipFlags, + const QRegion ®ion, const QPoint &offset); void releaseDFBSurface(IDirectFBSurface *surface); + void erase(const QRegion ®ion); static int depth(DFBSurfacePixelFormat format); @@ -154,14 +155,9 @@ public: #endif static uchar *lockSurface(IDirectFBSurface *surface, uint flags, int *bpl = 0); - private: IDirectFBSurface *createDFBSurface(DFBSurfaceDescription desc, SurfaceCreationOptions options); - void compose(const QRegion &r); - void blit(IDirectFBSurface *src, const QPoint &topLeft, - const QRegion ®ion); - QDirectFBScreenPrivate *d_ptr; friend class SurfaceCache; }; -- cgit v0.12 From eb6fa7e03a5c91e3da93d0c6203d9bad52dfcbb9 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 09:50:49 -0700 Subject: Fix dfbwindowsurface handling for offscreen mode This patch vastly simplifies the geometry handling (setGeometry/move) It also implements a mode in which DirectFB implementations that do not support windows can use an offscreen buffer as its backing store. Previously the only way to do this was to paint directly on the primary surface. This didn't work when the dfb driver didn't support an accelerated mouse cursor. It also detects the situation when the cursor isn't accelerated and takes care of painting it manually when needed. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 268 +++++++++++---------- .../gfxdrivers/directfb/qdirectfbwindowsurface.h | 10 +- 2 files changed, 151 insertions(+), 127 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index 7dcf398..ed4b2d9 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -44,10 +44,10 @@ #include "qdirectfbpaintengine.h" #include +#include #include #include - //#define QT_DIRECTFB_DEBUG_SURFACES 1 QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr) @@ -59,6 +59,11 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect , flipFlags(flip) , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) { +#ifdef QT_NO_DIRECTFB_WM + mode = Offscreen; +#else + mode = Window; +#endif setSurfaceFlags(Opaque | Buffered); #ifdef QT_DIRECTFB_TIMING frames = 0; @@ -75,11 +80,17 @@ QDirectFBWindowSurface::QDirectFBWindowSurface(DFBSurfaceFlipFlags flip, QDirect , flipFlags(flip) , boundingRectFlip(scr->directFBFlags() & QDirectFBScreen::BoundingRectFlip) { - onscreen = widget->testAttribute(Qt::WA_PaintOnScreen); - if (onscreen) + if (widget && widget->testAttribute(Qt::WA_PaintOnScreen)) { setSurfaceFlags(Opaque | RegionReserved); - else + mode = Primary; + } else { +#ifdef QT_NO_DIRECTFB_WM + mode = Offscreen; +#else + mode = Window; +#endif setSurfaceFlags(Opaque | Buffered); + } #ifdef QT_DIRECTFB_TIMING frames = 0; timer.start(); @@ -99,7 +110,7 @@ bool QDirectFBWindowSurface::isValid() const void QDirectFBWindowSurface::createWindow() { #ifdef QT_NO_DIRECTFB_LAYER -#warning QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM +#error QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM #else IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); if (!layer) @@ -129,8 +140,40 @@ void QDirectFBWindowSurface::createWindow() } #endif // QT_NO_DIRECTFB_WM -void QDirectFBWindowSurface::setGeometry(const QRect &rect, const QRegion &mask) +#ifndef QT_NO_DIRECTFB_WM +static DFBResult setGeometry(IDirectFBWindow *dfbWindow, const QRect &old, const QRect &rect) +{ + DFBResult result = DFB_OK; + const bool isMove = old.isEmpty() || rect.topLeft() != old.topLeft(); + const bool isResize = rect.size() != old.size(); + +#if (Q_DIRECTFB_VERSION >= 0x010000) + if (isResize && isMove) { + result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(), + rect.width(), rect.height()); + } else if (isResize) { + result = dfbWindow->Resize(dfbWindow, + rect.width(), rect.height()); + } else if (isMove) { + result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y()); + } +#else + if (isResize) { + result = dfbWindow->Resize(dfbWindow, + rect.width(), rect.height()); + } + if (isMove) { + result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y()); + } +#endif + return result; +} +#endif + +void QDirectFBWindowSurface::setGeometry(const QRect &rect) { + IDirectFBSurface *primarySurface = screen->dfbSurface(); + Q_ASSERT(primarySurface); if (rect.isNull()) { #ifndef QT_NO_DIRECTFB_WM if (dfbWindow) { @@ -138,22 +181,21 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect, const QRegion &mask) dfbWindow = 0; } #endif - if (dfbSurface && dfbSurface != screen->dfbSurface()) { - dfbSurface->Release(dfbSurface); + if (dfbSurface) { + if (dfbSurface != primarySurface) { + dfbSurface->Release(dfbSurface); + } dfbSurface = 0; } } else if (rect != geometry()) { + const QRect oldRect = geometry(); DFBResult result = DFB_OK; - // If we're in a resize, the surface shouldn't be locked Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size())); - - if (onscreen) { - IDirectFBSurface *primarySurface = screen->dfbSurface(); - Q_ASSERT(primarySurface); + switch (mode) { + case Primary: if (dfbSurface && dfbSurface != primarySurface) dfbSurface->Release(dfbSurface); - if (rect == screen->region().boundingRect()) { dfbSurface = primarySurface; } else { @@ -161,58 +203,32 @@ void QDirectFBWindowSurface::setGeometry(const QRect &rect, const QRegion &mask) rect.width(), rect.height() }; result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); } - } else { - const bool isResize = rect.size() != geometry().size(); -#ifdef QT_NO_DIRECTFB_WM - if (isResize) { + break; + case Window: +#ifndef QT_NO_DIRECTFB_WM + if (!dfbWindow) + createWindow(); + ::setGeometry(dfbWindow, oldRect, rect); + // ### do I need to release and get the surface again here? +#endif + break; + case Offscreen: { + if (!dfbSurface || oldRect.size() != rect.size()) { if (dfbSurface) dfbSurface->Release(dfbSurface); - - IDirectFB *dfb = screen->dfb(); - if (!dfb) { - qFatal("QDirectFBWindowSurface::setGeometry(): " - "Unable to get DirectFB handle!"); - } - dfbSurface = screen->createDFBSurface(rect.size(), screen->pixelFormat(), QDirectFBScreen::DontTrackSurface); - } else { - Q_ASSERT(dfbSurface); - } -#else - const QRect oldRect = geometry(); - const bool isMove = oldRect.isEmpty() || - rect.topLeft() != oldRect.topLeft(); - - if (!dfbWindow) - createWindow(); - -#if (Q_DIRECTFB_VERSION >= 0x010000) - if (isResize && isMove) { - result = dfbWindow->SetBounds(dfbWindow, rect.x(), rect.y(), - rect.width(), rect.height()); - } else if (isResize) { - result = dfbWindow->Resize(dfbWindow, - rect.width(), rect.height()); - } else if (isMove) { - result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y()); - } -#else - if (isResize) { - result = dfbWindow->Resize(dfbWindow, - rect.width(), rect.height()); } - if (isMove) { - result = dfbWindow->MoveTo(dfbWindow, rect.x(), rect.y()); - } -#endif -#endif + const QRegion region = QRegion(oldRect.isEmpty() ? screen->region() : QRegion(oldRect)).subtracted(rect); + screen->erase(region); + screen->flipSurface(primarySurface, flipFlags, region, QPoint()); + break; } } if (result != DFB_OK) DirectFBErrorFatal("QDirectFBWindowSurface::setGeometry()", result); } - QWSWindowSurface::setGeometry(rect, mask); + QWSWindowSurface::setGeometry(rect); } QByteArray QDirectFBWindowSurface::permanentState() const @@ -254,7 +270,6 @@ static inline void scrollSurface(IDirectFBSurface *surface, const QRect &r, int surface->Blit(surface, surface, &rect, r.x() + dx, r.y() + dy); } - bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) { if (!dfbSurface || !(flipFlags & DSFLIP_BLIT) || region.isEmpty()) @@ -272,35 +287,13 @@ bool QDirectFBWindowSurface::scroll(const QRegion ®ion, int dx, int dy) return true; } -bool QDirectFBWindowSurface::move(const QPoint &offset) -{ - QWSWindowSurface::move(offset); - -#ifdef QT_NO_DIRECTFB_WM - return true; // buffered -#else - if (!dfbWindow) - return false; - - DFBResult status = dfbWindow->Move(dfbWindow, offset.x(), offset.y()); - return (status == DFB_OK); -#endif -} - -QRegion QDirectFBWindowSurface::move(const QPoint &offset, const QRegion &newClip) +bool QDirectFBWindowSurface::move(const QPoint &moveBy) { -#ifdef QT_NO_DIRECTFB_WM - return QWSWindowSurface::move(offset, newClip); -#else - Q_UNUSED(offset); - Q_UNUSED(newClip); - - // DirectFB handles the entire move, so there's no need to blit. - return QRegion(); -#endif + setGeometry(geometry().translated(moveBy)); + return true; } -QPaintEngine* QDirectFBWindowSurface::paintEngine() const +QPaintEngine *QDirectFBWindowSurface::paintEngine() const { if (!engine) { QDirectFBWindowSurface *that = const_cast(this); @@ -333,57 +326,86 @@ inline bool isWidgetOpaque(const QWidget *w) return false; } -void QDirectFBWindowSurface::flush(QWidget *widget, const QRegion ®ion, + +void QDirectFBWindowSurface::flush(QWidget *, const QRegion ®ion, const QPoint &offset) { - Q_UNUSED(widget); -#ifdef QT_NO_DIRECTFB_WM - Q_UNUSED(region); - Q_UNUSED(offset); -#endif - - QWidget *win = window(); - // hw: make sure opacity information is updated before compositing - const bool opaque = isWidgetOpaque(win); - if (opaque != isOpaque()) { - SurfaceFlags flags = Buffered; - if (opaque) - flags |= Opaque; - setSurfaceFlags(flags); - } + if (QWidget *win = window()) { + + const bool opaque = isWidgetOpaque(win); + if (opaque != isOpaque()) { + SurfaceFlags flags = surfaceFlags(); + if (opaque) { + flags |= Opaque; + } else { + flags &= ~Opaque; + } + setSurfaceFlags(flags); + } #ifndef QT_NO_DIRECTFB_WM - const quint8 winOpacity = quint8(win->windowOpacity() * 255); - quint8 opacity; + const quint8 winOpacity = quint8(win->windowOpacity() * 255); + quint8 opacity; - if (dfbWindow) { - dfbWindow->GetOpacity(dfbWindow, &opacity); - if (winOpacity != opacity) - dfbWindow->SetOpacity(dfbWindow, winOpacity); - } + if (dfbWindow) { + dfbWindow->GetOpacity(dfbWindow, &opacity); + if (winOpacity != opacity) + dfbWindow->SetOpacity(dfbWindow, winOpacity); + } #endif - if (!(flipFlags & DSFLIP_BLIT)) { - dfbSurface->Flip(dfbSurface, 0, flipFlags); - } else { - if (!boundingRectFlip && region.numRects() > 1) { + } + + if (mode == Offscreen) { + IDirectFBSurface *primarySurface = screen->dfbSurface(); + primarySurface->SetBlittingFlags(primarySurface, DSBLIT_NOFX); + const QRect windowGeometry = QDirectFBWindowSurface::geometry(); + const QRect windowRect(0, 0, windowGeometry.width(), windowGeometry.height()); + if (boundingRectFlip || region.numRects() == 1) { + const QRect regionBoundingRect = region.boundingRect().translated(offset); + const QRect source = windowRect & regionBoundingRect; + const DFBRectangle rect = { + source.x(), source.y(), source.width(), source.height() + }; + primarySurface->Blit(primarySurface, dfbSurface, &rect, + windowGeometry.x() + source.x(), + windowGeometry.y() + source.y()); + } else { const QVector rects = region.rects(); - const DFBSurfaceFlipFlags nonWaitFlags = flipFlags & ~DSFLIP_WAIT; - for (int i=0; iFlip(dfbSurface, &dfbReg, i + 1 < rects.size() ? nonWaitFlags : flipFlags); + const int count = rects.size(); + for (int i=0; iBlit(primarySurface, dfbSurface, &rect, + windowGeometry.x() + source.x(), + windowGeometry.y() + source.y()); } - } else { - const QRect r = region.boundingRect(); - const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), - r.x() + r.width() + offset.x(), - r.y() + r.height() + offset.y() }; - dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); } + if (QScreenCursor *cursor = QScreenCursor::instance()) { + const QRect cursorRectangle = cursor->boundingRect(); + if (cursor->isVisible() && !cursor->isAccelerated() + && region.intersects(cursorRectangle.translated(-(offset + windowGeometry.topLeft())))) { + const QImage image = cursor->image(); + + IDirectFBSurface *surface = screen->createDFBSurface(image, QDirectFBScreen::DontTrackSurface); + primarySurface->SetBlittingFlags(primarySurface, DSBLIT_BLEND_ALPHACHANNEL); + primarySurface->Blit(primarySurface, surface, 0, cursorRectangle.x(), cursorRectangle.y()); + surface->Release(surface); +#if (Q_DIRECTFB_VERSION >= 0x010000) + primarySurface->ReleaseSource(primarySurface); +#endif + } + } + + screen->flipSurface(primarySurface, flipFlags, region, offset + windowGeometry.topLeft()); + } else { + screen->flipSurface(dfbSurface, flipFlags, region, offset); } + + #ifdef QT_DIRECTFB_TIMING enum { Secs = 3 }; ++frames; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h index 7885b73..c46d93b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.h @@ -67,7 +67,7 @@ public: bool isValid() const; - void setGeometry(const QRect &rect, const QRegion &mask); + void setGeometry(const QRect &rect); QString key() const { return QLatin1String("directfb"); } QByteArray permanentState() const; @@ -76,7 +76,6 @@ public: bool scroll(const QRegion &area, int dx, int dy); bool move(const QPoint &offset); - QRegion move(const QPoint &offset, const QRegion &newClip); QImage image() const { return QImage(); } QPaintDevice *paintDevice() { return this; } @@ -88,7 +87,6 @@ public: void endPaint(const QRegion &); QImage *buffer(const QWidget *widget); - private: #ifndef QT_NO_DIRECTFB_WM void createWindow(); @@ -96,7 +94,11 @@ private: #endif QDirectFBPaintEngine *engine; - bool onscreen; + enum Mode { + Primary, + Offscreen, + Window + } mode; QList bufferImages; DFBSurfaceFlipFlags flipFlags; -- cgit v0.12 From d79f61b51868712590f423483f4d3b39cb60aa64 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 11:20:32 -0700 Subject: Fix IDirectFBSurface::ReleaseSource calls Make sure that these calls are in the right order. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 94f1aeb..68f37ff 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -466,7 +466,7 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, d->blit(r, imgSurface, sr); if (release) { #if (Q_DIRECTFB_VERSION >= 0x010000) - imgSurface->ReleaseSource(imgSurface); + d->surface->ReleaseSource(d->surface); #endif imgSurface->Release(imgSurface); } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 88e304c..e12cbc4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -141,6 +141,7 @@ IDirectFBSurface *QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCr { if (img.isNull()) // assert? return 0; + if (QDirectFBScreen::getSurfacePixelFormat(img.format()) == DSPF_UNKNOWN) { QImage image = img.convertToFormat(img.hasAlphaChannel() ? d_ptr->alphaPixmapFormat @@ -321,10 +322,10 @@ IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, DFBResult result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0); if (result != DFB_OK) DirectFBError("QDirectFBScreen::copyToDFBSurface()", result); + imgSurface->Release(imgSurface); #if (Q_DIRECTFB_VERSION >= 0x010000) dfbSurface->ReleaseSource(dfbSurface); #endif - imgSurface->Release(imgSurface); #else // QT_NO_DIRECTFB_PREALLOCATED Q_ASSERT(image.format() == pixmapFormat); int bpl; -- cgit v0.12 From 18728d2ddd725199017a36cb290c30d6e8c9e647 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 11:25:47 -0700 Subject: Use dfbsurface::FillRectangles in solidFill Minor optimization Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index e12cbc4..ae2e38b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1254,11 +1254,21 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface, color.red(), color.green(), color.blue(), color.alpha()); - const QVector rects = region.rects(); - for (int i=0; idfbSurface->FillRectangle(d_ptr->dfbSurface, - r.x(), r.y(), r.width(), r.height()); + const int n = region.numRects(); + if (n > 1) { + const QRect r = region.boundingRect(); + d_ptr->dfbSurface->FillRectangle(d_ptr->dfbSurface, r.x(), r.y(), r.width(), r.height()); + } else { + const QVector rects = region.rects(); + QVarLengthArray rectArray(n); + for (int i=0; idfbSurface->FillRectangles(d_ptr->dfbSurface, rectArray.constData(), n); } } -- cgit v0.12 From e38aed0bf5ea35db7dc82a943dfffcd31cca4700 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 11:54:01 -0700 Subject: Use BatchBlit in flush/exposeRegion Minor optimization. Also make sure cursor is drawn in flush even if we're not in Offscreen mode. Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 25 ++++++---- .../gfxdrivers/directfb/qdirectfbwindowsurface.cpp | 57 ++++++++++++---------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index ae2e38b..1efebd9 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1204,7 +1204,8 @@ void QDirectFBScreen::exposeRegion(QRegion r, int changing) ? static_cast(s) : 0; if (dfbWindowSurface) { IDirectFBSurface *surface = dfbWindowSurface->directFBSurface(); - if (d_ptr->directFBFlags & BoundingRectFlip || insideWindow.numRects() == 1) { + const int n = insideWindow.numRects(); + if (n == 1 || d_ptr->directFBFlags & BoundingRectFlip) { const QRect source = (insideWindow.boundingRect().intersected(windowGeometry)).translated(-windowGeometry.topLeft()); const DFBRectangle rect = { source.x(), source.y(), source.width(), source.height() @@ -1214,17 +1215,21 @@ void QDirectFBScreen::exposeRegion(QRegion r, int changing) windowGeometry.y() + source.y()); } else { const QVector rects = insideWindow.rects(); - const int count = rects.size(); - Q_ASSERT(count > 1); - for (int i=0; i dfbRectangles(n); + QVarLengthArray dfbPoints(n); + + for (int i=0; idfbSurface->Blit(d_ptr->dfbSurface, surface, &rect, - windowGeometry.x() + source.x(), - windowGeometry.y() + source.y()); + DFBRectangle &rect = dfbRectangles[i]; + rect.x = source.x(); + rect.y = source.y(); + rect.w = source.width(); + rect.h = source.height(); + dfbPoints[i].x = (windowGeometry.x() + source.x()); + dfbPoints[i].y = (windowGeometry.y() + source.y()); } + d_ptr->dfbSurface->BatchBlit(d_ptr->dfbSurface, surface, dfbRectangles.constData(), + dfbPoints.constData(), n); } } } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp index ed4b2d9..a1009ac 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbwindowsurface.cpp @@ -356,12 +356,13 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion ®ion, #endif } + const QRect windowGeometry = QDirectFBWindowSurface::geometry(); + IDirectFBSurface *primarySurface = screen->dfbSurface(); if (mode == Offscreen) { - IDirectFBSurface *primarySurface = screen->dfbSurface(); primarySurface->SetBlittingFlags(primarySurface, DSBLIT_NOFX); - const QRect windowGeometry = QDirectFBWindowSurface::geometry(); const QRect windowRect(0, 0, windowGeometry.width(), windowGeometry.height()); - if (boundingRectFlip || region.numRects() == 1) { + const int n = region.numRects(); + if (n == 1 || boundingRectFlip ) { const QRect regionBoundingRect = region.boundingRect().translated(offset); const QRect source = windowRect & regionBoundingRect; const DFBRectangle rect = { @@ -372,40 +373,46 @@ void QDirectFBWindowSurface::flush(QWidget *, const QRegion ®ion, windowGeometry.y() + source.y()); } else { const QVector rects = region.rects(); - const int count = rects.size(); - for (int i=0; i dfbRectangles(n); + QVarLengthArray dfbPoints(n); + + for (int i=0; iBlit(primarySurface, dfbSurface, &rect, - windowGeometry.x() + source.x(), - windowGeometry.y() + source.y()); + DFBRectangle &rect = dfbRectangles[i]; + rect.x = source.x(); + rect.y = source.y(); + rect.w = source.width(); + rect.h = source.height(); + dfbPoints[i].x = (windowGeometry.x() + source.x()); + dfbPoints[i].y = (windowGeometry.y() + source.y()); } + primarySurface->BatchBlit(primarySurface, dfbSurface, dfbRectangles.constData(), + dfbPoints.constData(), n); } - if (QScreenCursor *cursor = QScreenCursor::instance()) { - const QRect cursorRectangle = cursor->boundingRect(); - if (cursor->isVisible() && !cursor->isAccelerated() - && region.intersects(cursorRectangle.translated(-(offset + windowGeometry.topLeft())))) { - const QImage image = cursor->image(); - - IDirectFBSurface *surface = screen->createDFBSurface(image, QDirectFBScreen::DontTrackSurface); - primarySurface->SetBlittingFlags(primarySurface, DSBLIT_BLEND_ALPHACHANNEL); - primarySurface->Blit(primarySurface, surface, 0, cursorRectangle.x(), cursorRectangle.y()); - surface->Release(surface); + } + + if (QScreenCursor *cursor = QScreenCursor::instance()) { + const QRect cursorRectangle = cursor->boundingRect(); + if (cursor->isVisible() && !cursor->isAccelerated() + && region.intersects(cursorRectangle.translated(-(offset + windowGeometry.topLeft())))) { + const QImage image = cursor->image(); + + IDirectFBSurface *surface = screen->createDFBSurface(image, QDirectFBScreen::DontTrackSurface); + primarySurface->SetBlittingFlags(primarySurface, DSBLIT_BLEND_ALPHACHANNEL); + primarySurface->Blit(primarySurface, surface, 0, cursorRectangle.x(), cursorRectangle.y()); + surface->Release(surface); #if (Q_DIRECTFB_VERSION >= 0x010000) - primarySurface->ReleaseSource(primarySurface); + primarySurface->ReleaseSource(primarySurface); #endif - } } - + } + if (mode == Offscreen) { screen->flipSurface(primarySurface, flipFlags, region, offset + windowGeometry.topLeft()); } else { screen->flipSurface(dfbSurface, flipFlags, region, offset); } - #ifdef QT_DIRECTFB_TIMING enum { Secs = 3 }; ++frames; -- cgit v0.12 From a974ce81d6324d8d85ade0153b5ce7c757ba4fdf Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 12:15:57 -0700 Subject: Fix a bug in directfb mouse handling Always check the mouse data we read for coordinates rather than asking the layer. This approach works whether we have layers enabled/window management enabled or any combination thereof. Also, make sure we use a software cursor when either of NO_WM or NO_LAYER is defined. Reviewed: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp | 14 -------------- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 2 +- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp index 142993d..4365a5d 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp @@ -203,7 +203,6 @@ void QDirectFBMouseHandlerPrivate::readMouseData() int wheel = 0; if (input.type == DIET_AXISMOTION) { -#ifdef QT_NO_DIRECTFB_LAYER if (input.flags & DIEF_AXISABS) { switch (input.axis) { case DIAI_X: x = input.axisabs; break; @@ -223,19 +222,6 @@ void QDirectFBMouseHandlerPrivate::readMouseData() "unknown axis (releative) %d", input.axis); } } -#else - if (input.axis == DIAI_X || input.axis == DIAI_Y) { - DFBResult result = layer->GetCursorPosition(layer, &x, &y); - if (result != DFB_OK) { - DirectFBError("QDirectFBMouseHandler::readMouseData", - result); - } - } else if (input.axis == DIAI_Z) { - Q_ASSERT(input.flags & DIEF_AXISREL); - wheel = input.axisrel; - wheel *= -120; - } -#endif } Qt::MouseButtons buttons = Qt::NoButton; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 1efebd9..4b76ef6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1096,7 +1096,7 @@ bool QDirectFBScreen::initDevice() #endif #ifndef QT_NO_QWS_CURSOR -#ifdef QT_NO_DIRECTFB_WM +#if defined QT_NO_DIRECTFB_WM || defined QT_NO_DIRECTFB_LAYER QScreenCursor::initSoftwareCursor(); #else qt_screencursor = new QDirectFBScreenCursor; -- cgit v0.12 From 08d549d00816c753096d9cb97a29f4d9dd7c5573 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 17:16:43 -0700 Subject: return when brush is NoBrush in DFBPaintEngine Reviewed-by: Noam Rosenthal --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 68f37ff..b264ac0 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -608,6 +608,8 @@ void QDirectFBPaintEngine::drawTextItem(const QPointF &p, void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { + if (brush.style() == Qt::NoBrush) + return; RASTERFALLBACK(FILL_PATH, path, brush, VOID_ARG()); Q_D(QDirectFBPaintEngine); d->lock(); @@ -618,6 +620,8 @@ void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush) void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) { Q_D(QDirectFBPaintEngine); + if (brush.style() == Qt::NoBrush) + return; d->updateClip(); if (!d->unsupportedCompositionMode && !(d->transformationType & (QDirectFBPaintEnginePrivate::RectsUnsupported)) -- cgit v0.12 From 5027f869f8fc759148871b378e9cae6e88694bcb Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 23 Jul 2009 10:43:31 +1000 Subject: Remove autotest for "Won't fix" bug 258462. --- tests/auto/qprocess/tst_qprocess.cpp | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index 3ce080a..6318d1d 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -141,7 +141,6 @@ private slots: void startFinishStartFinish(); void invalidProgramString_data(); void invalidProgramString(); - void processEventsInAReadyReadSlot(); // keep these at the end, since they use lots of processes and sometimes // caused obscure failures to occur in tests that followed them (esp. on the Mac) @@ -155,7 +154,6 @@ protected slots: void restartProcess(); void waitForReadyReadInAReadyReadSlotSlot(); void waitForBytesWrittenInABytesWrittenSlotSlot(); - void processEventsInAReadyReadSlotSlot(); private: QProcess *process; @@ -2026,34 +2024,5 @@ void tst_QProcess::invalidProgramString() QVERIFY(!QProcess::startDetached(programString)); } -//----------------------------------------------------------------------------- -void tst_QProcess::processEventsInAReadyReadSlot() -{ -#ifdef Q_OS_WINCE - QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll); -#endif - - QProcess process; - QVERIFY(QObject::connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(processEventsInAReadyReadSlotSlot()))); - - for (int i = 0; i < 10; ++i) { - QCOMPARE(process.state(), QProcess::NotRunning); - -#ifdef Q_OS_MAC - process.start("testProcessOutput/testProcessOutput.app"); -#else - process.start("testProcessOutput/testProcessOutput"); -#endif - - QVERIFY(process.waitForFinished(10000)); - } -} - -//----------------------------------------------------------------------------- -void tst_QProcess::processEventsInAReadyReadSlotSlot() -{ - qApp->processEvents(); -} - QTEST_MAIN(tst_QProcess) #include "tst_qprocess.moc" -- cgit v0.12 From 91f85abc13a4dc75bfb810f6c6cc290a3ff75d27 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 23 Jul 2009 09:18:26 +0200 Subject: Recognize .jui file format in lupdate The translator had been installed for the jui format, but the extension wasn't recognized. Task-number: 258547 Reviewed-by: Gunnar --- tools/linguist/lupdate/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index cedc01e..6b454ef 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -485,6 +485,9 @@ int main(int argc, char **argv) fetchedTor.load(*it, cd, QLatin1String("java")); //fetchtr_java(*it, &fetchedTor, defaultContext, true, codecForSource); } + else if (it->endsWith(QLatin1String(".jui"), Qt::CaseInsensitive)) { + fetchedTor.load(*it, cd, QLatin1String("jui")); + } else if (it->endsWith(QLatin1String(".ui"), Qt::CaseInsensitive)) { fetchedTor.load(*it, cd, QLatin1String("ui")); //fetchedTor.load(*it + QLatin1String(".h"), cd, QLatin1String("cpp")); -- cgit v0.12 From ec679d7d49012996bc43a7f4152616af15d97dfd Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 23 Jul 2009 11:27:45 +0200 Subject: Enabled setting of DESIGNABLE=false-properties using FormWindowCursor API Regression breakage introduced by the PropertySheet::isEnabled handling in 4.5. Task-number: 253278 Reviewed-by: Jarek Kobus --- .../src/lib/shared/qdesigner_propertysheet.cpp | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp b/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp index f43b527..5b22a86 100644 --- a/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp +++ b/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp @@ -1381,6 +1381,24 @@ bool QDesignerPropertySheet::isFakeLayoutProperty(int index) const return false; } +// Determine the "designable" state of a property. Properties, which have +// a per-object boolean test function that returns false are shown in +// disabled state ("checked" depending on "checkable", etc.) +// Properties, which are generally not designable independent +// of the object are not shown at all. +enum DesignableState { PropertyIsDesignable, + // Object has a Designable test function that returns false. + PropertyOfObjectNotDesignable, + PropertyNotDesignable }; + +static inline DesignableState designableState(const QDesignerMetaPropertyInterface *p, const QObject *object) +{ + if (p->attributes(object) & QDesignerMetaPropertyInterface::DesignableAttribute) + return PropertyIsDesignable; + return (p->attributes() & QDesignerMetaPropertyInterface::DesignableAttribute) ? + PropertyOfObjectNotDesignable : PropertyNotDesignable; +} + bool QDesignerPropertySheet::isVisible(int index) const { if (d->invalidIndex(Q_FUNC_INFO, index)) @@ -1450,9 +1468,8 @@ bool QDesignerPropertySheet::isVisible(int index) const if (!(p->accessFlags() & QDesignerMetaPropertyInterface::WriteAccess)) return false; - // Enabled handling - return (p->attributes(d->m_object) & QDesignerMetaPropertyInterface::DesignableAttribute) || - (p->attributes() & QDesignerMetaPropertyInterface::DesignableAttribute); + // Enabled handling: Hide only statically not designable properties + return designableState(p, d->m_object) != PropertyNotDesignable; } void QDesignerPropertySheet::setVisible(int index, bool visible) @@ -1482,9 +1499,12 @@ bool QDesignerPropertySheet::isEnabled(int index) const if (d->m_info.value(index).visible == true) // Sun CC 5.5 oddity, wants true return true; + // Enable setting of properties for statically non-designable properties + // as this might be done via TaskMenu/Cursor::setProperty. Note that those + // properties are not visible. const QDesignerMetaPropertyInterface *p = d->m_meta->property(index); return (p->accessFlags() & QDesignerMetaPropertyInterface::WriteAccess) && - (p->attributes(d->m_object) & QDesignerMetaPropertyInterface::DesignableAttribute); + designableState(p, d->m_object) != PropertyOfObjectNotDesignable; } bool QDesignerPropertySheet::isAttribute(int index) const -- cgit v0.12 From 9fd510721a140c46ce371b0c7bbc6917e3709c1d Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 23 Jul 2009 14:20:14 +0200 Subject: Implement clipping in the QPaintEngineEx::stroke() function. This is a huge impact on performance whenever this path is taken. Reviewed-By: Tom Cooksey --- src/gui/painting/qpaintengine_raster.cpp | 3 +++ src/gui/painting/qpaintengineex.cpp | 12 ++++++------ src/gui/painting/qpaintengineex_p.h | 2 ++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 8e91101..a34c264 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1101,6 +1101,9 @@ void QRasterPaintEnginePrivate::systemStateChanged() #ifdef QT_DEBUG_DRAW qDebug() << "systemStateChanged" << this << "deviceRect" << deviceRect << clipRect << systemClip; #endif + + exDeviceRect = deviceRect; + Q_Q(QRasterPaintEngine); q->state()->strokeFlags |= QPaintEngine::DirtyClipRegion; q->state()->fillFlags |= QPaintEngine::DirtyClipRegion; diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index df7dc3e..95355f3 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -296,12 +296,12 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) d->activeStroker = 0; } else { // ### re-enable... -// if (pen.isCosmetic()) { -// d->dashStroker->setClipRect(d->deviceRect); -// } else { -// QRectF clipRect = s->matrix.inverted().mapRect(QRectF(d->deviceRect)); -// d->dashStroker->setClipRect(clipRect); -// } + if (pen.isCosmetic()) { + d->dasher.setClipRect(d->exDeviceRect); + } else { + QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect)); + d->dasher.setClipRect(clipRect); + } d->dasher.setDashPattern(pen.dashPattern()); d->dasher.setDashOffset(pen.dashOffset()); d->activeStroker = &d->dasher; diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index 89b14eb..6e7e3b6 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -150,6 +150,8 @@ public: StrokeHandler *strokeHandler; QStrokerOps *activeStroker; QPen strokerPen; + + QRect exDeviceRect; }; class QPixmapFilter; -- cgit v0.12 From 2851458fbefcc4785a1a76f5216af6159d6c7116 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 23 Jul 2009 14:30:57 +0200 Subject: Diagonal dashes are moving when touching the clip boundary. We normally pad the clip rect with the size of the pen and miterlimit to avoid this, but this didn't handle the case where there was a long diagonal dash. We also need to multiply the padding with the longest dash. Reviewed-By: Tom Cooksey --- src/gui/painting/qstroker.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index ceafe4c..362b0b3 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -1012,10 +1012,13 @@ void QDashStroker::processCurrentSubpath() int dashCount = qMin(m_dashPattern.size(), 32); qfixed dashes[32]; + qreal longestLength = 0; qreal sumLength = 0; for (int i=0; istrokeWidth(); sumLength += dashes[i]; + if (dashes[i] > longestLength) + longestLength = dashes[i]; } if (qFuzzyCompare(sumLength + 1, qreal(1))) @@ -1053,7 +1056,7 @@ void QDashStroker::processCurrentSubpath() qfixed2d line_to_pos; // Pad to avoid clipping the borders of thick pens. - qfixed padding = qMax(m_stroker->strokeWidth(), m_stroker->miterLimit()); + qfixed padding = qt_real_to_fixed(qMax(m_stroker->strokeWidth(), m_stroker->miterLimit()) * longestLength); qfixed2d clip_tl = { qt_real_to_fixed(m_clip_rect.left()) - padding, qt_real_to_fixed(m_clip_rect.top()) - padding }; qfixed2d clip_br = { qt_real_to_fixed(m_clip_rect.right()) + padding , -- cgit v0.12 From c29d1cc49998ef895df9dcbccafe1b6d6d8e7efc Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 23 Jul 2009 15:26:11 +0200 Subject: QPainter::stroke() on raster engine would draw moveto's as lines The reason being that there was an assumption that any non-curved path was a continous polyline. For paths with multiple subpaths in it we need to split this up into multiple strokePolygonCosmetic calls. Task-number: 257621 Reviewed-by: Kim Motoyoshi Kalland --- src/gui/painting/qpaintengine_raster.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index a34c264..5176444 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1682,11 +1682,23 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) if (!s->penData.blend) return; - if (s->flags.fast_pen && path.shape() <= QVectorPath::NonCurvedShapeHint && s->lastPen.brush().isOpaque()) { - strokePolygonCosmetic((QPointF *) path.points(), path.elementCount(), - path.hasImplicitClose() - ? WindingMode - : PolylineMode); + if (s->flags.fast_pen && path.shape() <= QVectorPath::NonCurvedShapeHint + && s->lastPen.brush().isOpaque()) { + int count = path.elementCount(); + QPointF *points = (QPointF *) path.points(); + const QPainterPath::ElementType *types = path.elements(); + int first = 0; + int last; + while (first < count) { + while (first < count && types[first] != QPainterPath::MoveToElement) ++first; + last = first + 1; + while (last < count && types[last] == QPainterPath::LineToElement) ++last; + strokePolygonCosmetic(points + first, last - first, + path.hasImplicitClose() && last == count // only close last one.. + ? WindingMode + : PolylineMode); + first = last; + } } else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) { qreal width = s->lastPen.isCosmetic() -- cgit v0.12 From fdaed851ce71fc474a7959d8fc30b50465a98d0d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 23 Jul 2009 16:14:01 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to origin/qtwebkit-4.5 ( 1535d41a668e5f74f44ff3aa1313a84d5718d2d7 ) Changes in WebKit since the last update: ++ b/WebCore/ChangeLog 2009-07-23 Simon Hausmann Reviewed by Holger Freyther. Fix crashes with the QObject bindings after garbage collection. There is one QtInstance per wrapped QObject, and that QtInstance keeps references to cached JSObjects for slots. When those objects get deleted due to GC, then they becoming dangling pointers. When a cached member dies, it is now removed from the QtInstance's cache. As we cannot track the lifetime of the children, we have to remove them from QtInstance alltogether. They are not cached and were only used for mark(), but we _want_ them to be subject to gc. * bridge/qt/qt_instance.cpp: (JSC::Bindings::QtInstance::~QtInstance): Minor coding style cleanup, use qDeleteAll(). (JSC::Bindings::QtInstance::removeCachedMethod): New function, to clean m_methods and m_defaultMethod. (JSC::Bindings::QtInstance::mark): Avoid marking already marked objects. (JSC::Bindings::QtField::valueFromInstance): Don't save children for marking. * bridge/qt/qt_instance.h: Declare removeCachedMethod. * bridge/qt/qt_runtime.cpp: (JSC::Bindings::QtRuntimeMethod::~QtRuntimeMethod): Call removeCachedMethod with this on the instance. 2009-05-04 Jakub Wieczorek Reviewed by Simon Hausmann. As Qtish implementation of MIMETypeRegistry::getMIMETypeForExtension() returns the application/octet-stream mimetype when it can't associate extension with any mimetype, it can happen that the application/octet-stream mimetype will hit the list of supported image formats. For instance, it is possible when QImageReader or QImageWriter support an extension that is not in the extensions map. Make sure that this mimetype is not treated as displayable image type. * platform/MIMETypeRegistry.cpp: (WebCore::initializeSupportedImageMIMETypes): (WebCore::initializeSupportedImageMIMETypesForEncoding): ++ b/WebKit/qt/ChangeLog 2009-07-23 Simon Hausmann Reviewed by Holger Freyther. Added a testcase to verify that cached methods in the QOBject bindings remain alife even after garbage collection. * tests/qwebpage/tst_qwebpage.cpp: (tst_QWebPage::protectBindingsRuntimeObjectsFromCollector): --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 47 ++++++++++++++++++++++ .../webkit/WebCore/bridge/qt/qt_instance.cpp | 31 +++++++------- .../webkit/WebCore/bridge/qt/qt_instance.h | 3 +- .../webkit/WebCore/bridge/qt/qt_runtime.cpp | 2 + .../webkit/WebCore/platform/MIMETypeRegistry.cpp | 5 +++ src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp | 6 +++ src/3rdparty/webkit/WebKit/qt/ChangeLog | 10 +++++ .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 25 ++++++++++++ 9 files changed, 114 insertions(+), 17 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 88f32d9..eaa0479 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - a3e05ad8acdead3b534d0cef772b85f002e80b8d + 1535d41a668e5f74f44ff3aa1313a84d5718d2d7 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 19bb36a..83f5e6f 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,50 @@ +2009-07-23 Simon Hausmann + + Reviewed by Holger Freyther. + + Fix crashes with the QObject bindings after garbage collection. + + There is one QtInstance per wrapped QObject, and that QtInstance keeps + references to cached JSObjects for slots. When those objects get + deleted due to GC, then they becoming dangling pointers. + + When a cached member dies, it is now removed from the QtInstance's + cache. + + As we cannot track the lifetime of the children, we have to remove + them from QtInstance alltogether. They are not cached and were + only used for mark(), but we _want_ them to be subject to gc. + + * bridge/qt/qt_instance.cpp: + (JSC::Bindings::QtInstance::~QtInstance): Minor coding style cleanup, + use qDeleteAll(). + (JSC::Bindings::QtInstance::removeCachedMethod): New function, to + clean m_methods and m_defaultMethod. + (JSC::Bindings::QtInstance::mark): Avoid marking already marked objects. + (JSC::Bindings::QtField::valueFromInstance): Don't save children for + marking. + * bridge/qt/qt_instance.h: Declare removeCachedMethod. + * bridge/qt/qt_runtime.cpp: + (JSC::Bindings::QtRuntimeMethod::~QtRuntimeMethod): Call removeCachedMethod + with this on the instance. + +2009-05-04 Jakub Wieczorek + + Reviewed by Simon Hausmann. + + As Qtish implementation of MIMETypeRegistry::getMIMETypeForExtension() + returns the application/octet-stream mimetype when it can't associate + extension with any mimetype, it can happen that the application/octet-stream + mimetype will hit the list of supported image formats. For instance, + it is possible when QImageReader or QImageWriter support an extension + that is not in the extensions map. + + Make sure that this mimetype is not treated as displayable image type. + + * platform/MIMETypeRegistry.cpp: + (WebCore::initializeSupportedImageMIMETypes): + (WebCore::initializeSupportedImageMIMETypesForEncoding): + 2009-06-18 Chris Evans Reviewed by Adam Barth. diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp index 4b94a94..4fc95fa 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.cpp @@ -110,9 +110,7 @@ QtInstance::~QtInstance() // clean up (unprotect from gc) the JSValues we've created m_methods.clear(); - foreach(QtField* f, m_fields.values()) { - delete f; - } + qDeleteAll(m_fields); m_fields.clear(); if (m_object) { @@ -158,6 +156,19 @@ RuntimeObjectImp* QtInstance::getRuntimeObject(ExecState* exec, PassRefPtr::Iterator it = m_methods.begin(), + end = m_methods.end(); it != end; ++it) + if (it.value() == method) { + m_methods.erase(it); + return; + } +} + Class* QtInstance::getClass() const { if (!m_class) @@ -167,16 +178,12 @@ Class* QtInstance::getClass() const void QtInstance::mark() { - if (m_defaultMethod) + if (m_defaultMethod && !m_defaultMethod->marked()) m_defaultMethod->mark(); foreach(JSObject* val, m_methods.values()) { if (val && !val->marked()) val->mark(); } - foreach(JSValuePtr val, m_children.values()) { - if (val && !val->marked()) - val->mark(); - } } void QtInstance::begin() @@ -329,13 +336,7 @@ JSValuePtr QtField::valueFromInstance(ExecState* exec, const Instance* inst) con else if (m_type == DynamicProperty) val = obj->property(m_dynamicProperty); - JSValuePtr ret = convertQVariantToValue(exec, inst->rootObject(), val); - - // Need to save children so we can mark them - if (m_type == ChildObject) - instance->m_children.insert(ret); - - return ret; + return convertQVariantToValue(exec, inst->rootObject(), val); } else { QString msg = QString(QLatin1String("cannot access member `%1' of deleted QObject")).arg(QLatin1String(name())); return throwError(exec, GeneralError, msg.toLatin1().constData()); diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h index 50d4cf1..bc22725 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_instance.h @@ -64,6 +64,8 @@ public: static PassRefPtr getQtInstance(QObject*, PassRefPtr, QScriptEngine::ValueOwnership ownership); static RuntimeObjectImp* getRuntimeObject(ExecState* exec, PassRefPtr); + void removeCachedMethod(JSObject*); + private: static PassRefPtr create(QObject *instance, PassRefPtr rootObject, QScriptEngine::ValueOwnership ownership) { @@ -78,7 +80,6 @@ private: QObject* m_hashkey; mutable QHash m_methods; mutable QHash m_fields; - mutable QSet m_children; mutable QtRuntimeMetaMethod* m_defaultMethod; QScriptEngine::ValueOwnership m_ownership; }; diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp index c7ba6c2..c0883a9 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp @@ -913,6 +913,8 @@ QtRuntimeMethod::QtRuntimeMethod(QtRuntimeMethodData* dd, ExecState* exec, const QtRuntimeMethod::~QtRuntimeMethod() { + QW_D(QtRuntimeMethod); + d->m_instance->removeCachedMethod(this); delete d_ptr; } diff --git a/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp b/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp index 8f98735..a85d706 100644 --- a/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp +++ b/src/3rdparty/webkit/WebCore/platform/MIMETypeRegistry.cpp @@ -100,6 +100,9 @@ static void initializeSupportedImageMIMETypes() supportedImageMIMETypes->add(mimeType); supportedImageResourceMIMETypes->add(mimeType); } + + supportedImageMIMETypes->remove("application/octet-stream"); + supportedImageResourceMIMETypes->remove("application/octet-stream"); #else // assume that all implementations at least support the following standard // image types: @@ -145,6 +148,8 @@ static void initializeSupportedImageMIMETypesForEncoding() String mimeType = MIMETypeRegistry::getMIMETypeForExtension(formats.at(i).constData()); supportedImageMIMETypesForEncoding->add(mimeType); } + + supportedImageMIMETypesForEncoding->remove("application/octet-stream"); #elif PLATFORM(CAIRO) supportedImageMIMETypesForEncoding->add("image/png"); #endif diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp index e565476..bd43ce3 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp @@ -32,6 +32,7 @@ #include "Frame.h" #include "FrameTree.h" #include "FrameView.h" +#include "GCController.h" #include "IconDatabase.h" #include "InspectorController.h" #include "Page.h" @@ -105,6 +106,11 @@ void QWEBKIT_EXPORT qt_drt_setJavaScriptProfilingEnabled(QWebFrame* qframe, bool controller->disableProfiler(); } +void QWEBKIT_EXPORT qt_drt_garbageCollector_collect() +{ + gcController().garbageCollectNow(); +} + void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *webcorePage, QWebFrameData *frameData) { q = qframe; diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index a7e176d..125e556 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,13 @@ +2009-07-23 Simon Hausmann + + Reviewed by Holger Freyther. + + Added a testcase to verify that cached methods in the QOBject bindings + remain alife even after garbage collection. + + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::protectBindingsRuntimeObjectsFromCollector): + 2009-06-16 Morten Engvoldsen Reviewed by Ariya Hidayat. diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 620aa31..c3ed54c 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -107,6 +107,7 @@ private slots: void textEditing(); void requestCache(); + void protectBindingsRuntimeObjectsFromCollector(); private: @@ -1037,5 +1038,29 @@ void tst_QWebPage::requestCache() (int)QNetworkRequest::PreferCache); } +void QWEBKIT_EXPORT qt_drt_garbageCollector_collect(); + +void tst_QWebPage::protectBindingsRuntimeObjectsFromCollector() +{ + QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool))); + + PluginPage* newPage = new PluginPage(m_view); + m_view->setPage(newPage); + + m_view->settings()->setAttribute(QWebSettings::PluginsEnabled, true); + + m_view->setHtml(QString("")); + QTRY_COMPARE(loadSpy.count(), 1); + + newPage->mainFrame()->evaluateJavaScript("function testme(text) { var lineedit = document.getElementById('mylineedit'); lineedit.setText(text); lineedit.selectAll(); }"); + + newPage->mainFrame()->evaluateJavaScript("testme('foo')"); + + qt_drt_garbageCollector_collect(); + + // don't crash! + newPage->mainFrame()->evaluateJavaScript("testme('bar')"); +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" -- cgit v0.12 From c8dbff8b5ae8e4b5ef8a46a5e3b513a5f6f4a205 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 24 Jul 2009 09:35:41 +0200 Subject: Fixed crash when vectorpath was polygonal only in raster::stroke() Polygonal vector paths may have types==null, in which case this would have crashed. Reviewed-by: Eskil --- src/gui/painting/qpaintengine_raster.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 5176444..069c350 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1687,17 +1687,24 @@ void QRasterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) int count = path.elementCount(); QPointF *points = (QPointF *) path.points(); const QPainterPath::ElementType *types = path.elements(); - int first = 0; - int last; - while (first < count) { - while (first < count && types[first] != QPainterPath::MoveToElement) ++first; - last = first + 1; - while (last < count && types[last] == QPainterPath::LineToElement) ++last; - strokePolygonCosmetic(points + first, last - first, - path.hasImplicitClose() && last == count // only close last one.. + if (types) { + int first = 0; + int last; + while (first < count) { + while (first < count && types[first] != QPainterPath::MoveToElement) ++first; + last = first + 1; + while (last < count && types[last] == QPainterPath::LineToElement) ++last; + strokePolygonCosmetic(points + first, last - first, + path.hasImplicitClose() && last == count // only close last one.. + ? WindingMode + : PolylineMode); + first = last; + } + } else { + strokePolygonCosmetic(points, count, + path.hasImplicitClose() ? WindingMode : PolylineMode); - first = last; } } else if (s->flags.non_complex_pen && path.shape() == QVectorPath::LinesHint) { -- cgit v0.12 From 9dadc219814cd9baaa4be4cee6ee2b3cf7df4a19 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 24 Jul 2009 10:22:11 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to origin/qtwebkit-4.5 ( eb3afcbfb4006de4015047555cb256fcde93b954 ) Changes in WebKit since the last update: ++ b/WebCore/ChangeLog 2009-05-27 John Sullivan fixed repro crash in WebCore::DragController::dragExited dropping bookmarks (at least) over Top Sites (at least) Reviewed by Kevin Decker * page/DragController.cpp: (WebCore::DragController::dragExited): nil check m_documentUnderMouse and take the "local file" case if it's nil --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 11 +++++++++++ src/3rdparty/webkit/WebCore/html/HTMLElement.cpp | 1 + src/3rdparty/webkit/WebCore/page/DragController.cpp | 2 +- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index eaa0479..12018e1 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 1535d41a668e5f74f44ff3aa1313a84d5718d2d7 + eb3afcbfb4006de4015047555cb256fcde93b954 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 83f5e6f..7dc4f71 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,14 @@ +2009-05-27 John Sullivan + + fixed repro crash in WebCore::DragController::dragExited dropping + bookmarks (at least) over Top Sites (at least) + + Reviewed by Kevin Decker + + * page/DragController.cpp: + (WebCore::DragController::dragExited): + nil check m_documentUnderMouse and take the "local file" case if it's nil + 2009-07-23 Simon Hausmann Reviewed by Holger Freyther. diff --git a/src/3rdparty/webkit/WebCore/html/HTMLElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLElement.cpp index 4caf336..b21a3fe 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLElement.cpp @@ -44,6 +44,7 @@ #include "XMLTokenizer.h" #include "markup.h" #include +#include namespace WebCore { diff --git a/src/3rdparty/webkit/WebCore/page/DragController.cpp b/src/3rdparty/webkit/WebCore/page/DragController.cpp index 10a11f2..c756da8 100644 --- a/src/3rdparty/webkit/WebCore/page/DragController.cpp +++ b/src/3rdparty/webkit/WebCore/page/DragController.cpp @@ -157,7 +157,7 @@ void DragController::dragExited(DragData* dragData) Frame* mainFrame = m_page->mainFrame(); if (RefPtr v = mainFrame->view()) { - ClipboardAccessPolicy policy = m_document->securityOrigin()->isLocal() ? ClipboardReadable : ClipboardTypesReadable; + ClipboardAccessPolicy policy = (!m_document || m_document->securityOrigin()->isLocal()) ? ClipboardReadable : ClipboardTypesReadable; RefPtr clipboard = dragData->createClipboard(policy); clipboard->setSourceOperation(dragData->draggingSourceOperationMask()); mainFrame->eventHandler()->cancelDragAndDrop(createMouseEvent(dragData), clipboard.get()); -- cgit v0.12