Support grabWindow() in linuxfb

Task-number: QTBUG-44465
Change-Id: Id4b0fcbcce3e005c1f147fa227ef987daac20fd5
Reviewed-by: Andy Nichols <andy.nichols@theqtcompany.com>
This commit is contained in:
Laszlo Agocs 2015-02-16 16:26:15 +01:00
parent 8e12367a94
commit 3acd8d9aa4
5 changed files with 49 additions and 10 deletions

View File

@ -46,7 +46,7 @@ QFbBackingStore::QFbBackingStore(QWindow *window)
if (window->handle())
(static_cast<QFbWindow *>(window->handle()))->setBackingStore(this);
else
(static_cast<QFbScreen *>(window->screen()->handle()))->addBackingStore(this);
(static_cast<QFbScreen *>(window->screen()->handle()))->addPendingBackingStore(this);
}
QFbBackingStore::~QFbBackingStore()

View File

@ -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

View File

@ -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<QFbWindow *> mWindowStack;
QRegion mRepaintRegion;
bool mUpdatePending;
@ -113,7 +114,7 @@ private:
QPainter *mCompositePainter;
QVector<QPair<QRect, int> > mCachedRects;
QList <QFbBackingStore*> mBackingStores;
QList<QFbBackingStore*> mPendingBackingStores;
friend class QFbWindow;
bool mIsUpToDate;

View File

@ -33,6 +33,7 @@
#include "qlinuxfbscreen.h"
#include <QtPlatformSupport/private/qfbcursor_p.h>
#include <QtPlatformSupport/private/qfbwindow_p.h>
#include <QtCore/QRegularExpression>
#include <QtGui/QPainter>
@ -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

View File

@ -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: