Added workable QScreen API on top of QPlatformScreen.

QPlatformIntegration::screens() no longer has to be implemented,
implementations should call QPlatformIntegration::screenAdded() for each
screen instead. This is for being able to support adding screens at
run-time later on, by connecting it to a signal in QGuiApplication.

The QGuiGLContext API has changed a bit, by not sending in all the
parameters in the constructor but instead having a create() function.
The createPlatformGLContext() factory in QPlatformIntegration takes a
QGuiGLContext * instead of a QSurfaceFormat and a share context, similar
to how the window and backing store factory functions work.

The XCB plugin has experimental support for connecting to multiple X
displays simultaneously, creating one or more QScreen for each.

Change-Id: I248a22a4fd3481280710110272c04a30a8021e8f
Reviewed-on: http://codereview.qt.nokia.com/2103
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
This commit is contained in:
Samuel Rødal 2011-07-21 13:50:28 +02:00 committed by Jørgen Lind
parent e80b661952
commit c3da77798b
50 changed files with 676 additions and 367 deletions

View File

@ -12,7 +12,9 @@ Renderer::Renderer()
m_format.setDepthBufferSize(16); m_format.setDepthBufferSize(16);
m_format.setSamples(4); m_format.setSamples(4);
m_context = new QGuiGLContext(m_format); m_context = new QGuiGLContext;
m_context->setFormat(m_format);
m_context->create();
} }
QSurfaceFormat Renderer::format() const QSurfaceFormat Renderer::format() const

View File

@ -1,4 +1,5 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <QScreen>
#include "window.h" #include "window.h"
@ -15,5 +16,16 @@ int main(int argc, char **argv)
Window child(&b); Window child(&b);
child.setVisible(true); child.setVisible(true);
// create one window on each additional screen as well
QList<QScreen *> screens = app.screens();
foreach (QScreen *screen, screens) {
if (screen == app.primaryScreen())
continue;
Window *window = new Window(screen);
window->setVisible(true);
window->setWindowTitle(screen->name());
}
return app.exec(); return app.exec();
} }

View File

@ -14,13 +14,23 @@ QColor colorTable[] =
QColor("#c0ef8f") QColor("#c0ef8f")
}; };
Window::Window(QScreen *screen)
: QWindow(screen)
, m_backgroundColorIndex(colorIndexId++)
{
initialize();
}
Window::Window(QWindow *parent) Window::Window(QWindow *parent)
: QWindow(parent) : QWindow(parent)
, m_backgroundColorIndex(colorIndexId++) , m_backgroundColorIndex(colorIndexId++)
{ {
setWindowTitle(QLatin1String("Window")); initialize();
}
if (parent) void Window::initialize()
{
if (parent())
setGeometry(QRect(160, 120, 320, 240)); setGeometry(QRect(160, 120, 320, 240));
else { else {
setGeometry(QRect(10, 10, 640, 480)); setGeometry(QRect(10, 10, 640, 480));
@ -38,6 +48,7 @@ Window::Window(QWindow *parent)
m_image.fill(colorTable[m_backgroundColorIndex % (sizeof(colorTable) / sizeof(colorTable[0]))].rgba()); m_image.fill(colorTable[m_backgroundColorIndex % (sizeof(colorTable) / sizeof(colorTable[0]))].rgba());
m_lastPos = QPoint(-1, -1); m_lastPos = QPoint(-1, -1);
m_renderTimer = 0;
} }
void Window::mousePressEvent(QMouseEvent *event) void Window::mousePressEvent(QMouseEvent *event)
@ -54,7 +65,7 @@ void Window::mouseMoveEvent(QMouseEvent *event)
m_lastPos = event->pos(); m_lastPos = event->pos();
} }
render(); scheduleRender();
} }
void Window::mouseReleaseEvent(QMouseEvent *event) void Window::mouseReleaseEvent(QMouseEvent *event)
@ -66,12 +77,12 @@ void Window::mouseReleaseEvent(QMouseEvent *event)
m_lastPos = QPoint(-1, -1); m_lastPos = QPoint(-1, -1);
} }
render(); scheduleRender();
} }
void Window::exposeEvent(QExposeEvent *) void Window::exposeEvent(QExposeEvent *)
{ {
render(); scheduleRender();
} }
void Window::resizeEvent(QResizeEvent *) void Window::resizeEvent(QResizeEvent *)
@ -106,7 +117,20 @@ void Window::keyPressEvent(QKeyEvent *event)
m_text.append(event->text()); m_text.append(event->text());
break; break;
} }
scheduleRender();
}
void Window::scheduleRender()
{
if (!m_renderTimer)
m_renderTimer = startTimer(1);
}
void Window::timerEvent(QTimerEvent *)
{
render(); render();
killTimer(m_renderTimer);
m_renderTimer = 0;
} }
void Window::render() void Window::render()

View File

@ -5,6 +5,7 @@ class Window : public QWindow
{ {
public: public:
Window(QWindow *parent = 0); Window(QWindow *parent = 0);
Window(QScreen *screen);
protected: protected:
void mousePressEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *);
@ -16,12 +17,17 @@ protected:
void exposeEvent(QExposeEvent *); void exposeEvent(QExposeEvent *);
void resizeEvent(QResizeEvent *); void resizeEvent(QResizeEvent *);
void timerEvent(QTimerEvent *);
private: private:
void render(); void render();
void scheduleRender();
void initialize();
QString m_text; QString m_text;
QImage m_image; QImage m_image;
QPoint m_lastPos; QPoint m_lastPos;
int m_backgroundColorIndex; int m_backgroundColorIndex;
QBackingStore *m_backingStore; QBackingStore *m_backingStore;
int m_renderTimer;
}; };

View File

@ -42,6 +42,7 @@
#include "qbitmap.h" #include "qbitmap.h"
#include "qplatformpixmap_qpa.h" #include "qplatformpixmap_qpa.h"
#include "qimage.h" #include "qimage.h"
#include "qscreen.h"
#include "qvariant.h" #include "qvariant.h"
#include <qpainter.h> #include <qpainter.h>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>

View File

@ -42,6 +42,7 @@
#include <qdebug.h> #include <qdebug.h>
#include "qnativeimage_p.h" #include "qnativeimage_p.h"
#include "qcolormap.h" #include "qcolormap.h"
#include "qscreen.h"
#include "private/qpaintengine_raster_p.h" #include "private/qpaintengine_raster_p.h"
@ -207,7 +208,7 @@ QNativeImage::~QNativeImage()
QImage::Format QNativeImage::systemFormat() QImage::Format QNativeImage::systemFormat()
{ {
return QGuiApplicationPrivate::platformIntegration()->screens().at(0)->format(); return QGuiApplication::primaryScreen()->handle()->format();
} }
#endif // platforms #endif // platforms

View File

@ -43,6 +43,7 @@
#include <qpainter.h> #include <qpainter.h>
#include <qimage.h> #include <qimage.h>
#include <qscreen.h>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
#include <private/qblittable_p.h> #include <private/qblittable_p.h>
@ -98,7 +99,7 @@ void QBlittablePlatformPixmap::resize(int width, int height)
delete m_engine; delete m_engine;
m_engine = 0; m_engine = 0;
#ifdef Q_WS_QPA #ifdef Q_WS_QPA
d = QGuiApplicationPrivate::platformIntegration()->screens().at(0)->depth(); d = QGuiApplication::primaryScreen()->depth();
#endif #endif
w = width; w = width;
h = height; h = height;

View File

@ -40,9 +40,10 @@
****************************************************************************/ ****************************************************************************/
#include <qpixmap.h> #include <qpixmap.h>
#include <qscreen.h>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h) QPixmap QPixmap::grabWindow(WId window, int x, int y, int w, int h)
{ {
return QGuiApplicationPrivate::platformIntegration()->grabWindow(window, x, y, w, h); return QGuiApplication::primaryScreen()->handle()->grabWindow(window, x, y, w, h);
} }

View File

@ -20,6 +20,7 @@ HEADERS += \
kernel/qpalette.h \ kernel/qpalette.h \
kernel/qsessionmanager.h \ kernel/qsessionmanager.h \
kernel/qwindowdefs.h \ kernel/qwindowdefs.h \
kernel/qscreen.h
SOURCES += \ SOURCES += \
kernel/qclipboard.cpp \ kernel/qclipboard.cpp \
@ -33,6 +34,7 @@ SOURCES += \
kernel/qmime.cpp \ kernel/qmime.cpp \
kernel/qpalette.cpp \ kernel/qpalette.cpp \
kernel/qguivariant.cpp \ kernel/qguivariant.cpp \
kernel/qscreen.cpp
qpa { qpa {
HEADERS += \ HEADERS += \

View File

@ -113,7 +113,7 @@ class QShapedPixmapWindow : public QWindow {
QPixmap pixmap; QPixmap pixmap;
public: public:
QShapedPixmapWindow() : QShapedPixmapWindow() :
QWindow(0) QWindow()
{ {
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
// ### Should we set the surface type to raster? // ### Should we set the surface type to raster?

View File

@ -52,6 +52,7 @@
#include <QtCore/qmutex.h> #include <QtCore/qmutex.h>
#include <QtDebug> #include <QtDebug>
#include <qpalette.h> #include <qpalette.h>
#include <qscreen.h>
#include <QtGui/QPlatformIntegration> #include <QtGui/QPlatformIntegration>
#include <QtGui/QGenericPluginFactory> #include <QtGui/QGenericPluginFactory>
@ -103,6 +104,8 @@ QGuiApplicationPrivate *QGuiApplicationPrivate::self = 0;
QClipboard *QGuiApplicationPrivate::qt_clipboard = 0; QClipboard *QGuiApplicationPrivate::qt_clipboard = 0;
#endif #endif
QList<QScreen *> QGuiApplicationPrivate::screen_list;
QWindowList QGuiApplicationPrivate::window_list; QWindowList QGuiApplicationPrivate::window_list;
QWindow *QGuiApplicationPrivate::active_window = 0; QWindow *QGuiApplicationPrivate::active_window = 0;
@ -179,21 +182,27 @@ QWindowList QGuiApplication::topLevelWindows()
return QGuiApplicationPrivate::window_list; return QGuiApplicationPrivate::window_list;
} }
QScreen *QGuiApplication::primaryScreen()
{
if (QGuiApplicationPrivate::screen_list.isEmpty())
return 0;
return QGuiApplicationPrivate::screen_list.at(0);
}
QList<QScreen *> QGuiApplication::screens()
{
return QGuiApplicationPrivate::screen_list;
}
QWindow *QGuiApplication::topLevelAt(const QPoint &pos) QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
{ {
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); QList<QScreen *> screens = QGuiApplication::screens();
QList<QScreen *>::const_iterator screen = screens.constBegin();
QList<QPlatformScreen *> screens = pi->screens(); QList<QScreen *>::const_iterator end = screens.constEnd();
QList<QPlatformScreen *>::const_iterator screen = screens.constBegin();
QList<QPlatformScreen *>::const_iterator end = screens.constEnd();
// The first screen in a virtual environment should know about all top levels
if (pi->isVirtualDesktop())
return (*screen)->topLevelAt(pos);
while (screen != end) { while (screen != end) {
if ((*screen)->geometry().contains(pos)) if ((*screen)->geometry().contains(pos))
return (*screen)->topLevelAt(pos); return (*screen)->handle()->topLevelAt(pos);
++screen; ++screen;
} }
return 0; return 0;

View File

@ -57,6 +57,7 @@ QT_MODULE(Gui)
class QGuiApplicationPrivate; class QGuiApplicationPrivate;
class QPlatformNativeInterface; class QPlatformNativeInterface;
class QPalette; class QPalette;
class QScreen;
#if defined(qApp) #if defined(qApp)
#undef qApp #undef qApp
@ -83,6 +84,8 @@ public:
static QWindow *topLevelAt(const QPoint &pos); static QWindow *topLevelAt(const QPoint &pos);
static QWindow *activeWindow(); static QWindow *activeWindow();
static QScreen *primaryScreen();
static QList<QScreen *> screens();
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
static QCursor *overrideCursor(); static QCursor *overrideCursor();
@ -125,6 +128,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
void fontDatabaseChanged(); void fontDatabaseChanged();
void screenAdded(QScreen *screen);
protected: protected:
bool event(QEvent *); bool event(QEvent *);
@ -140,6 +144,7 @@ private:
friend class QGestureManager; friend class QGestureManager;
#endif #endif
friend class QFontDatabasePrivate; friend class QFontDatabasePrivate;
friend class QPlatformIntegration;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -162,6 +162,7 @@ public:
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
QList<QCursor> cursor_list; QList<QCursor> cursor_list;
#endif #endif
static QList<QScreen *> screen_list;
static QFont *app_font; static QFont *app_font;
private: private:

View File

@ -47,6 +47,7 @@
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QScreen>
#include <QDebug> #include <QDebug>
@ -69,6 +70,7 @@ public:
: qGLContextHandle(0) : qGLContextHandle(0)
, platformGLContext(0) , platformGLContext(0)
, shareContext(0) , shareContext(0)
, screen(0)
{ {
} }
@ -79,8 +81,11 @@ public:
} }
void *qGLContextHandle; void *qGLContextHandle;
void (*qGLContextDeleteFunction)(void *handle); void (*qGLContextDeleteFunction)(void *handle);
QSurfaceFormat requestedFormat;
QPlatformGLContext *platformGLContext; QPlatformGLContext *platformGLContext;
QGuiGLContext *shareContext; QGuiGLContext *shareContext;
QScreen *screen;
static void setCurrentContext(QGuiGLContext *context); static void setCurrentContext(QGuiGLContext *context);
}; };
@ -117,16 +122,74 @@ QPlatformGLContext *QGuiGLContext::handle() const
return d->platformGLContext; return d->platformGLContext;
} }
QPlatformGLContext *QGuiGLContext::shareHandle() const
{
Q_D(const QGuiGLContext);
if (d->shareContext)
return d->shareContext->handle();
return 0;
}
/*! /*!
Creates a new GL context with the given format and shared context. Creates a new GL context instance, you need to call create() before it can be used.
*/ */
QGuiGLContext::QGuiGLContext(const QSurfaceFormat &format, QGuiGLContext *shareContext) QGuiGLContext::QGuiGLContext()
: d_ptr(new QGuiGLContextPrivate()) : d_ptr(new QGuiGLContextPrivate())
{ {
Q_D(QGuiGLContext); Q_D(QGuiGLContext);
QPlatformGLContext *share = shareContext ? shareContext->handle() : 0; d->screen = QGuiApplication::primaryScreen();
}
/*!
Sets the format the GL context should be compatible with. You need to call create() before it takes effect.
*/
void QGuiGLContext::setFormat(const QSurfaceFormat &format)
{
Q_D(QGuiGLContext);
d->requestedFormat = format;
}
/*!
Sets the context to share textures, shaders, and other GL resources with. You need to call create() before it takes effect.
*/
void QGuiGLContext::setShareContext(QGuiGLContext *shareContext)
{
Q_D(QGuiGLContext);
d->shareContext = shareContext; d->shareContext = shareContext;
d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformGLContext(format, share); }
/*!
Sets the screen the GL context should be valid for. You need to call create() before it takes effect.
*/
void QGuiGLContext::setScreen(QScreen *screen)
{
Q_D(QGuiGLContext);
d->screen = screen;
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
}
/*!
Attempts to create the GL context with the desired parameters.
Returns true if the native context was successfully created and is ready to be used.d
*/
bool QGuiGLContext::create()
{
destroy();
Q_D(QGuiGLContext);
d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformGLContext(this);
return d->platformGLContext;
}
void QGuiGLContext::destroy()
{
Q_D(QGuiGLContext);
if (QGuiGLContext::currentContext() == this)
doneCurrent();
delete d->platformGLContext;
d->platformGLContext = 0;
} }
/*! /*!
@ -134,12 +197,12 @@ QGuiGLContext::QGuiGLContext(const QSurfaceFormat &format, QGuiGLContext *shareC
*/ */
QGuiGLContext::~QGuiGLContext() QGuiGLContext::~QGuiGLContext()
{ {
Q_D(QGuiGLContext); destroy();
if (QGuiGLContext::currentContext() == this)
doneCurrent();
delete d->platformGLContext;
} }
/*!
Returns if this context is valid, i.e. has been successfully created.
*/
bool QGuiGLContext::isValid() const bool QGuiGLContext::isValid() const
{ {
Q_D(const QGuiGLContext); Q_D(const QGuiGLContext);
@ -210,18 +273,22 @@ QSurfaceFormat QGuiGLContext::format() const
{ {
Q_D(const QGuiGLContext); Q_D(const QGuiGLContext);
if (!d->platformGLContext) if (!d->platformGLContext)
return QSurfaceFormat(); return d->requestedFormat;
return d->platformGLContext->format(); return d->platformGLContext->format();
} }
QGuiGLContext *QGuiGLContext::shareContext() const QGuiGLContext *QGuiGLContext::shareContext() const
{ {
Q_D(const QGuiGLContext); Q_D(const QGuiGLContext);
if (!d->platformGLContext)
return 0;
return d->shareContext; return d->shareContext;
} }
QScreen *QGuiGLContext::screen() const
{
Q_D(const QGuiGLContext);
return d->screen;
}
/* /*
internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant internal: Needs to have a pointer to qGLContext. But since this is in QtGui we cant
have any type information. have any type information.

View File

@ -61,24 +61,30 @@ class Q_GUI_EXPORT QGuiGLContext
{ {
Q_DECLARE_PRIVATE(QGuiGLContext); Q_DECLARE_PRIVATE(QGuiGLContext);
public: public:
QGuiGLContext(const QSurfaceFormat &format = QSurfaceFormat(), QGuiGLContext *shareContext = 0); QGuiGLContext();
~QGuiGLContext(); ~QGuiGLContext();
void setFormat(const QSurfaceFormat &format);
void setShareContext(QGuiGLContext *shareContext);
void setScreen(QScreen *screen);
bool create();
bool isValid() const; bool isValid() const;
QSurfaceFormat format() const;
QGuiGLContext *shareContext() const;
QScreen *screen() const;
bool makeCurrent(QSurface *surface); bool makeCurrent(QSurface *surface);
void doneCurrent(); void doneCurrent();
void swapBuffers(QSurface *surface); void swapBuffers(QSurface *surface);
void (*getProcAddress(const QByteArray &procName)) (); void (*getProcAddress(const QByteArray &procName)) ();
QSurfaceFormat format() const;
QGuiGLContext *shareContext() const;
static QGuiGLContext *currentContext(); static QGuiGLContext *currentContext();
QPlatformGLContext *handle() const; QPlatformGLContext *handle() const;
QPlatformGLContext *shareHandle() const;
private: private:
QScopedPointer<QGuiGLContextPrivate> d_ptr; QScopedPointer<QGuiGLContextPrivate> d_ptr;
@ -91,6 +97,8 @@ private:
void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)); void setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *));
void deleteQGLContext(); void deleteQGLContext();
void destroy();
Q_DISABLE_COPY(QGuiGLContext); Q_DISABLE_COPY(QGuiGLContext);
}; };

View File

@ -44,21 +44,12 @@
#include <QtGui/QPlatformFontDatabase> #include <QtGui/QPlatformFontDatabase>
#include <QtGui/QPlatformClipboard> #include <QtGui/QPlatformClipboard>
#include <QtGui/QPlatformPrinterSupport> #include <QtGui/QPlatformPrinterSupport>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qpixmap_raster_p.h>
#include <private/qdnd_p.h> #include <private/qdnd_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, int height) const
{
Q_UNUSED(window);
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(width);
Q_UNUSED(height);
return QPixmap();
}
/*! /*!
Accessor for the platform integrations fontdatabase. Accessor for the platform integrations fontdatabase.
@ -177,12 +168,6 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const
*/ */
QPlatformGLContext *QPlatformIntegration::createPlatformGLContext(const QSurfaceFormat &, QPlatformGLContext *) const
{
qWarning("This plugin does not support createPlatformGLContext!");
return 0;
}
/*! /*!
\fn void QPlatformIntegration::moveToScreen(QWindow *window, int screen) \fn void QPlatformIntegration::moveToScreen(QWindow *window, int screen)
@ -211,15 +196,6 @@ QPlatformGLContext *QPlatformIntegration::createPlatformGLContext(const QSurface
Default implementation returns false. Default implementation returns false.
*/ */
/*!
\fn QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, int height) const
This function is called when Qt needs to be able to grab the content of a window.
Returnes the content of the window specified with the WId handle within the boundaries of
QRect(x,y,width,height).
*/
/*! /*!
\fn QAbstractEventDispatcher *createEventDispatcher() const \fn QAbstractEventDispatcher *createEventDispatcher() const
@ -234,6 +210,17 @@ bool QPlatformIntegration::hasCapability(Capability cap) const
return false; return false;
} }
QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
return new QRasterPlatformPixmap(type);
}
QPlatformGLContext *QPlatformIntegration::createPlatformGLContext(QGuiGLContext *context) const
{
qWarning("This plugin does not support createPlatformGLContext!");
return 0;
}
/*! /*!
Returns the platform's printing support. Returns the platform's printing support.
@ -261,4 +248,24 @@ QPlatformInputContext *QPlatformIntegration::inputContext() const
return 0; return 0;
} }
/*!
Should be called by the implementation whenever a new screen is added.
The first screen added will be the primary screen, used for default-created
windows, GL contexts, and other resources unless otherwise specified.
This adds the screen to QGuiApplication::screens(), and emits the
QGuiApplication::screenAdded() signal.
The screen is automatically removed when the QPlatformScreen is destroyed.
*/
void QPlatformIntegration::screenAdded(QPlatformScreen *ps)
{
QScreen *screen = ps ? ps->screen() : 0;
if (screen && !QGuiApplicationPrivate::screen_list.contains(screen)) {
QGuiApplicationPrivate::screen_list << screen;
emit qGuiApp->screenAdded(screen);
}
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -43,7 +43,6 @@
#define QPLATFORMINTEGRATION_H #define QPLATFORMINTEGRATION_H
#include <QtGui/qwindowdefs.h> #include <QtGui/qwindowdefs.h>
#include <QtGui/qplatformpixmap_qpa.h>
#include <QtGui/qplatformscreen_qpa.h> #include <QtGui/qplatformscreen_qpa.h>
#include <QtGui/qsurfaceformat.h> #include <QtGui/qsurfaceformat.h>
@ -78,17 +77,10 @@ public:
virtual bool hasCapability(Capability cap) const; virtual bool hasCapability(Capability cap) const;
// GraphicsSystem functions virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const = 0;
virtual QPlatformWindow *createPlatformWindow(QWindow *window) const = 0; virtual QPlatformWindow *createPlatformWindow(QWindow *window) const = 0;
virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const = 0; virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const = 0;
virtual QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &format, QPlatformGLContext *share) const; virtual QPlatformGLContext *createPlatformGLContext(QGuiGLContext *context) const;
// Window System functions
virtual QList<QPlatformScreen *> screens() const = 0;
virtual void moveToScreen(QWindow *window, int screen) {Q_UNUSED(window); Q_UNUSED(screen);}
virtual bool isVirtualDesktop() { return false; }
virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
// Event dispatcher: // Event dispatcher:
virtual QAbstractEventDispatcher *createEventDispatcher() const = 0; virtual QAbstractEventDispatcher *createEventDispatcher() const = 0;
@ -107,6 +99,9 @@ public:
virtual QPlatformNativeInterface *nativeInterface() const; virtual QPlatformNativeInterface *nativeInterface() const;
virtual QPlatformPrinterSupport *printerSupport() const; virtual QPlatformPrinterSupport *printerSupport() const;
protected:
void screenAdded(QPlatformScreen *screen);
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -43,8 +43,47 @@
#include <QtGui/qguiapplication.h> #include <QtGui/qguiapplication.h>
#include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qplatformintegration_qpa.h> #include <QtGui/qplatformintegration_qpa.h>
#include <QtGui/qscreen.h>
#include <QtGui/qwindow.h> #include <QtGui/qwindow.h>
struct QPlatformScreenPrivate
{
QScreen *screen;
};
QPlatformScreen::QPlatformScreen()
: d_ptr(new QPlatformScreenPrivate)
{
Q_D(QPlatformScreen);
d->screen = new QScreen(this);
}
QPlatformScreen::~QPlatformScreen()
{
Q_D(QPlatformScreen);
QGuiApplicationPrivate::screen_list.removeOne(d->screen);
delete d->screen;
}
/*!
\fn QPixmap QPlatformScreen::grabWindow(WId window, int x, int y, int width, int height) const
This function is called when Qt needs to be able to grab the content of a window.
Returnes the content of the window specified with the WId handle within the boundaries of
QRect(x,y,width,height).
*/
QPixmap QPlatformScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
Q_UNUSED(window);
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(width);
Q_UNUSED(height);
return QPixmap();
}
/*! /*!
Return the given top level window for a given position. Return the given top level window for a given position.
@ -63,6 +102,26 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
return 0; return 0;
} }
/*!
Returns a list of all the platform screens that are part of the same
virtual desktop.
Screens part of the same virtual desktop share a common coordinate system,
and windows can be freely moved between them.
*/
QList<QPlatformScreen *> QPlatformScreen::virtualSiblings() const
{
QList<QPlatformScreen *> list;
list << const_cast<QPlatformScreen *>(this);
return list;
}
QScreen *QPlatformScreen::screen() const
{
Q_D(const QPlatformScreen);
return d->screen;
}
/*! /*!
Reimplement this function in subclass to return the physical size of the Reimplement this function in subclass to return the physical size of the
screen. This function is used by QFont to convert point sizes to pixel screen. This function is used by QFont to convert point sizes to pixel
@ -81,9 +140,9 @@ QSize QPlatformScreen::physicalSize() const
return QSize(width,height); return QSize(width,height);
} }
QPlatformScreen * QPlatformScreen::platformScreenForWindow(const QWindow *) QPlatformScreen * QPlatformScreen::platformScreenForWindow(const QWindow *window)
{ {
return QGuiApplicationPrivate::platformIntegration()->screens().at(0); return window->screen()->handle();
} }
/*! /*!

View File

@ -52,6 +52,7 @@
#include <QtGui/qcursor.h> #include <QtGui/qcursor.h>
#include <QtGui/qimage.h> #include <QtGui/qimage.h>
#include <QtGui/qwindowdefs.h> #include <QtGui/qwindowdefs.h>
#include <QtGui/qplatformpixmap_qpa.h>
QT_BEGIN_HEADER QT_BEGIN_HEADER
@ -59,24 +60,46 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Gui) QT_MODULE(Gui)
class Q_GUI_EXPORT QPlatformScreen : public QObject class QPlatformBackingStore;
class QPlatformGLContext;
class QPlatformScreenPrivate;
class QPlatformWindow;
class QScreen;
class QSurfaceFormat;
class Q_GUI_EXPORT QPlatformScreen
{ {
Q_OBJECT Q_DECLARE_PRIVATE(QPlatformScreen)
public: public:
virtual ~QPlatformScreen() { } QPlatformScreen();
virtual ~QPlatformScreen();
virtual QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
virtual QRect geometry() const = 0; virtual QRect geometry() const = 0;
virtual QRect availableGeometry() const {return geometry();} virtual QRect availableGeometry() const {return geometry();}
virtual int depth() const = 0; virtual int depth() const = 0;
virtual QImage::Format format() const = 0; virtual QImage::Format format() const = 0;
virtual QSize physicalSize() const; virtual QSize physicalSize() const;
//jl: should setDirty be removed.
virtual void setDirty(const QRect &) {}
virtual QWindow *topLevelAt(const QPoint &point) const; virtual QWindow *topLevelAt(const QPoint &point) const;
virtual QList<QPlatformScreen *> virtualSiblings() const;
QScreen *screen() const;
//jl: should this function be in QPlatformIntegration //jl: should this function be in QPlatformIntegration
//jl: maybe screenForWindow is a better name? //jl: maybe screenForWindow is a better name?
static QPlatformScreen *platformScreenForWindow(const QWindow *window); static QPlatformScreen *platformScreenForWindow(const QWindow *window);
virtual QString name() const { return QString(); }
protected:
QScopedPointer<QPlatformScreenPrivate> d_ptr;
private:
Q_DISABLE_COPY(QPlatformScreen)
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

95
src/gui/kernel/qscreen.h Normal file
View File

@ -0,0 +1,95 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QSCREEN_H
#define QSCREEN_H
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
QT_MODULE(Gui)
#include <QList>
class QPlatformScreen;
class QScreenPrivate;
class QWindow;
class Q_GUI_EXPORT QScreen : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QScreen)
public:
QPlatformScreen *handle() const;
QString name() const;
int depth() const;
QSize size() const;
QRect geometry() const;
QSize availableSize() const;
QRect availableGeometry() const;
QList<QScreen *> virtualSiblings() const;
QSize virtualSize() const;
QRect virtualGeometry() const;
QSize availableVirtualSize() const;
QRect availableVirtualGeometry() const;
private:
QScreen(QPlatformScreen *screen);
Q_DISABLE_COPY(QScreen)
friend class QPlatformScreen;
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QSCREEN_H

View File

@ -45,6 +45,7 @@
#include "qsurfaceformat.h" #include "qsurfaceformat.h"
#include "qplatformglcontext_qpa.h" #include "qplatformglcontext_qpa.h"
#include "qguiglcontext_qpa.h" #include "qguiglcontext_qpa.h"
#include "qscreen.h"
#include "qwindow_p.h" #include "qwindow_p.h"
#include "qguiapplication_p.h" #include "qguiapplication_p.h"
@ -55,12 +56,27 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QWindow::QWindow(QScreen *targetScreen)
: QObject(*new QWindowPrivate(), 0)
, QSurface(QSurface::Window)
{
Q_D(QWindow);
d->screen = targetScreen;
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
QGuiApplicationPrivate::window_list.prepend(this);
}
QWindow::QWindow(QWindow *parent) QWindow::QWindow(QWindow *parent)
: QObject(*new QWindowPrivate(), parent) : QObject(*new QWindowPrivate(), parent)
, QSurface(QSurface::Window) , QSurface(QSurface::Window)
{ {
Q_D(QWindow); Q_D(QWindow);
d->parentWindow = parent; d->parentWindow = parent;
if (parent)
d->screen = parent->screen();
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
QGuiApplicationPrivate::window_list.prepend(this); QGuiApplicationPrivate::window_list.prepend(this);
} }
@ -439,6 +455,23 @@ bool QWindow::setMouseGrabEnabled(bool grab)
return false; return false;
} }
QScreen *QWindow::screen() const
{
Q_D(const QWindow);
return d->screen;
}
void QWindow::setScreen(QScreen *newScreen)
{
Q_D(QWindow);
bool wasCreated = d->platformWindow != 0;
if (wasCreated)
destroy();
d->screen = newScreen ? newScreen : QGuiApplication::primaryScreen();
if (wasCreated)
create();
}
void QWindow::showMinimized() void QWindow::showMinimized()
{ {
qDebug() << "unimplemented:" << __FILE__ << __LINE__; qDebug() << "unimplemented:" << __FILE__ << __LINE__;
@ -486,7 +519,6 @@ void QWindow::hideEvent(QHideEvent *)
bool QWindow::event(QEvent *event) bool QWindow::event(QEvent *event)
{ {
Q_D(QWindow);
switch (event->type()) { switch (event->type()) {
case QEvent::MouseMove: case QEvent::MouseMove:
mouseMoveEvent(static_cast<QMouseEvent*>(event)); mouseMoveEvent(static_cast<QMouseEvent*>(event));

View File

@ -71,6 +71,7 @@ class QWheelEvent;
class QPlatformSurface; class QPlatformSurface;
class QPlatformWindow; class QPlatformWindow;
class QBackingStore; class QBackingStore;
class QScreen;
class Q_GUI_EXPORT QSurface class Q_GUI_EXPORT QSurface
{ {
@ -102,7 +103,8 @@ class Q_GUI_EXPORT QWindow : public QObject, public QSurface
public: public:
enum SurfaceType { RasterSurface, OpenGLSurface }; enum SurfaceType { RasterSurface, OpenGLSurface };
QWindow(QWindow *parent = 0); QWindow(QScreen *screen = 0);
QWindow(QWindow *parent);
virtual ~QWindow(); virtual ~QWindow();
void setSurfaceType(SurfaceType surfaceType); void setSurfaceType(SurfaceType surfaceType);
@ -166,6 +168,9 @@ public:
bool setKeyboardGrabEnabled(bool grab); bool setKeyboardGrabEnabled(bool grab);
bool setMouseGrabEnabled(bool grab); bool setMouseGrabEnabled(bool grab);
QScreen *screen() const;
void setScreen(QScreen *screen);
public Q_SLOTS: public Q_SLOTS:
inline void show() { setVisible(true); } inline void show() { setVisible(true); }
inline void hide() { setVisible(false); } inline void hide() { setVisible(false); }

View File

@ -68,6 +68,7 @@ public:
, maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX) , maximumSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX)
, modality(Qt::NonModal) , modality(Qt::NonModal)
, transientParent(0) , transientParent(0)
, screen(0)
{ {
isWindow = true; isWindow = true;
} }
@ -93,6 +94,7 @@ public:
Qt::WindowModality modality; Qt::WindowModality modality;
QPointer<QWindow> transientParent; QPointer<QWindow> transientParent;
QScreen *screen;
}; };

View File

@ -43,6 +43,7 @@
#include <qwindow.h> #include <qwindow.h>
#include <qpixmap.h> #include <qpixmap.h>
#include <qplatformbackingstore_qpa.h> #include <qplatformbackingstore_qpa.h>
#include <qscreen.h>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
#include <private/qwindow_p.h> #include <private/qwindow_p.h>

View File

@ -42,7 +42,7 @@
#include "qcolormap.h" #include "qcolormap.h"
#include "qcolor.h" #include "qcolor.h"
#include "qpaintdevice.h" #include "qpaintdevice.h"
#include "private/qguiapplication_p.h" #include "qscreen.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -66,10 +66,7 @@ void QColormap::initialize()
{ {
screenMap = new QColormapPrivate; screenMap = new QColormapPrivate;
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); screenMap->depth = QGuiApplication::primaryScreen()->depth();
QList<QPlatformScreen*> screens = pi->screens();
screenMap->depth = screens.at(0)->depth();
if (screenMap->depth < 8) { if (screenMap->depth < 8) {
screenMap->mode = QColormap::Indexed; screenMap->mode = QColormap::Indexed;
screenMap->numcolors = 256; screenMap->numcolors = 256;

View File

@ -50,6 +50,7 @@
#include "qdatastream.h" #include "qdatastream.h"
#include "qguiapplication.h" #include "qguiapplication.h"
#include "qstringlist.h" #include "qstringlist.h"
#include "qscreen.h"
#include "qthread.h" #include "qthread.h"
#include "qthreadstorage.h" #include "qthreadstorage.h"
@ -167,11 +168,10 @@ Q_GUI_EXPORT int qt_defaultDpiX()
extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp extern float qt_mac_defaultDpi_x(); //qpaintdevice_mac.cpp
dpi = qt_mac_defaultDpi_x(); dpi = qt_mac_defaultDpi_x();
#elif defined(Q_WS_QPA) #elif defined(Q_WS_QPA)
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); QScreen *screen = QGuiApplication::primaryScreen();
if (pi) { if (screen) {
QPlatformScreen *screen = pi->screens().at(0);
const QSize screenSize = screen->geometry().size(); const QSize screenSize = screen->geometry().size();
const QSize physicalSize = screen->physicalSize(); const QSize physicalSize = screen->handle()->physicalSize();
dpi = qRound(screenSize.width() / (physicalSize.width() / qreal(25.4))); dpi = qRound(screenSize.width() / (physicalSize.width() / qreal(25.4)));
} else { } else {
//PI has not been initialised, or it is being initialised. Give a default dpi //PI has not been initialised, or it is being initialised. Give a default dpi
@ -198,11 +198,10 @@ Q_GUI_EXPORT int qt_defaultDpiY()
extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp extern float qt_mac_defaultDpi_y(); //qpaintdevice_mac.cpp
dpi = qt_mac_defaultDpi_y(); dpi = qt_mac_defaultDpi_y();
#elif defined(Q_WS_QPA) #elif defined(Q_WS_QPA)
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); QScreen *screen = QGuiApplication::primaryScreen();
if (pi) { if (screen) {
QPlatformScreen *screen = pi->screens().at(0);
const QSize screenSize = screen->geometry().size(); const QSize screenSize = screen->geometry().size();
const QSize physicalSize = screen->physicalSize(); const QSize physicalSize = screen->handle()->physicalSize();
dpi = qRound(screenSize.height() / (physicalSize.height() / qreal(25.4))); dpi = qRound(screenSize.height() / (physicalSize.height() / qreal(25.4)));
} else { } else {
//PI has not been initialised, or it is being initialised. Give a default dpi //PI has not been initialised, or it is being initialised. Give a default dpi

View File

@ -150,13 +150,15 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
delete d->guiGlContext; delete d->guiGlContext;
QGuiGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0; QGuiGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0;
d->guiGlContext = new QGuiGLContext(winFormat, shareGlContext); d->guiGlContext = new QGuiGLContext;
d->guiGlContext->setFormat(winFormat);
d->guiGlContext->setShareContext(shareGlContext);
d->valid = d->guiGlContext->create();
if (d->valid)
d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext);
d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format()); d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format());
d->valid = d->guiGlContext->isValid();
if (d->valid) {
d->guiGlContext->setQGLContextHandle(this,qDeleteQGLContext);
}
d->setupSharing(); d->setupSharing();
} }
@ -300,6 +302,7 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
d->window->create(); d->window->create();
d->context = new QGuiGLContext; d->context = new QGuiGLContext;
d->context->create();
d->context->makeCurrent(d->window); d->context->makeCurrent(d->window);
} }

View File

@ -67,8 +67,6 @@ QEventDispatcherQPA::~QEventDispatcherQPA()
bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags) bool QEventDispatcherQPA::processEvents(QEventLoop::ProcessEventsFlags flags)
{ {
Q_D(QEventDispatcherQPA);
bool didSendEvents = QWindowSystemInterface::sendWindowSystemEvents(this, flags); bool didSendEvents = QWindowSystemInterface::sendWindowSystemEvents(this, flags);
if (QEventDispatcherUNIX::processEvents(flags)) { if (QEventDispatcherUNIX::processEvents(flags)) {

View File

@ -76,19 +76,15 @@ public:
~QCocoaIntegration(); ~QCocoaIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const; bool hasCapability(QPlatformIntegration::Capability cap) const;
QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformWindow *createPlatformWindow(QWindow *window) const;
QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const; QPlatformGLContext *createPlatformGLContext(QGuiGLContext *context) const;
QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const;
QAbstractEventDispatcher *createEventDispatcher() const; QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const { return mScreens; }
QPlatformFontDatabase *fontDatabase() const; QPlatformFontDatabase *fontDatabase() const;
QPlatformNativeInterface *nativeInterface() const; QPlatformNativeInterface *nativeInterface() const;
private: private:
QList<QPlatformScreen *> mScreens;
QPlatformFontDatabase *mFontDb; QPlatformFontDatabase *mFontDb;
QCocoaAutoReleasePool *mPool; QCocoaAutoReleasePool *mPool;

View File

@ -47,7 +47,6 @@
#include "qcocoaeventdispatcher.h" #include "qcocoaeventdispatcher.h"
#include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h> #include <QtPlatformSupport/private/qbasicunixfontdatabase_p.h>
#include <private/qpixmap_raster_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -83,7 +82,7 @@ QCocoaIntegration::QCocoaIntegration()
NSArray *screens = [NSScreen screens]; NSArray *screens = [NSScreen screens];
for (uint i = 0; i < [screens count]; i++) { for (uint i = 0; i < [screens count]; i++) {
QCocoaScreen *screen = new QCocoaScreen(i); QCocoaScreen *screen = new QCocoaScreen(i);
mScreens.append(screen); screenAdded(screen);
} }
} }
@ -103,19 +102,14 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
QPlatformPixmap *QCocoaIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
return new QRasterPlatformPixmap(type);
}
QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const
{ {
return new QCocoaWindow(window); return new QCocoaWindow(window);
} }
QPlatformGLContext *QCocoaIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const QPlatformGLContext *QCocoaIntegration::createPlatformGLContext(QGuiGLContext *context) const
{ {
return new QCocoaGLContext(glFormat, share); return new QCocoaGLContext(context->format(), context->shareHandle());
} }
QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *window) const QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *window) const

View File

@ -41,6 +41,7 @@
#include "qminimalbackingstore.h" #include "qminimalbackingstore.h"
#include "qscreen.h"
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
#include <private/qguiapplication_p.h> #include <private/qguiapplication_p.h>
@ -77,7 +78,7 @@ void QMinimalBackingStore::flush(QWindow *window, const QRegion &region, const Q
void QMinimalBackingStore::resize(const QSize &size, const QRegion &) void QMinimalBackingStore::resize(const QSize &size, const QRegion &)
{ {
//qDebug() << "QMinimalBackingStore::setGeometry:" << (long)this << rect; //qDebug() << "QMinimalBackingStore::setGeometry:" << (long)this << rect;
QImage::Format format = QGuiApplicationPrivate::platformIntegration()->screens().first()->format(); QImage::Format format = QGuiApplication::primaryScreen()->handle()->format();
if (mImage.size() != size) if (mImage.size() != size)
mImage = QImage(size, format); mImage = QImage(size, format);
} }

View File

@ -58,7 +58,7 @@ QMinimalIntegration::QMinimalIntegration()
mPrimaryScreen->mDepth = 32; mPrimaryScreen->mDepth = 32;
mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied; mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied;
mScreens.append(mPrimaryScreen); screenAdded(mPrimaryScreen);
} }
bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) const bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@ -69,11 +69,6 @@ bool QMinimalIntegration::hasCapability(QPlatformIntegration::Capability cap) co
} }
} }
QPlatformPixmap *QMinimalIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
return new QRasterPlatformPixmap(type);
}
QPlatformWindow *QMinimalIntegration::createPlatformWindow(QWindow *window) const QPlatformWindow *QMinimalIntegration::createPlatformWindow(QWindow *window) const
{ {
Q_UNUSED(window); Q_UNUSED(window);

View File

@ -71,15 +71,10 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const; bool hasCapability(QPlatformIntegration::Capability cap) const;
QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformWindow *createPlatformWindow(QWindow *window) const;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
QAbstractEventDispatcher *createEventDispatcher() const; QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const { return mScreens; }
private:
QList<QPlatformScreen *> mScreens;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -54,8 +54,6 @@
#include <QtGui/QPlatformCursor> #include <QtGui/QPlatformCursor>
#include <QtGui/QSurfaceFormat> #include <QtGui/QSurfaceFormat>
#include <QtGui/private/qpixmap_raster_p.h>
#ifdef QT_WAYLAND_GL_SUPPORT #ifdef QT_WAYLAND_GL_SUPPORT
#include "gl_integration/qwaylandglintegration.h" #include "gl_integration/qwaylandglintegration.h"
#endif #endif
@ -92,11 +90,6 @@ bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) co
} }
} }
QPlatformPixmap *QWaylandIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
return new QRasterPlatformPixmap(type);
}
QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const
{ {
#ifdef QT_WAYLAND_GL_SUPPORT #ifdef QT_WAYLAND_GL_SUPPORT

View File

@ -56,7 +56,6 @@ public:
QWaylandIntegration(); QWaylandIntegration();
bool hasCapability(QPlatformIntegration::Capability cap) const; bool hasCapability(QPlatformIntegration::Capability cap) const;
QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformWindow *createPlatformWindow(QWindow *window) const;
QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const; QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;

View File

@ -44,6 +44,7 @@
#include "qwaylanddisplay.h" #include "qwaylanddisplay.h"
#include "qwaylandwindow.h" #include "qwaylandwindow.h"
#include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QScreen>
void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{ {
@ -64,9 +65,9 @@ QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWindow(QWindow *wind
QWaylandScreen *screen; QWaylandScreen *screen;
if (window) { if (window) {
screen = static_cast<QWaylandScreen *>(QPlatformScreen::platformScreenForWindow(window)); screen = static_cast<QWaylandScreen *>(window->screen()->handle());
} else { } else {
screen = static_cast<QWaylandScreen *>(QGuiApplicationPrivate::platformIntegration()->screens()[0]); screen = static_cast<QWaylandScreen *>(QGuiApplication::primaryScreen()->handle());
} }
return screen; return screen;
} }

View File

@ -53,7 +53,6 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output
, mFormat(QImage::Format_ARGB32_Premultiplied) , mFormat(QImage::Format_ARGB32_Premultiplied)
, mWaylandCursor(new QWaylandCursor(this)) , mWaylandCursor(new QWaylandCursor(this))
{ {
moveToThread(waylandDisplay->thread());
} }
QWaylandScreen::~QWaylandScreen() QWaylandScreen::~QWaylandScreen()

View File

@ -58,11 +58,10 @@ QStringList QXcbIntegrationPlugin::keys() const
return list; return list;
} }
QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& paramList) QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters)
{ {
Q_UNUSED(paramList);
if (system.toLower() == "xcb") if (system.toLower() == "xcb")
return new QXcbIntegration; return new QXcbIntegration(parameters);
return 0; return 0;
} }

View File

@ -56,6 +56,7 @@
#include <qdebug.h> #include <qdebug.h>
#include <qpainter.h> #include <qpainter.h>
#include <qscreen.h>
class QXcbShmImage : public QXcbObject class QXcbShmImage : public QXcbObject
{ {
@ -213,7 +214,7 @@ QXcbBackingStore::QXcbBackingStore(QWindow *window)
, m_image(0) , m_image(0)
, m_syncingResize(false) , m_syncingResize(false)
{ {
QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWindow(window)); QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle());
setConnection(screen->connection()); setConnection(screen->connection());
} }
@ -280,7 +281,7 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &)
Q_XCB_NOOP(connection()); Q_XCB_NOOP(connection());
QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWindow(window())); QXcbScreen *screen = static_cast<QXcbScreen *>(window()->screen()->handle());
QXcbWindow* win = static_cast<QXcbWindow *>(window()->handle()); QXcbWindow* win = static_cast<QXcbWindow *>(window()->handle());
delete m_image; delete m_image;

View File

@ -109,8 +109,11 @@ QXcbConnection::QXcbConnection(const char *displayName)
#endif //XCB_USE_EGL #endif //XCB_USE_EGL
#else #else
m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen); m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreen);
#endif //XCB_USE_XLIB #endif //XCB_USE_XLIB
if (m_connection)
printf("Successfully connected to display %s\n", m_displayName.constData());
xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id); xcb_prefetch_extension_data (m_connection, &xcb_xfixes_id);
m_setup = xcb_get_setup(xcb_connection()); m_setup = xcb_get_setup(xcb_connection());

View File

@ -47,14 +47,11 @@
#include "qxcbnativeinterface.h" #include "qxcbnativeinterface.h"
#include "qxcbclipboard.h" #include "qxcbclipboard.h"
#include "qxcbdrag.h" #include "qxcbdrag.h"
#include "qxcbimage.h"
#include <QtPlatformSupport/private/qgenericunixprintersupport_p.h> #include <QtPlatformSupport/private/qgenericunixprintersupport_p.h>
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <private/qpixmap_raster_p.h>
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> #include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> #include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
@ -64,6 +61,11 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#endif #endif
#define XCB_USE_IBUS
#if defined(XCB_USE_IBUS)
#include "QtPlatformSupport/qibusplatforminputcontext.h"
#endif
#if defined(XCB_USE_GLX) #if defined(XCB_USE_GLX)
#include "qglxintegration.h" #include "qglxintegration.h"
#elif defined(XCB_USE_EGL) #elif defined(XCB_USE_EGL)
@ -71,16 +73,23 @@
#include <QtPlatformSupport/private/qeglplatformcontext_p.h> #include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#endif #endif
#define XCB_USE_IBUS #include <QtGui/QGuiGLContext>
#if defined(XCB_USE_IBUS) #include <QtGui/QScreen>
#include "QtPlatformSupport/qibusplatforminputcontext.h"
#endif
QXcbIntegration::QXcbIntegration() QXcbIntegration::QXcbIntegration(const QStringList &parameters)
: m_connection(new QXcbConnection), m_printerSupport(new QGenericUnixPrinterSupport) : m_printerSupport(new QGenericUnixPrinterSupport)
{ {
foreach (QXcbScreen *screen, m_connection->screens()) m_connections << new QXcbConnection;
m_screens << screen;
for (int i = 0; i < parameters.size() - 1; i += 2) {
qDebug() << parameters.at(i) << parameters.at(i+1);
QString display = parameters.at(i) + ':' + parameters.at(i+1);
m_connections << new QXcbConnection(display.toAscii().constData());
}
foreach (QXcbConnection *connection, m_connections)
foreach (QXcbScreen *screen, connection->screens())
screenAdded(screen);
m_fontDatabase = new QGenericUnixFontDatabase(); m_fontDatabase = new QGenericUnixFontDatabase();
m_nativeInterface = new QXcbNativeInterface; m_nativeInterface = new QXcbNativeInterface;
@ -90,21 +99,7 @@ QXcbIntegration::QXcbIntegration()
QXcbIntegration::~QXcbIntegration() QXcbIntegration::~QXcbIntegration()
{ {
delete m_connection; qDeleteAll(m_connections);
}
bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
case OpenGL: return hasOpenGL();
default: return QPlatformIntegration::hasCapability(cap);
}
}
QPlatformPixmap *QXcbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
return new QRasterPlatformPixmap(type);
} }
QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
@ -128,14 +123,15 @@ public:
}; };
#endif #endif
QPlatformGLContext *QXcbIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const QPlatformGLContext *QXcbIntegration::createPlatformGLContext(QGuiGLContext *context) const
{ {
QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
#if defined(XCB_USE_GLX) #if defined(XCB_USE_GLX)
return new QGLXContext(static_cast<QXcbScreen *>(m_screens.at(0)), glFormat, share); return new QGLXContext(screen, context->format(), context->shareHandle());
#elif defined(XCB_USE_EGL) #elif defined(XCB_USE_EGL)
return new QEGLXcbPlatformContext(glFormat, share, m_connection->egl_display()); return new QEGLXcbPlatformContext(context->format(), context->shareHandle(), screen->connection()->egl_display());
#elif defined(XCB_USE_DRI2) #elif defined(XCB_USE_DRI2)
return new QDri2Context(glFormat, share); return new QDri2Context(context->format(), context->shareHandle());
#endif #endif
} }
@ -144,10 +140,21 @@ QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *wind
return new QXcbBackingStore(window); return new QXcbBackingStore(window);
} }
bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
case OpenGL: return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const
{ {
QAbstractEventDispatcher *eventDispatcher = createUnixEventDispatcher(); QAbstractEventDispatcher *eventDispatcher = createUnixEventDispatcher();
m_connection->setEventDispatcher(eventDispatcher);
foreach (QXcbConnection *connection, m_connections)
connection->setEventDispatcher(eventDispatcher);
#ifdef XCB_USE_IBUS #ifdef XCB_USE_IBUS
// A bit hacky to do this here, but we need an eventloop before we can instantiate // A bit hacky to do this here, but we need an eventloop before we can instantiate
// the input context. // the input context.
@ -156,161 +163,17 @@ QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const
return eventDispatcher; return eventDispatcher;
} }
QList<QPlatformScreen *> QXcbIntegration::screens() const
{
return m_screens;
}
void QXcbIntegration::moveToScreen(QWindow *window, int screen) void QXcbIntegration::moveToScreen(QWindow *window, int screen)
{ {
Q_UNUSED(window); Q_UNUSED(window);
Q_UNUSED(screen); Q_UNUSED(screen);
} }
bool QXcbIntegration::isVirtualDesktop()
{
return false;
}
QPlatformFontDatabase *QXcbIntegration::fontDatabase() const QPlatformFontDatabase *QXcbIntegration::fontDatabase() const
{ {
return m_fontDatabase; return m_fontDatabase;
} }
QPixmap QXcbIntegration::grabWindow(WId window, int x, int y, int width, int height) const
{
if (width == 0 || height == 0)
return QPixmap();
xcb_connection_t *connection = m_connection->xcb_connection();
xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry(connection, window);
xcb_generic_error_t *error;
xcb_get_geometry_reply_t *reply =
xcb_get_geometry_reply(connection, geometry_cookie, &error);
if (!reply) {
if (error) {
m_connection->handleXcbError(error);
free(error);
}
return QPixmap();
}
if (width < 0)
width = reply->width - x;
if (height < 0)
height = reply->height - y;
// TODO: handle multiple screens
QXcbScreen *screen = m_connection->screens().at(0);
xcb_window_t root = screen->root();
geometry_cookie = xcb_get_geometry(connection, root);
xcb_get_geometry_reply_t *root_reply =
xcb_get_geometry_reply(connection, geometry_cookie, &error);
if (!root_reply) {
if (error) {
m_connection->handleXcbError(error);
free(error);
}
free(reply);
return QPixmap();
}
if (reply->depth == root_reply->depth) {
// if the depth of the specified window and the root window are the
// same, grab pixels from the root window (so that we get the any
// overlapping windows and window manager frames)
// map x and y to the root window
xcb_translate_coordinates_cookie_t translate_cookie =
xcb_translate_coordinates(connection, window, root, x, y);
xcb_translate_coordinates_reply_t *translate_reply =
xcb_translate_coordinates_reply(connection, translate_cookie, &error);
if (!translate_reply) {
if (error) {
m_connection->handleXcbError(error);
free(error);
}
free(reply);
free(root_reply);
return QPixmap();
}
x = translate_reply->dst_x;
y = translate_reply->dst_y;
window = root;
free(translate_reply);
free(reply);
reply = root_reply;
} else {
free(root_reply);
root_reply = 0;
}
xcb_get_window_attributes_reply_t *attributes_reply =
xcb_get_window_attributes_reply(connection, xcb_get_window_attributes(connection, window), &error);
if (!attributes_reply) {
if (error) {
m_connection->handleXcbError(error);
free(error);
}
free(reply);
return QPixmap();
}
const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual);
free(attributes_reply);
xcb_pixmap_t pixmap = xcb_generate_id(connection);
error = xcb_request_check(connection, xcb_create_pixmap_checked(connection, reply->depth, pixmap, window, width, height));
if (error) {
m_connection->handleXcbError(error);
free(error);
}
uint32_t gc_value_mask = XCB_GC_SUBWINDOW_MODE;
uint32_t gc_value_list[] = { XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS };
xcb_gcontext_t gc = xcb_generate_id(connection);
xcb_create_gc(connection, gc, pixmap, gc_value_mask, gc_value_list);
error = xcb_request_check(connection, xcb_copy_area_checked(connection, window, pixmap, gc, x, y, 0, 0, width, height));
if (error) {
m_connection->handleXcbError(error);
free(error);
}
QPixmap result = qt_xcb_pixmapFromXPixmap(m_connection, pixmap, width, height, reply->depth, visual);
free(reply);
xcb_free_gc(connection, gc);
xcb_free_pixmap(connection, pixmap);
return result;
}
bool QXcbIntegration::hasOpenGL() const
{
#if defined(XCB_USE_GLX)
return true;
#elif defined(XCB_USE_EGL)
return m_connection->hasEgl();
#elif defined(XCB_USE_DRI2)
if (m_connection->hasSupportForDri2()) {
return true;
}
#endif
return false;
}
QPlatformNativeInterface * QXcbIntegration::nativeInterface() const QPlatformNativeInterface * QXcbIntegration::nativeInterface() const
{ {
return m_nativeInterface; return m_nativeInterface;
@ -323,12 +186,12 @@ QPlatformPrinterSupport *QXcbIntegration::printerSupport() const
QPlatformClipboard *QXcbIntegration::clipboard() const QPlatformClipboard *QXcbIntegration::clipboard() const
{ {
return m_connection->clipboard(); return m_connections.at(0)->clipboard();
} }
QPlatformDrag *QXcbIntegration::drag() const QPlatformDrag *QXcbIntegration::drag() const
{ {
return m_connection->drag(); return m_connections.at(0)->drag();
} }
QPlatformInputContext *QXcbIntegration::inputContext() const QPlatformInputContext *QXcbIntegration::inputContext() const

View File

@ -53,20 +53,17 @@ class QAbstractEventDispatcher;
class QXcbIntegration : public QPlatformIntegration class QXcbIntegration : public QPlatformIntegration
{ {
public: public:
QXcbIntegration(); QXcbIntegration(const QStringList &parameters);
~QXcbIntegration(); ~QXcbIntegration();
bool hasCapability(Capability cap) const;
QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformWindow *createPlatformWindow(QWindow *window) const;
QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *share) const; QPlatformGLContext *createPlatformGLContext(QGuiGLContext *context) const;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
bool hasCapability(Capability cap) const;
QAbstractEventDispatcher *createEventDispatcher() const; QAbstractEventDispatcher *createEventDispatcher() const;
QList<QPlatformScreen *> screens() const;
void moveToScreen(QWindow *window, int screen); void moveToScreen(QWindow *window, int screen);
bool isVirtualDesktop();
QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
QPlatformFontDatabase *fontDatabase() const; QPlatformFontDatabase *fontDatabase() const;
@ -79,9 +76,7 @@ public:
QPlatformInputContext *inputContext() const; QPlatformInputContext *inputContext() const;
private: private:
bool hasOpenGL() const; QList<QXcbConnection *> m_connections;
QList<QPlatformScreen *> m_screens;
QXcbConnection *m_connection;
QPlatformFontDatabase *m_fontDatabase; QPlatformFontDatabase *m_fontDatabase;
QPlatformNativeInterface *m_nativeInterface; QPlatformNativeInterface *m_nativeInterface;

View File

@ -49,6 +49,7 @@
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtGui/qguiglcontext_qpa.h> #include <QtGui/qguiglcontext_qpa.h>
#include <QtGui/qscreen.h>
#if defined(XCB_USE_EGL) #if defined(XCB_USE_EGL)
#include "QtPlatformSupport/private/qeglplatformcontext_p.h" #include "QtPlatformSupport/private/qeglplatformcontext_p.h"
@ -119,9 +120,9 @@ QXcbScreen *QXcbNativeInterface::qPlatformScreenForWindow(QWindow *window)
{ {
QXcbScreen *screen; QXcbScreen *screen;
if (window) { if (window) {
screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWindow(window)); screen = static_cast<QXcbScreen *>(window->screen()->handle());
} else { } else {
screen = static_cast<QXcbScreen *>(QGuiApplicationPrivate::platformIntegration()->screens()[0]); screen = static_cast<QXcbScreen *>(QGuiApplication::primaryScreen()->handle());
} }
return screen; return screen;
} }

View File

@ -42,6 +42,7 @@
#include "qxcbscreen.h" #include "qxcbscreen.h"
#include "qxcbwindow.h" #include "qxcbwindow.h"
#include "qxcbcursor.h" #include "qxcbcursor.h"
#include "qxcbimage.h"
#include <stdio.h> #include <stdio.h>
@ -150,6 +151,7 @@ QXcbScreen::~QXcbScreen()
delete m_cursor; delete m_cursor;
} }
QWindow *QXcbScreen::topLevelAt(const QPoint &p) const QWindow *QXcbScreen::topLevelAt(const QPoint &p) const
{ {
xcb_window_t root = m_screen->root; xcb_window_t root = m_screen->root;
@ -227,3 +229,126 @@ int QXcbScreen::screenNumber() const
{ {
return m_number; return m_number;
} }
QPixmap QXcbScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
if (width == 0 || height == 0)
return QPixmap();
xcb_get_geometry_cookie_t geometry_cookie = xcb_get_geometry(xcb_connection(), window);
xcb_generic_error_t *error;
xcb_get_geometry_reply_t *reply =
xcb_get_geometry_reply(xcb_connection(), geometry_cookie, &error);
if (!reply) {
if (error) {
connection()->handleXcbError(error);
free(error);
}
return QPixmap();
}
if (width < 0)
width = reply->width - x;
if (height < 0)
height = reply->height - y;
// TODO: handle multiple screens
QXcbScreen *screen = const_cast<QXcbScreen *>(this);
xcb_window_t root = screen->root();
geometry_cookie = xcb_get_geometry(xcb_connection(), root);
xcb_get_geometry_reply_t *root_reply =
xcb_get_geometry_reply(xcb_connection(), geometry_cookie, &error);
if (!root_reply) {
if (error) {
connection()->handleXcbError(error);
free(error);
}
free(reply);
return QPixmap();
}
if (reply->depth == root_reply->depth) {
// if the depth of the specified window and the root window are the
// same, grab pixels from the root window (so that we get the any
// overlapping windows and window manager frames)
// map x and y to the root window
xcb_translate_coordinates_cookie_t translate_cookie =
xcb_translate_coordinates(xcb_connection(), window, root, x, y);
xcb_translate_coordinates_reply_t *translate_reply =
xcb_translate_coordinates_reply(xcb_connection(), translate_cookie, &error);
if (!translate_reply) {
if (error) {
connection()->handleXcbError(error);
free(error);
}
free(reply);
free(root_reply);
return QPixmap();
}
x = translate_reply->dst_x;
y = translate_reply->dst_y;
window = root;
free(translate_reply);
free(reply);
reply = root_reply;
} else {
free(root_reply);
root_reply = 0;
}
xcb_get_window_attributes_reply_t *attributes_reply =
xcb_get_window_attributes_reply(xcb_connection(), xcb_get_window_attributes(xcb_connection(), window), &error);
if (!attributes_reply) {
if (error) {
connection()->handleXcbError(error);
free(error);
}
free(reply);
return QPixmap();
}
const xcb_visualtype_t *visual = screen->visualForId(attributes_reply->visual);
free(attributes_reply);
xcb_pixmap_t pixmap = xcb_generate_id(xcb_connection());
error = xcb_request_check(xcb_connection(), xcb_create_pixmap_checked(xcb_connection(), reply->depth, pixmap, window, width, height));
if (error) {
connection()->handleXcbError(error);
free(error);
}
uint32_t gc_value_mask = XCB_GC_SUBWINDOW_MODE;
uint32_t gc_value_list[] = { XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS };
xcb_gcontext_t gc = xcb_generate_id(xcb_connection());
xcb_create_gc(xcb_connection(), gc, pixmap, gc_value_mask, gc_value_list);
error = xcb_request_check(xcb_connection(), xcb_copy_area_checked(xcb_connection(), window, pixmap, gc, x, y, 0, 0, width, height));
if (error) {
connection()->handleXcbError(error);
free(error);
}
QPixmap result = qt_xcb_pixmapFromXPixmap(connection(), pixmap, width, height, reply->depth, visual);
free(reply);
xcb_free_gc(xcb_connection(), gc);
xcb_free_pixmap(xcb_connection(), pixmap);
return result;
}
QString QXcbScreen::name() const
{
return connection()->displayName() + QLatin1String(".") + QString::number(screenNumber());
}

View File

@ -58,6 +58,8 @@ public:
QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number); QXcbScreen(QXcbConnection *connection, xcb_screen_t *screen, int number);
~QXcbScreen(); ~QXcbScreen();
QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
QWindow *topLevelAt(const QPoint &point) const; QWindow *topLevelAt(const QPoint &point) const;
QRect geometry() const; QRect geometry() const;
@ -77,6 +79,8 @@ public:
const xcb_visualtype_t *visualForId(xcb_visualid_t) const; const xcb_visualtype_t *visualForId(xcb_visualid_t) const;
QString name() const;
private: private:
xcb_screen_t *m_screen; xcb_screen_t *m_screen;
int m_number; int m_number;

View File

@ -42,6 +42,7 @@
#include "qxcbwindow.h" #include "qxcbwindow.h"
#include <QtDebug> #include <QtDebug>
#include <QScreen>
#include "qxcbconnection.h" #include "qxcbconnection.h"
#include "qxcbscreen.h" #include "qxcbscreen.h"
@ -102,7 +103,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_eglSurface(0) , m_eglSurface(0)
#endif #endif
{ {
m_screen = static_cast<QXcbScreen *>(QGuiApplicationPrivate::platformIntegration()->screens().at(0)); m_screen = static_cast<QXcbScreen *>(window->screen()->handle());
setConnection(m_screen->connection()); setConnection(m_screen->connection());

View File

@ -45,6 +45,7 @@
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
#include "private/qcursor_p.h" #include "private/qcursor_p.h"
#endif #endif
#include "qscreen.h"
#include "private/qwidget_p.h" #include "private/qwidget_p.h"
#include "private/qevent_p.h" #include "private/qevent_p.h"
@ -384,21 +385,13 @@ bool QApplication::isEffectEnabled(Qt::UIEffect effect)
QWidget *QApplication::topLevelAt(const QPoint &pos) QWidget *QApplication::topLevelAt(const QPoint &pos)
{ {
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); QList<QScreen *> screens = QGuiApplication::screens();
QList<QScreen *>::const_iterator screen = screens.constBegin();
QList<QPlatformScreen *> screens = pi->screens(); QList<QScreen *>::const_iterator end = screens.constEnd();
QList<QPlatformScreen *>::const_iterator screen = screens.constBegin();
QList<QPlatformScreen *>::const_iterator end = screens.constEnd();
// The first screen in a virtual environment should know about all top levels
if (pi->isVirtualDesktop()) {
QWidgetWindow *w = qobject_cast<QWidgetWindow *>((*screen)->topLevelAt(pos));
return w ? w->widget() : 0;
}
while (screen != end) { while (screen != end) {
if ((*screen)->geometry().contains(pos)) { if ((*screen)->geometry().contains(pos)) {
QWidgetWindow *w = qobject_cast<QWidgetWindow *>((*screen)->topLevelAt(pos)); QWidgetWindow *w = qobject_cast<QWidgetWindow *>((*screen)->handle()->topLevelAt(pos));
return w ? w->widget() : 0; return w ? w->widget() : 0;
} }
++screen; ++screen;

View File

@ -40,6 +40,7 @@
****************************************************************************/ ****************************************************************************/
#include "qdesktopwidget.h" #include "qdesktopwidget.h"
#include "qscreen.h"
#include "private/qapplication_p.h" #include "private/qapplication_p.h"
#include <QWidget> #include <QWidget>
#include "private/qwidget_p.h" #include "private/qwidget_p.h"
@ -51,7 +52,7 @@ QT_USE_NAMESPACE
void QDesktopWidgetPrivate::updateScreenList() void QDesktopWidgetPrivate::updateScreenList()
{ {
Q_Q(QDesktopWidget); Q_Q(QDesktopWidget);
QList<QPlatformScreen *> screenList = QGuiApplicationPrivate::platformIntegration()->screens(); QList<QScreen *> screenList = QGuiApplication::screens();
int targetLength = screenList.length(); int targetLength = screenList.length();
int currentLength = screens.length(); int currentLength = screens.length();
@ -97,7 +98,7 @@ QDesktopWidget::~QDesktopWidget()
bool QDesktopWidget::isVirtualDesktop() const bool QDesktopWidget::isVirtualDesktop() const
{ {
return QGuiApplicationPrivate::platformIntegration()->isVirtualDesktop(); return QGuiApplication::primaryScreen()->virtualSiblings().size() > 1;
} }
int QDesktopWidget::primaryScreen() const int QDesktopWidget::primaryScreen() const
@ -107,8 +108,7 @@ int QDesktopWidget::primaryScreen() const
int QDesktopWidget::numScreens() const int QDesktopWidget::numScreens() const
{ {
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); return qMax(QGuiApplication::screens().size(), 1);
return qMax(pi->screens().size(), 1);
} }
QWidget *QDesktopWidget::screen(int screen) QWidget *QDesktopWidget::screen(int screen)
@ -121,26 +121,24 @@ QWidget *QDesktopWidget::screen(int screen)
const QRect QDesktopWidget::availableGeometry(int screenNo) const const QRect QDesktopWidget::availableGeometry(int screenNo) const
{ {
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); QList<QScreen *> screens = QGuiApplication::screens();
QList<QPlatformScreen *> screens = pi->screens();
if (screenNo == -1) if (screenNo == -1)
screenNo = 0; screenNo = 0;
if (screenNo < 0 || screenNo >= screens.size()) if (screenNo < 0 || screenNo >= screens.size())
return QRect(); return QRect();
else else
return screens[screenNo]->availableGeometry(); return screens.at(screenNo)->availableGeometry();
} }
const QRect QDesktopWidget::screenGeometry(int screenNo) const const QRect QDesktopWidget::screenGeometry(int screenNo) const
{ {
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); QList<QScreen *> screens = QGuiApplication::screens();
QList<QPlatformScreen *> screens = pi->screens();
if (screenNo == -1) if (screenNo == -1)
screenNo = 0; screenNo = 0;
if (screenNo < 0 || screenNo >= screens.size()) if (screenNo < 0 || screenNo >= screens.size())
return QRect(); return QRect();
else else
return screens[screenNo]->geometry(); return screens.at(screenNo)->geometry();
} }
int QDesktopWidget::screenNumber(const QWidget *w) const int QDesktopWidget::screenNumber(const QWidget *w) const
@ -157,11 +155,10 @@ int QDesktopWidget::screenNumber(const QWidget *w) const
int QDesktopWidget::screenNumber(const QPoint &p) const int QDesktopWidget::screenNumber(const QPoint &p) const
{ {
QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); QList<QScreen *> screens = QGuiApplication::screens();
QList<QPlatformScreen *> screens = pi->screens();
for (int i = 0; i < screens.size(); ++i) for (int i = 0; i < screens.size(); ++i)
if (screens[i]->geometry().contains(p)) if (screens.at(i)->geometry().contains(p))
return i; return i;
return primaryScreen(); //even better would be closest screen return primaryScreen(); //even better would be closest screen

View File

@ -1266,8 +1266,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
#elif defined(Q_WS_QPA) #elif defined(Q_WS_QPA)
if (desktopWidget) { if (desktopWidget) {
int screen = desktopWidget->d_func()->topData()->screenIndex; int screen = desktopWidget->d_func()->topData()->screenIndex;
QPlatformIntegration *platform = QGuiApplicationPrivate::platformIntegration(); q->windowHandle()->setScreen(QGuiApplication::screens().value(screen, 0));
platform->moveToScreen(q->windowHandle(), screen);
} }
#else #else
Q_UNUSED(desktopWidget); Q_UNUSED(desktopWidget);

View File

@ -104,6 +104,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
win->setWindowFlags(data.window_flags); win->setWindowFlags(data.window_flags);
win->setGeometry(q->geometry()); win->setGeometry(q->geometry());
win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));
if (q->testAttribute(Qt::WA_TranslucentBackground)) { if (q->testAttribute(Qt::WA_TranslucentBackground)) {
QSurfaceFormat format; QSurfaceFormat format;
@ -141,7 +142,6 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
// first check children. and create them if necessary // first check children. and create them if necessary
// q_createNativeChildrenAndSetParent(q->windowHandle(),q); // q_createNativeChildrenAndSetParent(q->windowHandle(),q);
QGuiApplicationPrivate::platformIntegration()->moveToScreen(win, topData()->screenIndex);
// qDebug() << "create_sys" << q << q->internalWinId(); // qDebug() << "create_sys" << q << q->internalWinId();
} }
@ -261,8 +261,7 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
maybeTopData()->screenIndex = targetScreen; maybeTopData()->screenIndex = targetScreen;
// only if it is already created // only if it is already created
if (q->testAttribute(Qt::WA_WState_Created)) { if (q->testAttribute(Qt::WA_WState_Created)) {
QPlatformIntegration *platform = QGuiApplicationPrivate::platformIntegration(); q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
platform->moveToScreen(q->windowHandle(), targetScreen);
} }
} }
} }