diff options
Diffstat (limited to 'src/platformsupport/fbconvenience')
-rw-r--r-- | src/platformsupport/fbconvenience/qfbcursor.cpp | 18 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbcursor_p.h | 11 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbscreen.cpp | 159 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbscreen_p.h | 21 | ||||
-rw-r--r-- | src/platformsupport/fbconvenience/qfbwindow.cpp | 53 |
5 files changed, 112 insertions, 150 deletions
diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp index 004c586de3..7daf3f4d0c 100644 --- a/src/platformsupport/fbconvenience/qfbcursor.cpp +++ b/src/platformsupport/fbconvenience/qfbcursor.cpp @@ -60,8 +60,8 @@ QFbCursor::QFbCursor(QFbScreen *screen) mScreen(screen), mDirty(false), mOnScreen(false), - mGraphic(0), - mDeviceListener(0) + mCursorImage(nullptr), + mDeviceListener(nullptr) { QByteArray hideCursorVal = qgetenv("QT_QPA_FB_HIDECURSOR"); if (!hideCursorVal.isEmpty()) @@ -69,7 +69,7 @@ QFbCursor::QFbCursor(QFbScreen *screen) if (!mVisible) return; - mGraphic = new QPlatformCursorImage(0, 0, 0, 0, 0, 0); + mCursorImage = new QPlatformCursorImage(0, 0, 0, 0, 0, 0); setCursor(Qt::ArrowCursor); mDeviceListener = new QFbCursorDeviceListener(this); @@ -85,8 +85,8 @@ QFbCursor::~QFbCursor() QRect QFbCursor::getCurrentRect() { - QRect rect = mGraphic->image()->rect().translated(-mGraphic->hotspot().x(), - -mGraphic->hotspot().y()); + QRect rect = mCursorImage->image()->rect().translated(-mCursorImage->hotspot().x(), + -mCursorImage->hotspot().y()); rect.translate(m_pos); QPoint mScreenOffset = mScreen->geometry().topLeft(); rect.translate(-mScreenOffset); // global to local translation @@ -133,7 +133,7 @@ QRect QFbCursor::drawCursor(QPainter & painter) return QRect(); mPrevRect = mCurrentRect; - painter.drawImage(mPrevRect, *mGraphic->image()); + painter.drawImage(mPrevRect, *mCursorImage->image()); mOnScreen = true; return mPrevRect; } @@ -149,17 +149,17 @@ QRect QFbCursor::dirtyRect() void QFbCursor::setCursor(Qt::CursorShape shape) { - mGraphic->set(shape); + mCursorImage->set(shape); } void QFbCursor::setCursor(const QImage &image, int hotx, int hoty) { - mGraphic->set(image, hotx, hoty); + mCursorImage->set(image, hotx, hoty); } void QFbCursor::setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY) { - mGraphic->set(data, mask, width, height, hotX, hotY); + mCursorImage->set(data, mask, width, height, hotX, hotY); } #ifndef QT_NO_CURSOR diff --git a/src/platformsupport/fbconvenience/qfbcursor_p.h b/src/platformsupport/fbconvenience/qfbcursor_p.h index f08babd45b..beda10a5f3 100644 --- a/src/platformsupport/fbconvenience/qfbcursor_p.h +++ b/src/platformsupport/fbconvenience/qfbcursor_p.h @@ -87,11 +87,11 @@ public: virtual QRect drawCursor(QPainter &painter); // input methods - void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE; - QPoint pos() const Q_DECL_OVERRIDE; - void setPos(const QPoint &pos) Q_DECL_OVERRIDE; + void pointerEvent(const QMouseEvent &event) override; + QPoint pos() const override; + void setPos(const QPoint &pos) override; #ifndef QT_NO_CURSOR - void changeCursor(QCursor *widgetCursor, QWindow *window) Q_DECL_OVERRIDE; + void changeCursor(QCursor *widgetCursor, QWindow *window) override; #endif virtual void setDirty(); @@ -113,7 +113,7 @@ private: QRect mPrevRect; // last place the cursor was drawn bool mDirty; bool mOnScreen; - QPlatformCursorImage *mGraphic; + QPlatformCursorImage *mCursorImage; QFbCursorDeviceListener *mDeviceListener; QPoint m_pos; }; @@ -121,4 +121,3 @@ private: QT_END_NAMESPACE #endif // QFBCURSOR_P_H - diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index 216f2722a4..2b4498157c 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -51,19 +51,23 @@ QT_BEGIN_NAMESPACE -QFbScreen::QFbScreen() : mUpdatePending(false), mCursor(0), mGeometry(), mDepth(16), mFormat(QImage::Format_RGB16), mScreenImage(0), mCompositePainter(0), mIsUpToDate(false) +QFbScreen::QFbScreen() + : mUpdatePending(false), + mCursor(0), + mDepth(16), + mFormat(QImage::Format_RGB16), + mPainter(nullptr) { } QFbScreen::~QFbScreen() { - delete mCompositePainter; - delete mScreenImage; + delete mPainter; } void QFbScreen::initializeCompositor() { - mScreenImage = new QImage(mGeometry.size(), mFormat); + mScreenImage = QImage(mGeometry.size(), mFormat); scheduleUpdate(); } @@ -93,7 +97,6 @@ void QFbScreen::addWindow(QFbWindow *window) } } } - invalidateRectCache(); setDirty(window->geometry()); QWindow *w = topWindow(); QWindowSystemInterface::handleWindowActivated(w); @@ -103,7 +106,6 @@ void QFbScreen::addWindow(QFbWindow *window) void QFbScreen::removeWindow(QFbWindow *window) { mWindowStack.removeOne(window); - invalidateRectCache(); setDirty(window->geometry()); QWindow *w = topWindow(); QWindowSystemInterface::handleWindowActivated(w); @@ -116,7 +118,6 @@ void QFbScreen::raise(QFbWindow *window) if (index <= 0) return; mWindowStack.move(index, 0); - invalidateRectCache(); setDirty(window->geometry()); QWindow *w = topWindow(); QWindowSystemInterface::handleWindowActivated(w); @@ -129,7 +130,6 @@ void QFbScreen::lower(QFbWindow *window) if (index == -1 || index == (mWindowStack.size() - 1)) return; mWindowStack.move(index, mWindowStack.size() - 1); - invalidateRectCache(); setDirty(window->geometry()); QWindow *w = topWindow(); QWindowSystemInterface::handleWindowActivated(w); @@ -142,7 +142,7 @@ QWindow *QFbScreen::topWindow() const if (fbw->window()->type() == Qt::Window || fbw->window()->type() == Qt::Dialog) return fbw->window(); } - return 0; + return nullptr; } QWindow *QFbScreen::topLevelAt(const QPoint & p) const @@ -151,14 +151,19 @@ QWindow *QFbScreen::topLevelAt(const QPoint & p) const if (fbw->geometry().contains(p, false) && fbw->window()->isVisible()) return fbw->window(); } - return 0; + return nullptr; +} + +int QFbScreen::windowCount() const +{ + return mWindowStack.count(); } void QFbScreen::setDirty(const QRect &rect) { - QRect intersection = rect.intersected(mGeometry); - QPoint screenOffset = mGeometry.topLeft(); - mRepaintRegion += intersection.translated(-screenOffset); // global to local translation + const QRect intersection = rect.intersected(mGeometry); + const QPoint screenOffset = mGeometry.topLeft(); + mRepaintRegion += intersection.translated(-screenOffset); // global to local translation scheduleUpdate(); } @@ -177,141 +182,81 @@ void QFbScreen::setPhysicalSize(const QSize &size) void QFbScreen::setGeometry(const QRect &rect) { - delete mCompositePainter; - mCompositePainter = 0; - delete mScreenImage; + delete mPainter; + mPainter = nullptr; mGeometry = rect; - mScreenImage = new QImage(mGeometry.size(), mFormat); - invalidateRectCache(); + mScreenImage = QImage(mGeometry.size(), mFormat); QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry(), availableGeometry()); resizeMaximizedWindows(); } -void QFbScreen::generateRects() +bool QFbScreen::initialize() { - mCachedRects.clear(); - QPoint screenOffset = mGeometry.topLeft(); - QRegion remainingScreen(mGeometry.translated(-screenOffset)); // global to local translation - - for (int i = 0; i < mWindowStack.length(); i++) { - if (remainingScreen.isEmpty()) - break; -#if 0 - if (!mWindowStack[i]->isVisible()) - continue; - if (mWindowStack[i]->isMinimized()) - continue; - - if (!mWindowStack[i]->testAttribute(Qt::WA_TranslucentBackground)) { - QRect localGeometry = mWindowStack.at(i)->geometry().translated(-screenOffset); // global to local translation - remainingScreen -= localGeometry; - QRegion windowRegion(localGeometry); - windowRegion -= remainingScreen; - for (const QRect &rect : windowRegion) - mCachedRects += QPair<QRect, int>(rect, i); - } -#endif - } - mCachedRects.reserve(mCachedRects.count() + remainingScreen.rectCount()); - for (const QRect &rect : remainingScreen) - mCachedRects += QPair<QRect, int>(rect, -1); - mIsUpToDate = true; + return true; } QRegion QFbScreen::doRedraw() { - QPoint screenOffset = mGeometry.topLeft(); + const QPoint screenOffset = mGeometry.topLeft(); QRegion touchedRegion; if (mCursor && mCursor->isDirty() && mCursor->isOnScreen()) { - QRect lastCursor = mCursor->dirtyRect(); + const QRect lastCursor = mCursor->dirtyRect(); mRepaintRegion += lastCursor; } - if (mRepaintRegion.isEmpty() && (!mCursor || !mCursor->isDirty())) { + if (mRepaintRegion.isEmpty() && (!mCursor || !mCursor->isDirty())) return touchedRegion; - } - QVector<QRect> rects = mRepaintRegion.rects(); - - if (!mIsUpToDate) - generateRects(); - - if (!mCompositePainter) - mCompositePainter = new QPainter(mScreenImage); + if (!mPainter) + mPainter = new QPainter(&mScreenImage); + const QVector<QRect> rects = mRepaintRegion.rects(); + const QRect screenRect = mGeometry.translated(-screenOffset); for (int rectIndex = 0; rectIndex < mRepaintRegion.rectCount(); rectIndex++) { - QRegion rectRegion = rects[rectIndex]; + const QRect rect = rects[rectIndex].intersected(screenRect); + if (rect.isEmpty()) + continue; - for (int i = 0; i < mCachedRects.length(); i++) { - QRect screenSubRect = mCachedRects[i].first; - int layer = mCachedRects[i].second; - QRegion intersect = rectRegion.intersected(screenSubRect); + mPainter->setCompositionMode(QPainter::CompositionMode_Source); + mPainter->fillRect(rect, mScreenImage.hasAlphaChannel() ? Qt::transparent : Qt::black); - if (intersect.isEmpty()) + for (int layerIndex = mWindowStack.size() - 1; layerIndex != -1; layerIndex--) { + if (!mWindowStack[layerIndex]->window()->isVisible()) continue; - rectRegion -= intersect; - - // we only expect one rectangle, but defensive coding... - for (const QRect &rect : intersect) { - bool firstLayer = true; - if (layer == -1) { - mCompositePainter->setCompositionMode(QPainter::CompositionMode_Source); - mCompositePainter->fillRect(rect, mScreenImage->hasAlphaChannel() ? Qt::transparent : Qt::black); - firstLayer = false; - layer = mWindowStack.size() - 1; - } - - for (int layerIndex = layer; layerIndex != -1; layerIndex--) { - if (!mWindowStack[layerIndex]->window()->isVisible()) - continue; - // if (mWindowStack[layerIndex]->isMinimized()) - // continue; - - QRect windowRect = mWindowStack[layerIndex]->geometry().translated(-screenOffset); - QRect windowIntersect = rect.translated(-windowRect.left(), - -windowRect.top()); - - - QFbBackingStore *backingStore = mWindowStack[layerIndex]->backingStore(); - - if (backingStore) { - backingStore->lock(); - mCompositePainter->drawImage(rect, backingStore->image(), windowIntersect); - backingStore->unlock(); - } - if (firstLayer) { - firstLayer = false; - } - } + const QRect windowRect = mWindowStack[layerIndex]->geometry().translated(-screenOffset); + const QRect windowIntersect = rect.translated(-windowRect.left(), -windowRect.top()); + QFbBackingStore *backingStore = mWindowStack[layerIndex]->backingStore(); + if (backingStore) { + backingStore->lock(); + mPainter->drawImage(rect, backingStore->image(), windowIntersect); + backingStore->unlock(); } } } - QRect cursorRect; if (mCursor && (mCursor->isDirty() || mRepaintRegion.intersects(mCursor->lastPainted()))) { - mCompositePainter->setCompositionMode(QPainter::CompositionMode_SourceOver); - cursorRect = mCursor->drawCursor(*mCompositePainter); - touchedRegion += cursorRect; + mPainter->setCompositionMode(QPainter::CompositionMode_SourceOver); + touchedRegion += mCursor->drawCursor(*mPainter); } touchedRegion += mRepaintRegion; mRepaintRegion = QRegion(); - - -// qDebug() << "QFbScreen::doRedraw" << mWindowStack.size() << mScreenImage->size() << touchedRegion; - return touchedRegion; } QFbWindow *QFbScreen::windowForId(WId wid) const { - for (int i = 0; i < mWindowStack.count(); ++i) + for (int i = 0; i < mWindowStack.count(); ++i) { if (mWindowStack[i]->winId() == wid) return mWindowStack[i]; + } + return nullptr; +} +QFbScreen::Flags QFbScreen::flags() const +{ return 0; } QT_END_NAMESPACE - diff --git a/src/platformsupport/fbconvenience/qfbscreen_p.h b/src/platformsupport/fbconvenience/qfbscreen_p.h index e9b570aa1c..1c27a941cc 100644 --- a/src/platformsupport/fbconvenience/qfbscreen_p.h +++ b/src/platformsupport/fbconvenience/qfbscreen_p.h @@ -66,10 +66,18 @@ class QFbBackingStore; class QFbScreen : public QObject, public QPlatformScreen { Q_OBJECT + public: + enum Flag { + DontForceFirstWindowToFullScreen = 0x01 + }; + Q_DECLARE_FLAGS(Flags, Flag) + QFbScreen(); ~QFbScreen(); + virtual bool initialize(); + QRect geometry() const Q_DECL_OVERRIDE { return mGeometry; } int depth() const Q_DECL_OVERRIDE { return mDepth; } QImage::Format format() const Q_DECL_OVERRIDE { return mFormat; } @@ -85,6 +93,8 @@ public: virtual void raise(QFbWindow *window); virtual void lower(QFbWindow *window); virtual void topWindowChanged(QWindow *) {} + virtual int windowCount() const; + virtual Flags flags() const; void addPendingBackingStore(QFbBackingStore *bs) { mPendingBackingStores << bs; } @@ -112,20 +122,17 @@ protected: int mDepth; QImage::Format mFormat; QSizeF mPhysicalSize; - QImage *mScreenImage; + QImage mScreenImage; private: - void invalidateRectCache() { mIsUpToDate = false; } - void generateRects(); - - QPainter *mCompositePainter; - QVector<QPair<QRect, int> > mCachedRects; + QPainter *mPainter; QList<QFbBackingStore*> mPendingBackingStores; friend class QFbWindow; - bool mIsUpToDate; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QFbScreen::Flags) + QT_END_NAMESPACE #endif // QFBSCREEN_P_H diff --git a/src/platformsupport/fbconvenience/qfbwindow.cpp b/src/platformsupport/fbconvenience/qfbwindow.cpp index 2d5570fe5d..7e016f2f49 100644 --- a/src/platformsupport/fbconvenience/qfbwindow.cpp +++ b/src/platformsupport/fbconvenience/qfbwindow.cpp @@ -66,41 +66,55 @@ void QFbWindow::setGeometry(const QRect &rect) // store previous geometry for screen update mOldGeometry = geometry(); - platformScreen()->invalidateRectCache(); QWindowSystemInterface::handleGeometryChange(window(), rect); QPlatformWindow::setGeometry(rect); + + if (mOldGeometry != rect) + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); } void QFbWindow::setVisible(bool visible) { + QRect newGeom; + QFbScreen *fbScreen = platformScreen(); if (visible) { - if (mWindowState & Qt::WindowFullScreen) - setGeometry(platformScreen()->geometry()); + bool convOk = false; + static bool envDisableForceFullScreen = qEnvironmentVariableIntValue("QT_QPA_FB_FORCE_FULLSCREEN", &convOk) == 0 && convOk; + const bool platformDisableForceFullScreen = fbScreen->flags().testFlag(QFbScreen::DontForceFirstWindowToFullScreen); + const bool forceFullScreen = !envDisableForceFullScreen && !platformDisableForceFullScreen && fbScreen->windowCount() == 0; + if (forceFullScreen || (mWindowState & Qt::WindowFullScreen)) + newGeom = platformScreen()->geometry(); else if (mWindowState & Qt::WindowMaximized) - setGeometry(platformScreen()->availableGeometry()); + newGeom = platformScreen()->availableGeometry(); } QPlatformWindow::setVisible(visible); if (visible) - platformScreen()->addWindow(this); + fbScreen->addWindow(this); else - platformScreen()->removeWindow(this); -} + fbScreen->removeWindow(this); + if (!newGeom.isEmpty()) + setGeometry(newGeom); // may or may not generate an expose + + if (newGeom.isEmpty() || newGeom == mOldGeometry) { + // QWindow::isExposed() maps to QWindow::visible() by default so simply + // generating an expose event regardless of this being a show or hide is + // just what is needed here. + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); + } +} void QFbWindow::setWindowState(Qt::WindowState state) { QPlatformWindow::setWindowState(state); mWindowState = state; - platformScreen()->invalidateRectCache(); } - void QFbWindow::setWindowFlags(Qt::WindowFlags flags) { mWindowFlags = flags; - platformScreen()->invalidateRectCache(); } Qt::WindowFlags QFbWindow::windowFlags() const @@ -111,29 +125,26 @@ Qt::WindowFlags QFbWindow::windowFlags() const void QFbWindow::raise() { platformScreen()->raise(this); + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); } void QFbWindow::lower() { platformScreen()->lower(this); + QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size())); } void QFbWindow::repaint(const QRegion ®ion) { - QRect currentGeometry = geometry(); - - QRect dirtyClient = region.boundingRect(); - QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(), - currentGeometry.top() + dirtyClient.top(), - dirtyClient.width(), - dirtyClient.height()); - QRect mOldGeometryLocal = mOldGeometry; + const QRect currentGeometry = geometry(); + const QRect dirtyClient = region.boundingRect(); + const QRect dirtyRegion = dirtyClient.translated(currentGeometry.topLeft()); + const QRect oldGeometryLocal = mOldGeometry; mOldGeometry = currentGeometry; // If this is a move, redraw the previous location - if (mOldGeometryLocal != currentGeometry) - platformScreen()->setDirty(mOldGeometryLocal); + if (oldGeometryLocal != currentGeometry) + platformScreen()->setDirty(oldGeometryLocal); platformScreen()->setDirty(dirtyRegion); } QT_END_NAMESPACE - |