summaryrefslogtreecommitdiffstats
path: root/src/platformsupport/fbconvenience
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport/fbconvenience')
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor.cpp18
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor_p.h11
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen.cpp159
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen_p.h21
-rw-r--r--src/platformsupport/fbconvenience/qfbwindow.cpp53
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 &region)
{
- 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
-