summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorJeremy Katz <jeremy.katz@nokia.com>2010-06-11 10:50:27 (GMT)
committerJeremy Katz <jeremy.katz@nokia.com>2010-06-11 10:50:27 (GMT)
commita498db43a02972e90df5f1cdd73e90260471f5f8 (patch)
tree1d8fe5409fe68eaf898ad54de87ce814669c836a /src/plugins/platforms
parent28547949cc78d25884a76bf3c2112a6217ba5b66 (diff)
downloadQt-a498db43a02972e90df5f1cdd73e90260471f5f8.zip
Qt-a498db43a02972e90df5f1cdd73e90260471f5f8.tar.gz
Qt-a498db43a02972e90df5f1cdd73e90260471f5f8.tar.bz2
litehouse multiscreen support
This commit adds QPlatformIntegration::moveToScreen(), which requests that a widget be moved to another screen. The default implementation ignores the request. The VNC plugin has been updated accordingly. It currently only supports non-virtual desktops. Review by: Jørgen
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/fb_base/fb_base.cpp61
-rw-r--r--src/plugins/platforms/fb_base/fb_base.h7
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.cpp40
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h3
-rw-r--r--src/plugins/platforms/vnc/qvncserver.cpp9
5 files changed, 91 insertions, 29 deletions
diff --git a/src/plugins/platforms/fb_base/fb_base.cpp b/src/plugins/platforms/fb_base/fb_base.cpp
index cdcb608..0463a60 100644
--- a/src/plugins/platforms/fb_base/fb_base.cpp
+++ b/src/plugins/platforms/fb_base/fb_base.cpp
@@ -18,6 +18,8 @@ QRect QGraphicsSystemSoftwareCursor::getCurrentRect()
QRect rect = graphic->image()->rect().translated(-graphic->hotspot().x(),
-graphic->hotspot().y());
rect.translate(QCursor::pos());
+ QPoint screenOffset = screen->geometry().topLeft();
+ rect.translate(-screenOffset); // global to local translation
return rect;
}
@@ -25,8 +27,12 @@ QRect QGraphicsSystemSoftwareCursor::getCurrentRect()
void QGraphicsSystemSoftwareCursor::pointerEvent(const QMouseEvent & e)
{
Q_UNUSED(e);
+ QPoint screenOffset = screen->geometry().topLeft();
currentRect = getCurrentRect();
- setDirty();
+ // global to local translation
+ if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset))) {
+ setDirty();
+ }
}
QRect QGraphicsSystemSoftwareCursor::drawCursor(QPainter & painter)
@@ -35,7 +41,10 @@ QRect QGraphicsSystemSoftwareCursor::drawCursor(QPainter & painter)
if (currentRect.isNull())
return QRect();
- if (!currentRect.intersects(screen->geometry()))
+ // We need this because the cursor might be dirty due to moving off screen
+ QPoint screenOffset = screen->geometry().topLeft();
+ // global to local translation
+ if (!currentRect.translated(screenOffset).intersects(screen->geometry()))
return QRect();
prevRect = currentRect;
@@ -82,7 +91,9 @@ void QGraphicsSystemSoftwareCursor::changeCursor(QCursor * widgetCursor, QWidget
setCursor(shape);
}
currentRect = getCurrentRect();
- setDirty();
+ QPoint screenOffset = screen->geometry().topLeft(); // global to local translation
+ if (onScreen || screen->geometry().intersects(currentRect.translated(screenOffset)))
+ setDirty();
}
QFbScreen::QFbScreen() : cursor(0), mGeometry(), mDepth(16), mFormat(QImage::Format_RGB16), mScreenImage(0), compositePainter(0), isUpToDate(false)
@@ -130,7 +141,9 @@ QFbScreen::~QFbScreen()
void QFbScreen::setDirty(const QRect &rect)
{
- repaintRegion += rect;
+ QRect intersection = rect.intersected(mGeometry);
+ QPoint screenOffset = mGeometry.topLeft();
+ repaintRegion += intersection.translated(-screenOffset); // global to local translation
if (!redrawTimer.isActive()) {
redrawTimer.start();
}
@@ -139,7 +152,8 @@ void QFbScreen::setDirty(const QRect &rect)
void QFbScreen::generateRects()
{
cachedRects.clear();
- QRegion remainingScreen(mGeometry);
+ QPoint screenOffset = mGeometry.topLeft();
+ QRegion remainingScreen(mGeometry.translated(-screenOffset)); // global to local translation
for (int i = 0; i < windowStack.length(); i++) {
if (remainingScreen.isEmpty())
@@ -148,8 +162,8 @@ void QFbScreen::generateRects()
continue;
if (!windowStack[i]->widget()->testAttribute(Qt::WA_TranslucentBackground)) {
- remainingScreen -= windowStack[i]->geometry();
- QRegion windowRegion(windowStack[i]->geometry());
+ remainingScreen -= windowStack[i]->localGeometry();
+ QRegion windowRegion(windowStack[i]->localGeometry());
windowRegion -= remainingScreen;
foreach(QRect rect, windowRegion.rects()) {
cachedRects += QPair<QRect, int>(rect, i);
@@ -166,11 +180,16 @@ void QFbScreen::generateRects()
QRegion QFbScreen::doRedraw()
{
+ QPoint screenOffset = mGeometry.topLeft(); // optimize me!
+
QRegion touchedRegion;
- if (cursor && cursor->isDirty() && cursor->isOnScreen())
- repaintRegion += cursor->dirtyRect();
- if (repaintRegion.isEmpty() && !cursor->isDirty())
+ if (cursor && cursor->isDirty() && cursor->isOnScreen()) {
+ QRect lastCursor = cursor->dirtyRect();
+ repaintRegion += lastCursor;
+ }
+ if (repaintRegion.isEmpty() && !cursor->isDirty()) {
return touchedRegion;
+ }
QVector<QRect> rects = repaintRegion.rects();
@@ -206,10 +225,9 @@ QRegion QFbScreen::doRedraw()
continue;
if (windowStack[layerIndex]->widget()->isMinimized())
continue;
- QRect windowRect = windowStack[layerIndex]->geometry();
+ QRect windowRect = windowStack[layerIndex]->geometry().translated(-screenOffset);
QRect windowIntersect = rect.translated(-windowRect.left(),
- -windowRect.top());
-// qDebug() << " compositing" << layerIndex << windowStack[layerIndex]->surface->image().size();
+ -windowRect.top());
compositePainter->drawImage(rect, windowStack[layerIndex]->surface->image(),
windowIntersect);
if (firstLayer) {
@@ -218,10 +236,6 @@ QRegion QFbScreen::doRedraw()
}
}
}
- if (!rectRegion.isEmpty())
- qWarning() << "non-empty region!" << rectRegion;
- // Everything on screen should be mapped to a sub-rectangle
- // unless it's off the screen...
}
QRect cursorRect;
@@ -240,6 +254,16 @@ QRegion QFbScreen::doRedraw()
return touchedRegion;
}
+void QFbScreen::addWindow(QFbWindow *surface)
+{
+ windowStack.prepend(surface);
+ surface->mScreen = this;
+ QPoint screenOffset = mGeometry.topLeft();
+ surface->localGeometry() = surface->geometry().translated(-screenOffset); // global to local translation
+ invalidateRectCache();
+ setDirty(surface->geometry());
+}
+
void QFbScreen::removeWindow(QFbWindow * surface)
{
windowStack.removeOne(surface);
@@ -369,6 +393,9 @@ void QFbWindow::setGeometry(const QRect &rect)
//### QWindowSystemInterface::handleGeometryChange(window(), rect);
QPlatformWindow::setGeometry(rect);
+
+ QPoint screenOffset = mScreen->geometry().topLeft();
+ mLocalGeometry = rect.translated(-screenOffset); // global to local translation
}
bool QFbWindowSurface::scroll(const QRegion &area, int dx, int dy)
diff --git a/src/plugins/platforms/fb_base/fb_base.h b/src/plugins/platforms/fb_base/fb_base.h
index d94462d..f1dd574 100644
--- a/src/plugins/platforms/fb_base/fb_base.h
+++ b/src/plugins/platforms/fb_base/fb_base.h
@@ -98,6 +98,8 @@ public:
virtual void repaint(const QRegion&);
+ virtual QRect localGeometry() { return mLocalGeometry; }
+
protected:
friend class QFbWindowSurface;
friend class QFbScreen;
@@ -106,7 +108,7 @@ protected:
QRect oldGeometry;
bool visibleFlag;
Qt::WindowFlags flags;
-
+ QRect mLocalGeometry; // local screen coordinates
WId windowId;
};
@@ -131,8 +133,7 @@ public:
virtual void setDirty(const QRect &rect);
virtual void removeWindow(QFbWindow * surface);
- virtual void addWindow(QFbWindow * surface) {
- windowStack.prepend(surface); invalidateRectCache(); }
+ virtual void addWindow(QFbWindow * surface);
virtual void raise(QPlatformWindow * surface);
virtual void lower(QPlatformWindow * surface);
virtual QWidget * topLevelAt(const QPoint & p) const;
diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp
index 69aea79..de6d81f 100644
--- a/src/plugins/platforms/vnc/qvncintegration.cpp
+++ b/src/plugins/platforms/vnc/qvncintegration.cpp
@@ -50,7 +50,6 @@
#include <QtCore/QTimer>
-
QVNCScreen::QVNCScreen(QRect screenSize, int screenId)
: QFbScreen::QFbScreen()
{
@@ -99,6 +98,8 @@ QVNCIntegration::QVNCIntegration(const QStringList& paramList)
{
int sizeX = defaultWidth();
int sizeY = defaultHeight();
+ int offsetX = 0;
+ int offsetY = 0;
int display = defaultDisplay();
bool showUsage = false;
@@ -111,6 +112,19 @@ QVNCIntegration::QVNCIntegration(const QStringList& paramList)
else if (confString.startsWith(QLatin1String("display="))) {
display = confString.section(QLatin1Char('='), 1, 1).toInt();
}
+ else if (confString.startsWith(QLatin1String("offset="))) {
+ QString val = confString.section(QLatin1Char('='), 1, 1);
+ offsetX = val.section(QLatin1Char('x'), 0, 0).toInt();
+ offsetY = val.section(QLatin1Char('x'), 1, 1).toInt();
+ }
+ else if (confString == QLatin1String("vnc")) {
+ QRect screenRect(offsetX, offsetY, sizeX, sizeY);
+ QVNCScreen *screen = new QVNCScreen(screenRect, display);
+ mScreens.append(screen);
+ screen->setObjectName(QString("screen %1").arg(display));
+ screen->setDirty(screenRect);
+ ++display;
+ }
else {
qWarning() << "Unknown VNC option:" << confString;
showUsage = true;
@@ -120,9 +134,12 @@ QVNCIntegration::QVNCIntegration(const QStringList& paramList)
if (showUsage)
usage();
- mPrimaryScreen = new QVNCScreen(QRect(0, 0, sizeX, sizeY), display);
-
- mScreens.append(mPrimaryScreen);
+ QRect screenRect(offsetX, offsetY, sizeX, sizeY);
+ QVNCScreen *screen = new QVNCScreen(screenRect, display);
+ mScreens.append(screen);
+ mPrimaryScreen = qobject_cast<QVNCScreen *>(mScreens.first());
+ screen->setObjectName(QString("screen %1").arg(display));
+ screen->setDirty(screenRect);
}
QPixmapData *QVNCIntegration::createPixmapData(QPixmapData::PixelType type) const
@@ -155,3 +172,18 @@ QPlatformWindow *QVNCIntegration::createPlatformWindow(QWidget *widget, WId /*wi
return w;
}
+void QVNCIntegration::moveToScreen(QWidget *window, int screen)
+{
+ if (screen < 0 || screen > mScreens.size())
+ return;
+ QVNCScreen * newScreen = qobject_cast<QVNCScreen *>(mScreens.at(screen));
+ for(int i = 0; i < mScreens.size(); i++) {
+ QVNCScreen *oldScreen = qobject_cast<QVNCScreen *>(mScreens.at(i));
+ if (oldScreen->windowStack.contains(static_cast<QFbWindow *>(window->platformWindow()))) {
+ oldScreen->removeWindow(static_cast<QFbWindow *>(window->platformWindow()));
+ break;
+ }
+ }
+ window->platformWindow()->setGeometry(window->geometry()); // this should be unified elsewhere
+ newScreen->addWindow(static_cast<QFbWindow *>(window->platformWindow()));
+}
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
index dcb5419..3436e51 100644
--- a/src/plugins/platforms/vnc/qvncintegration.h
+++ b/src/plugins/platforms/vnc/qvncintegration.h
@@ -55,6 +55,7 @@ class QVNCScreenPrivate;
class QVNCScreen : public QFbScreen
{
+ Q_OBJECT
public:
QVNCScreen(QRect screenSize, int screenId);
@@ -68,6 +69,7 @@ public:
private:
QVNCServer *server;
QRegion doRedraw();
+ friend class QVNCIntegration;
};
class QVNCIntegrationPrivate;
@@ -84,6 +86,7 @@ public:
QList<QPlatformScreen *> screens() const { return mScreens; }
+ void moveToScreen(QWidget *window, int screen);
private:
QVNCScreen *mPrimaryScreen;
diff --git a/src/plugins/platforms/vnc/qvncserver.cpp b/src/plugins/platforms/vnc/qvncserver.cpp
index 6424083..fb6eaa8 100644
--- a/src/plugins/platforms/vnc/qvncserver.cpp
+++ b/src/plugins/platforms/vnc/qvncserver.cpp
@@ -831,14 +831,13 @@ static bool buttonChange(Qt::MouseButtons before, Qt::MouseButtons after, Qt::Mo
void QVNCServer::pointerEvent()
{
+ QPoint screenOffset = this->screen()->geometry().topLeft();
+
QRfbPointerEvent ev;
if (ev.read(client)) {
-// const QPoint offset = qvnc_screen->offset();
-// QWSServer::sendMouseEvent(offset + QPoint(ev.x, ev.y), ev.buttons);
-
QPoint eventPoint(ev.x, ev.y);
- eventPoint += screen()->geometry().topLeft();
- //qDebug() << "pointerEvent" << ev.x << ev.y << hex << ev.buttons;
+ eventPoint += screenOffset; // local to global translation
+
if (ev.wheelDirection == ev.WheelNone) {
QEvent::Type type = QEvent::MouseMove;
Qt::MouseButton button = Qt::NoButton;