From 3acd8d9aa463ffcc7d63d5262c0a66577c38f556 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 16 Feb 2015 16:26:15 +0100 Subject: Support grabWindow() in linuxfb Task-number: QTBUG-44465 Change-Id: Id4b0fcbcce3e005c1f147fa227ef987daac20fd5 Reviewed-by: Andy Nichols --- .../fbconvenience/qfbbackingstore.cpp | 2 +- src/platformsupport/fbconvenience/qfbscreen.cpp | 17 +++++++++---- src/platformsupport/fbconvenience/qfbscreen_p.h | 9 +++---- src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp | 28 ++++++++++++++++++++++ src/plugins/platforms/linuxfb/qlinuxfbscreen.h | 3 ++- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/platformsupport/fbconvenience/qfbbackingstore.cpp b/src/platformsupport/fbconvenience/qfbbackingstore.cpp index bf9beac894..2800a81507 100644 --- a/src/platformsupport/fbconvenience/qfbbackingstore.cpp +++ b/src/platformsupport/fbconvenience/qfbbackingstore.cpp @@ -46,7 +46,7 @@ QFbBackingStore::QFbBackingStore(QWindow *window) if (window->handle()) (static_cast(window->handle()))->setBackingStore(this); else - (static_cast(window->screen()->handle()))->addBackingStore(this); + (static_cast(window->screen()->handle()))->addPendingBackingStore(this); } QFbBackingStore::~QFbBackingStore() diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp index 04aa9f2fae..566f84c9ea 100644 --- a/src/platformsupport/fbconvenience/qfbscreen.cpp +++ b/src/platformsupport/fbconvenience/qfbscreen.cpp @@ -74,15 +74,15 @@ bool QFbScreen::event(QEvent *event) void QFbScreen::addWindow(QFbWindow *window) { mWindowStack.prepend(window); - if (!mBackingStores.isEmpty()) { + if (!mPendingBackingStores.isEmpty()) { //check if we have a backing store for this window - for (int i = 0; i < mBackingStores.size(); ++i) { - QFbBackingStore *bs = mBackingStores.at(i); + for (int i = 0; i < mPendingBackingStores.size(); ++i) { + QFbBackingStore *bs = mPendingBackingStores.at(i); // this gets called during QWindow::create() at a point where the // invariant (window->handle()->window() == window) is broken if (bs->window() == window->window()) { window->setBackingStore(bs); - mBackingStores.removeAt(i); + mPendingBackingStores.removeAt(i); break; } } @@ -295,5 +295,14 @@ QRegion QFbScreen::doRedraw() return touchedRegion; } +QFbWindow *QFbScreen::windowForId(WId wid) const +{ + for (int i = 0; i < mWindowStack.count(); ++i) + if (mWindowStack[i]->winId() == wid) + return mWindowStack[i]; + + return 0; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbscreen_p.h b/src/platformsupport/fbconvenience/qfbscreen_p.h index 7f2db51b00..17b2cab43d 100644 --- a/src/platformsupport/fbconvenience/qfbscreen_p.h +++ b/src/platformsupport/fbconvenience/qfbscreen_p.h @@ -80,7 +80,7 @@ public: virtual void lower(QFbWindow *window); virtual void topWindowChanged(QWindow *) {} - void addBackingStore(QFbBackingStore *bs) {mBackingStores << bs;} + void addPendingBackingStore(QFbBackingStore *bs) { mPendingBackingStores << bs; } void scheduleUpdate(); @@ -89,13 +89,14 @@ public slots: void setPhysicalSize(const QSize &size); void setGeometry(const QRect &rect); -protected slots: +protected: virtual QRegion doRedraw(); -protected: void initializeCompositor(); bool event(QEvent *event); + QFbWindow *windowForId(WId wid) const; + QList mWindowStack; QRegion mRepaintRegion; bool mUpdatePending; @@ -113,7 +114,7 @@ private: QPainter *mCompositePainter; QVector > mCachedRects; - QList mBackingStores; + QList mPendingBackingStores; friend class QFbWindow; bool mIsUpToDate; diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp index 1c3854182f..5407fa66dc 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp @@ -33,6 +33,7 @@ #include "qlinuxfbscreen.h" #include +#include #include #include @@ -421,5 +422,32 @@ QRegion QLinuxFbScreen::doRedraw() return touched; } +// grabWindow() grabs "from the screen" not from the backingstores. +// In linuxfb's case it will also include the mouse cursor. +QPixmap QLinuxFbScreen::grabWindow(WId wid, int x, int y, int width, int height) const +{ + if (!wid) { + if (width < 0) + width = mFbScreenImage.width() - x; + if (height < 0) + height = mFbScreenImage.height() - y; + return QPixmap::fromImage(mFbScreenImage).copy(x, y, width, height); + } + + QFbWindow *window = windowForId(wid); + if (window) { + const QRect geom = window->geometry(); + if (width < 0) + width = geom.width() - x; + if (height < 0) + height = geom.height() - y; + QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height)); + rect &= window->geometry(); + return QPixmap::fromImage(mFbScreenImage).copy(rect); + } + + return QPixmap(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h index 0cb9961599..1adce2189b 100644 --- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h +++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h @@ -50,7 +50,8 @@ public: bool initialize(); -public slots: + QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE; + QRegion doRedraw() Q_DECL_OVERRIDE; private: -- cgit v1.2.3