diff options
Diffstat (limited to 'src/plugins/platforms/wayland')
71 files changed, 1781 insertions, 922 deletions
diff --git a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri index d9b5fa9bff..20c3aa0bd9 100644 --- a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri +++ b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri @@ -3,12 +3,10 @@ contains(QT_CONFIG, opengl) { QT += opengl HEADERS += \ - $$PWD/qwaylandglintegration.h \ - $$PWD/qwaylandglwindowsurface.h + $$PWD/qwaylandglintegration.h SOURCES += \ - $$PWD/qwaylandglintegration.cpp \ - $$PWD/qwaylandglwindowsurface.cpp + $$PWD/qwaylandglintegration.cpp QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) contains(QT_CONFIG, opengles2) { @@ -22,6 +20,9 @@ SOURCES += \ QT_WAYLAND_GL_INTEGRATION = xcomposite_egl CONFIG += xcomposite_egl } + } else:mac { + QT_WAYLAND_GL_INTEGRATION = readback_cgl + CONFIG += readback_cgl } else { isEqual(QT_WAYLAND_GL_CONFIG, readback) { QT_WAYLAND_GL_INTEGRATION = readback_glx @@ -48,6 +49,10 @@ readback_glx { include ($$PWD/readback_glx/readback_glx.pri) } +readback_cgl { + include ($$PWD/readback_cgl/readback_cgl.pri) +} + xcomposite_glx { include ($$PWD/xcomposite_glx/xcomposite_glx.pri) } diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h index 4b50b4bd68..4f688e41d8 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h @@ -44,7 +44,10 @@ class QWaylandWindow; class QWaylandDisplay; -class QWidget; +class QWindow; + +class QPlatformOpenGLContext; +class QSurfaceFormat; class QWaylandGLIntegration { @@ -54,7 +57,8 @@ public: virtual void initialize() = 0; - virtual QWaylandWindow *createEglWindow(QWidget *widget) = 0; + virtual QWaylandWindow *createEglWindow(QWindow *window) = 0; + virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0; static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay); }; diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp deleted file mode 100644 index fef07e6bf7..0000000000 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** 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 plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandglwindowsurface.h" - -#include "qwaylanddisplay.h" -#include "qwaylandwindow.h" -#include "qwaylandscreen.h" - -#include <QtOpenGL/QGLFramebufferObject> -#include <QtOpenGL/QGLContext> - -#include <QtOpenGL/private/qglengineshadermanager_p.h> - -QT_BEGIN_NAMESPACE - -static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br) -{ -#if !defined(QT_OPENGL_ES_2) - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); -#endif - const GLenum target = GL_TEXTURE_2D; - QRectF src = br.isEmpty() - ? QRectF(QPointF(), texSize) - : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size()); - - if (target == GL_TEXTURE_2D) { - qreal width = texSize.width(); - qreal height = texSize.height(); - - src.setLeft(src.left() / width); - src.setRight(src.right() / width); - src.setTop(src.top() / height); - src.setBottom(src.bottom() / height); - } - - const GLfloat tx1 = src.left(); - const GLfloat tx2 = src.right(); - const GLfloat ty1 = src.top(); - const GLfloat ty2 = src.bottom(); - - GLfloat texCoordArray[4*2] = { - tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1 - }; - - GLfloat vertexArray[4*2]; - vertexArray[0] = rect.left(); vertexArray[1] = rect.top(); - vertexArray[2] = rect.right(); vertexArray[3] = rect.top(); - vertexArray[4] = rect.right(); vertexArray[5] = rect.bottom(); - vertexArray[6] = rect.left(); vertexArray[7] = rect.bottom(); - - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray); - glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray); - - glBindTexture(target, tex_id); - - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - - glBindTexture(target, 0); -} - -static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect) -{ - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - glViewport(0, 0, viewport.width(), viewport.height()); - - QGLShaderProgram *blitProgram = - QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram(); - blitProgram->bind(); - blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/); - - // The shader manager's blit program does not multiply the - // vertices by the pmv matrix, so we need to do the effect - // of the orthographic projection here ourselves. - QRectF r; - qreal w = viewport.width(); - qreal h = viewport.height(); - r.setLeft((targetRect.left() / w) * 2.0f - 1.0f); - if (targetRect.right() == (viewport.width() - 1)) - r.setRight(1.0f); - else - r.setRight((targetRect.right() / w) * 2.0f - 1.0f); - r.setBottom((targetRect.top() / h) * 2.0f - 1.0f); - if (targetRect.bottom() == (viewport.height() - 1)) - r.setTop(1.0f); - else - r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f); - - drawTexture(r, texture, texSize, sourceRect); -} - -QWaylandGLWindowSurface::QWaylandGLWindowSurface(QWidget *window) - : QWindowSurface(window) - , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display()) - , mPaintDevice(0) -{ - -} - -QWaylandGLWindowSurface::~QWaylandGLWindowSurface() -{ - delete mPaintDevice; -} - -QPaintDevice *QWaylandGLWindowSurface::paintDevice() -{ - return mPaintDevice; -} - -void QWaylandGLWindowSurface::beginPaint(const QRegion &) -{ - window()->platformWindow()->glContext()->makeCurrent(); - glClearColor(0,0,0,0xff); - glClear(GL_COLOR_BUFFER_BIT); -} - -void QWaylandGLWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) -{ - Q_UNUSED(offset); - Q_UNUSED(region); - QWaylandWindow *ww = (QWaylandWindow *) widget->platformWindow(); - - if (mPaintDevice->isBound()) - mPaintDevice->release(); - - QRect rect(0,0,size().width(),size().height()); - QGLContext *ctx = QGLContext::fromPlatformGLContext(ww->glContext()); - blitTexture(ctx,mPaintDevice->texture(),size(),mPaintDevice->size(),rect,rect); - ww->glContext()->swapBuffers(); -} - -void QWaylandGLWindowSurface::resize(const QSize &size) -{ - QWindowSurface::resize(size); - window()->platformWindow()->glContext()->makeCurrent(); - delete mPaintDevice; - mPaintDevice = new QGLFramebufferObject(size,QGLFramebufferObject::CombinedDepthStencil); -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp new file mode 100644 index 0000000000..5f7663ef55 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandreadbackcglcontext.h" + +#include "qwaylandshmbackingstore.h" +#include "qwaylandreadbackcglwindow.h" + +#include <QtGui/QOpenGLContext> +#include <QtCore/QDebug> + +#include <OpenGL/OpenGL.h> +#include <OpenGL/glext.h> +#include <OpenGL/glu.h> + +#include <QtPlatformSupport/private/cglconvenience_p.h> + +QWaylandReadbackCGLContext::QWaylandReadbackCGLContext(QPlatformOpenGLContext *share) + : QPlatformOpenGLContext() +{ + Q_UNUSED(share); + m_glContext = qcgl_createGlContext(); +} + +QSurfaceFormat QWaylandReadbackCGLContext::format() const +{ + return qcgl_surfaceFormat(); +} + +bool QWaylandReadbackCGLContext::makeCurrent(QPlatformSurface *surface) +{ + QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface); + CGLSetPBuffer(m_glContext, window->pixelBuffer(), 0, 0, 0); + CGLSetCurrentContext(m_glContext); + return true; +} + +void QWaylandReadbackCGLContext::doneCurrent() +{ + CGLSetCurrentContext(0); +} + +void QWaylandReadbackCGLContext::swapBuffers(QPlatformSurface *surface) +{ + Q_UNUSED(surface); + + if (QOpenGLContext::currentContext()->handle() != this) { + makeCurrent(surface); + } + CGLFlushDrawable(m_glContext); + + QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface); + QSize size = window->geometry().size(); + + uchar *dstBits = const_cast<uchar *>(window->buffer()); + glReadPixels(0,0, size.width(), size.height(), GL_BGRA,GL_UNSIGNED_BYTE, dstBits); + + window->damage(QRect(QPoint(0,0),size)); + + // ### Should sync here but this call deadlocks with the server. + //window->waitForFrameSync(); +} + +void (*QWaylandReadbackCGLContext::getProcAddress(const QByteArray &procName)) () +{ + return qcgl_getProcAddress(procName); +} + diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h index 00da6976b8..eb065c3f69 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h @@ -39,31 +39,34 @@ ** ****************************************************************************/ -#ifndef QWAYLANDDRMSURFACE_H -#define QWAYLANDDRMSURFACE_H +#ifndef QWAYLANDREADBACKCGLCONTEXT_H +#define QWAYLANDREADBACKCGLCONTEXT_H -#include "qwaylanddisplay.h" +#include <QPlatformOpenGLContext> -#include <QtGui/private/qwindowsurface_p.h> +#include "qwaylandreadbackcglintegration.h" -class QGLFramebufferObject; +#include <OpenGL/OpenGL.h> -class QWaylandGLWindowSurface : public QWindowSurface +class QWaylandReadbackCGLWindow; +class QWaylandShmBuffer; + +class QWaylandReadbackCGLContext : public QPlatformOpenGLContext { public: - QWaylandGLWindowSurface(QWidget *window); - ~QWaylandGLWindowSurface(); + QWaylandReadbackCGLContext(QPlatformOpenGLContext *share); - void beginPaint(const QRegion &); + QSurfaceFormat format() const; - QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + void swapBuffers(QPlatformSurface *surface); + void (*getProcAddress(const QByteArray &procName)) (); - void resize(const QSize &size); + void geometryChanged(); private: - QWaylandDisplay *mDisplay; - QGLFramebufferObject *mPaintDevice; + CGLContextObj m_glContext; }; -#endif // QWAYLANDDRMSURFACE_H +#endif // QWAYLANDREADBACKCGLCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp new file mode 100644 index 0000000000..2878f9e292 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandreadbackcglintegration.h" +#include "qwaylandreadbackcglcontext.h" +#include "qwaylandreadbackcglwindow.h" + +#include <QtCore/QDebug> + +QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandReadbackCGLIntegration(waylandDisplay); +} + +QWaylandReadbackCGLIntegration::QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly) + : QWaylandGLIntegration() + , mWaylandDisplay(waylandDispaly) +{ + qDebug() << "Using Readback-CGL"; +} + +QWaylandReadbackCGLIntegration::~QWaylandReadbackCGLIntegration() +{ + +} + +void QWaylandReadbackCGLIntegration::initialize() +{ +} + +QWaylandWindow * QWaylandReadbackCGLIntegration::createEglWindow(QWindow *window) +{ + return new QWaylandReadbackCGLWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandReadbackCGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandReadbackCGLContext(share); +} + +QWaylandDisplay * QWaylandReadbackCGLIntegration::waylandDisplay() const +{ + return mWaylandDisplay; +} diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h new file mode 100644 index 0000000000..34c8d00a7c --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDREADBACKGLXINTEGRATION_H +#define QWAYLANDREADBACKGLXINTEGRATION_H + +#include "gl_integration/qwaylandglintegration.h" + +#include <QtCore/QTextStream> +#include <QtCore/QDataStream> +#include <QtCore/QMetaType> +#include <QtCore/QVariant> +#include <QtGui/QWindow> + +#include <X11/Xlib.h> + +class QWaylandReadbackCGLIntegration : public QWaylandGLIntegration +{ +public: + QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly); + ~QWaylandReadbackCGLIntegration(); + + void initialize(); + + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + QWaylandDisplay *waylandDisplay() const; + +private: + QWaylandDisplay *mWaylandDisplay; +}; + +#endif // QWAYLANDREADBACKGLXINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp new file mode 100644 index 0000000000..9e7f8520c9 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandreadbackcglwindow.h" +#include "qwaylandshmbackingstore.h" + +#include <OpenGL/OpenGL.h> +#include <OpenGL/glext.h> + +QWaylandReadbackCGLWindow::QWaylandReadbackCGLWindow(QWindow *window, QWaylandReadbackCGLIntegration *cglIntegration) + : QWaylandShmWindow(window) + , m_CglIntegration(cglIntegration) + , mContext(0) + , m_buffer(0) + , m_pixelBuffer(0) +{ +} + +QWaylandWindow::WindowType QWaylandReadbackCGLWindow::windowType() const +{ + //yeah. this type needs a new name + return QWaylandWindow::Egl; +} + + +void QWaylandReadbackCGLWindow::setGeometry(const QRect &rect) +{ + QWaylandShmWindow::setGeometry(rect); + + if (m_buffer) { + delete m_buffer; + m_buffer = 0; + + CGLDestroyPBuffer(m_pixelBuffer); + m_pixelBuffer = 0; + } +} + +CGLPBufferObj QWaylandReadbackCGLWindow::pixelBuffer() +{ + if (!m_pixelBuffer) + createSurface(); + + return m_pixelBuffer; +} + +uchar *QWaylandReadbackCGLWindow::buffer() +{ + return m_buffer->image()->bits(); +} + +void QWaylandReadbackCGLWindow::createSurface() +{ + QSize size(geometry().size()); + if (size.isEmpty()) { + //QGLWidget wants a context for a window without geometry + size = QSize(1,1); + } + + waitForFrameSync(); + + CGLCreatePBuffer(size.width(), size.height(), GL_TEXTURE_RECTANGLE_ARB, GL_BGRA, 0, &m_pixelBuffer); + + delete m_buffer; + m_buffer = new QWaylandShmBuffer(m_CglIntegration->waylandDisplay(),size,QImage::Format_ARGB32); + attach(m_buffer); +} + diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h new file mode 100644 index 0000000000..0598cf9037 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDREADBACKGLXWINDOW_H +#define QWAYLANDREADBACKGLXWINDOW_H + +#include "qwaylandshmwindow.h" +#include "qwaylandreadbackcglintegration.h" +#include "qwaylandreadbackcglcontext.h" + +#include <OpenGL/OpenGL.h> + +class QWaylandReadbackCGLWindow : public QWaylandShmWindow +{ +public: + QWaylandReadbackCGLWindow(QWindow *window, QWaylandReadbackCGLIntegration *cglIntegration); + WindowType windowType() const; + + void setGeometry(const QRect &rect); + CGLPBufferObj pixelBuffer(); + uchar *buffer(); +private: + void createSurface(); + + QWaylandReadbackCGLIntegration *m_CglIntegration; + QWaylandReadbackCGLContext *mContext; + + QWaylandShmBuffer *m_buffer; + CGLPBufferObj m_pixelBuffer; +}; + +#endif // QWAYLANDREADBACKGLXWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri b/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri new file mode 100644 index 0000000000..91cb90a30c --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri @@ -0,0 +1,10 @@ +HEADERS += \ + $$PWD/qwaylandreadbackcglintegration.h \ + $$PWD/qwaylandreadbackcglwindow.h \ + $$PWD/qwaylandreadbackcglcontext.h + +SOURCES += \ + $$PWD/qwaylandreadbackcglintegration.cpp \ + $$PWD/qwaylandreadbackcglwindow.cpp \ + $$PWD/qwaylandreadbackcglcontext.cpp + diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp index f02a10a05b..c03e8a9444 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp @@ -41,14 +41,16 @@ #include "qwaylandreadbackeglcontext.h" -#include "../../../eglconvenience/qeglconvenience.h" +#include <QPlatformSupport/eglconvenience/qeglconvenience_p.h> + +#include <QtCore/QDebug> +#include <QtGui/QWindowContext> #include <QtOpenGL/QGLContext> #include <QtOpenGL/private/qglextensions_p.h> #include "qwaylandshmsurface.h" -#include <QtCore/QDebug> static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) { @@ -77,7 +79,7 @@ QWaylandReadbackEglContext::QWaylandReadbackEglContext(QWaylandReadbackEglIntegr , mWindow(window) , mBuffer(0) , mPixmap(0) - , mConfig(q_configFromQPlatformWindowFormat(eglIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_PIXMAP_BIT)) + , mConfig(q_configFromQWindowFormat(eglIntegration->eglDisplay(),window->window()->requestedWindowFormat(),true,EGL_PIXMAP_BIT)) , mPixmapSurface(EGL_NO_SURFACE) { QVector<EGLint> eglContextAttrs; @@ -97,8 +99,6 @@ QWaylandReadbackEglContext::~QWaylandReadbackEglContext() void QWaylandReadbackEglContext::makeCurrent() { - QPlatformGLContext::makeCurrent(); - mWindow->waitForFrameSync(); eglMakeCurrent(mEglIntegration->eglDisplay(),mPixmapSurface,mPixmapSurface,mContext); @@ -106,7 +106,7 @@ void QWaylandReadbackEglContext::makeCurrent() void QWaylandReadbackEglContext::doneCurrent() { - QPlatformGLContext::doneCurrent(); + QPlatformOpenGLContext::doneCurrent(); eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT); } @@ -114,7 +114,7 @@ void QWaylandReadbackEglContext::swapBuffers() { eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface); - if (QPlatformGLContext::currentContext() != this) { + if (QWindowContext::currentContext()->handle() != this) { makeCurrent(); } @@ -143,9 +143,9 @@ void * QWaylandReadbackEglContext::getProcAddress(const QString &procName) return (void *) eglGetProcAddress(procName.toLatin1().data()); } -QPlatformWindowFormat QWaylandReadbackEglContext::platformWindowFormat() const +QWindowFormat QWaylandReadbackEglContext::windowFormat() const { - return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig); + return q_windowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig); } void QWaylandReadbackEglContext::geometryChanged() diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h index f9ab3783dd..75755fbd1a 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h @@ -42,15 +42,14 @@ #ifndef QWAYLANDREADBACKEGLGLCONTEXT_H #define QWAYLANDREADBACKEGLGLCONTEXT_H -#include <QPlatformGLContext> -#include <QtGui/QWidget> +#include <QPlatformOpenGLContext> #include "qwaylandreadbackeglintegration.h" #include "qwaylandreadbackeglwindow.h" class QWaylandShmBuffer; -class QWaylandReadbackEglContext : public QPlatformGLContext +class QWaylandReadbackEglContext : public QPlatformOpenGLContext { public: QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window); @@ -61,7 +60,7 @@ public: void swapBuffers(); void* getProcAddress(const QString& procName); - virtual QPlatformWindowFormat platformWindowFormat() const; + virtual QWindowFormat windowFormat() const; void geometryChanged(); diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp index 6bbac603cf..39fa3d589c 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp @@ -81,9 +81,14 @@ void QWaylandReadbackEglIntegration::initialize() } } -QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWidget *widget) +QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWindow *window) { - return new QWaylandReadbackEglWindow(widget,this); + return new QWaylandReadbackEglWindow(window, this); +} + +QPlatformOpenGLContext *QWaylandReadbackEglWindow::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandReadbackEglContext(glFormat, share, this); } EGLDisplay QWaylandReadbackEglIntegration::eglDisplay() diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h index ae1e8e5095..0d6aa55e4e 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h @@ -48,7 +48,8 @@ #include <QtCore/QDataStream> #include <QtCore/QMetaType> #include <QtCore/QVariant> -#include <QtGui/QWidget> +#include <QtCore/QEvent> +#include <QtGui/QCursor> #include <X11/Xlib.h> @@ -61,7 +62,8 @@ public: ~QWaylandReadbackEglIntegration(); void initialize(); - QWaylandWindow *createEglWindow(QWidget *widget); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; QWaylandDisplay *waylandDisplay() const; Display *xDisplay() const; diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp index 868e32e030..f4bc6379d6 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp @@ -43,7 +43,7 @@ #include "qwaylandreadbackeglcontext.h" -QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration) +QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration) : QWaylandShmWindow(window) , mEglIntegration(eglIntegration) , mContext(0) @@ -57,7 +57,7 @@ QWaylandWindow::WindowType QWaylandReadbackEglWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext *QWaylandReadbackEglWindow::glContext() const +QPlatformOpenGLContext *QWaylandReadbackEglWindow::glContext() const { if (!mContext) { QWaylandReadbackEglWindow *that = const_cast<QWaylandReadbackEglWindow *>(this); diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h index 1433483923..0852a8ee66 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h @@ -50,11 +50,11 @@ class QWaylandReadbackEglContext; class QWaylandReadbackEglWindow : public QWaylandShmWindow { public: - QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration); + QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; + QPlatformOpenGLContext *glContext() const; void setGeometry(const QRect &rect); diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri index 0d8e01b6bb..3325fe8ec9 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri @@ -1,14 +1,12 @@ - LIBS += -lX11 -lXext -lEGL +load(qpa/egl/convenience) HEADERS += \ $$PWD/qwaylandreadbackeglintegration.h \ $$PWD/qwaylandreadbackeglcontext.h \ $$PWD/qwaylandreadbackeglwindow.h \ - $$PWD/../../../eglconvenience/qeglconvenience.h SOURCES += \ $$PWD/qwaylandreadbackeglintegration.cpp \ $$PWD/qwaylandreadbackeglwindow.cpp \ $$PWD/qwaylandreadbackeglcontext.cpp \ - $$PWD/../../../eglconvenience/qeglconvenience.cpp diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp index 857c1db6e3..850e7bb0ac 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp @@ -41,9 +41,10 @@ #include "qwaylandreadbackglxcontext.h" -#include "qwaylandshmsurface.h" +#include "qwaylandshmbackingstore.h" #include "qwaylandreadbackglxwindow.h" +#include <QtGui/QOpenGLContext> #include <QtCore/QDebug> static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) @@ -68,96 +69,66 @@ static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) } } -QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window) - : QPlatformGLContext() - , mGlxIntegration(glxIntegration) - , mWindow(window) - , mBuffer(0) - , mPixmap(0) - , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat(),GLX_PIXMAP_BIT)) - , mGlxPixmap(0) +QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(const QSurfaceFormat &format, + QPlatformOpenGLContext *share, Display *display, int screen) + : m_display(display) { - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig); - mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE); + GLXFBConfig config = qglx_findConfig(display, screen, format, GLX_PIXMAP_BIT); - geometryChanged(); + GLXContext shareContext = share ? static_cast<QWaylandReadbackGlxContext *>(share)->m_context : 0; + + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config); + m_context = glXCreateContext(display, visualInfo, shareContext, TRUE); + m_format = qglx_surfaceFormatFromGLXFBConfig(display, config, m_context); +} + +QSurfaceFormat QWaylandReadbackGlxContext::format() const +{ + return m_format; } -void QWaylandReadbackGlxContext::makeCurrent() +bool QWaylandReadbackGlxContext::makeCurrent(QPlatformSurface *surface) { - QPlatformGLContext::makeCurrent(); + GLXPixmap glxPixmap = static_cast<QWaylandReadbackGlxWindow *>(surface)->glxPixmap(); - glXMakeCurrent(mGlxIntegration->xDisplay(),mGlxPixmap,mContext); + return glXMakeCurrent(m_display, glxPixmap, m_context); } void QWaylandReadbackGlxContext::doneCurrent() { - QPlatformGLContext::doneCurrent(); + glXMakeCurrent(m_display, 0, 0); } -void QWaylandReadbackGlxContext::swapBuffers() +void QWaylandReadbackGlxContext::swapBuffers(QPlatformSurface *surface) { - if (QPlatformGLContext::currentContext() != this) { - makeCurrent(); - } + // #### makeCurrent() directly on the platform context doesn't update QOpenGLContext::currentContext() + if (QOpenGLContext::currentContext()->handle() != this) + makeCurrent(surface); + + QWaylandReadbackGlxWindow *w = static_cast<QWaylandReadbackGlxWindow *>(surface); - QSize size = mWindow->geometry().size(); + QSize size = w->geometry().size(); - QImage img(size,QImage::Format_ARGB32); + QImage img(size, QImage::Format_ARGB32); const uchar *constBits = img.bits(); void *pixels = const_cast<uchar *>(constBits); - glReadPixels(0,0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels); + glReadPixels(0, 0, size.width(), size.height(), GL_RGBA,GL_UNSIGNED_BYTE, pixels); img = img.mirrored(); - qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV); + qgl_byteSwapImage(img, GL_UNSIGNED_INT_8_8_8_8_REV); constBits = img.bits(); - const uchar *constDstBits = mBuffer->image()->bits(); + const uchar *constDstBits = w->buffer(); uchar *dstBits = const_cast<uchar *>(constDstBits); - memcpy(dstBits,constBits,(img.width()*4) * img.height()); + memcpy(dstBits, constBits, (img.width() * 4) * img.height()); + w->damage(QRect(QPoint(), size)); - mWindow->damage(QRegion(QRect(QPoint(0,0),size))); - mWindow->waitForFrameSync(); - + w->waitForFrameSync(); } -void * QWaylandReadbackGlxContext::getProcAddress(const QString &procName) +void (*QWaylandReadbackGlxContext::getProcAddress(const QByteArray &procName)) () { - return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data())); -} - -QPlatformWindowFormat QWaylandReadbackGlxContext::platformWindowFormat() const -{ - return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext); -} - -void QWaylandReadbackGlxContext::geometryChanged() -{ - QSize size(mWindow->geometry().size()); - if (size.isEmpty()) { - //QGLWidget wants a context for a window without geometry - size = QSize(1,1); - } - - mWindow->waitForFrameSync(); - - delete mBuffer; - //XFreePixmap deletes the glxPixmap as well - if (mPixmap) { - XFreePixmap(mGlxIntegration->xDisplay(),mPixmap); - } - - mBuffer = new QWaylandShmBuffer(mGlxIntegration->waylandDisplay(),size,QImage::Format_ARGB32); - mWindow->attach(mBuffer); - int depth = XDefaultDepth(mGlxIntegration->xDisplay(),mGlxIntegration->screen()); - mPixmap = XCreatePixmap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),size.width(),size.height(),depth); - XSync(mGlxIntegration->xDisplay(),False); - - mGlxPixmap = glXCreatePixmap(mGlxIntegration->xDisplay(),mConfig,mPixmap,0); - - if (!mGlxPixmap) { - qDebug() << "Could not make egl surface out of pixmap :("; - } + return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData())); } diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h index 07e0f620de..7b5eeece93 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h @@ -42,38 +42,35 @@ #ifndef QWAYLANDREADBACKGLXCONTEXT_H #define QWAYLANDREADBACKGLXCONTEXT_H -#include <QPlatformGLContext> +#include <QPlatformOpenGLContext> +#include <QSurfaceFormat> #include "qwaylandreadbackglxintegration.h" -#include "qglxconvenience.h" +#include <QtPlatformSupport/private/qglxconvenience_p.h> class QWaylandReadbackGlxWindow; class QWaylandShmBuffer; -class QWaylandReadbackGlxContext : public QPlatformGLContext +class QWaylandReadbackGlxContext : public QPlatformOpenGLContext { public: - QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window); + QWaylandReadbackGlxContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen); - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + QSurfaceFormat format() const; + + void swapBuffers(QPlatformSurface *surface); - QPlatformWindowFormat platformWindowFormat() const; + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); - void geometryChanged(); + void (*getProcAddress(const QByteArray &procName)) (); private: - QWaylandReadbackGlxIntegration *mGlxIntegration; - QWaylandReadbackGlxWindow *mWindow; - QWaylandShmBuffer *mBuffer; + GLXContext m_context; - Pixmap mPixmap; - GLXFBConfig mConfig; - GLXContext mContext; - GLXPixmap mGlxPixmap; + Display *m_display; + QSurfaceFormat m_format; }; #endif // QWAYLANDREADBACKGLXCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp index 37a14a9f4c..752bb06a43 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp @@ -66,9 +66,14 @@ void QWaylandReadbackGlxIntegration::initialize() { } -QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWidget *widget) +QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWindow *window) { - return new QWaylandReadbackGlxWindow(widget,this); + return new QWaylandReadbackGlxWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandReadbackGlxIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandReadbackGlxContext(glFormat, share, mDisplay, mScreen); } QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h index d267d8dffe..ee50d74ebd 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h @@ -48,7 +48,7 @@ #include <QtCore/QDataStream> #include <QtCore/QMetaType> #include <QtCore/QVariant> -#include <QtGui/QWidget> +#include <QtGui/QWindow> #include <X11/Xlib.h> @@ -60,7 +60,8 @@ public: void initialize(); - QWaylandWindow *createEglWindow(QWidget *widget); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; QWaylandDisplay *waylandDisplay() const; diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp index 98198dfa06..35c3ca3154 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp @@ -39,12 +39,19 @@ ** ****************************************************************************/ +#include <QtDebug> + #include "qwaylandreadbackglxwindow.h" +#include "qwaylandshmbackingstore.h" -QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration) +QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration) : QWaylandShmWindow(window) - , mGlxIntegration(glxIntegration) - , mContext(0) + , m_glxIntegration(glxIntegration) + , m_buffer(0) + , m_pixmap(0) + , m_config(0) + , m_glxPixmap(0) + , m_window(window) { } @@ -54,20 +61,54 @@ QWaylandWindow::WindowType QWaylandReadbackGlxWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext * QWaylandReadbackGlxWindow::glContext() const +void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect) { - if (!mContext) { - QWaylandReadbackGlxWindow *that = const_cast<QWaylandReadbackGlxWindow *>(this); - that->mContext = new QWaylandReadbackGlxContext(mGlxIntegration,that); + QWaylandShmWindow::setGeometry(rect); + + if (m_pixmap) { + delete mBuffer; + //XFreePixmap deletes the glxPixmap as well + XFreePixmap(m_glxIntegration->xDisplay(), m_pixmap); + m_pixmap = 0; } - return mContext; } -void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect) +GLXPixmap QWaylandReadbackGlxWindow::glxPixmap() const { - QWaylandShmWindow::setGeometry(rect); + if (!m_pixmap) + const_cast<QWaylandReadbackGlxWindow *>(this)->createSurface(); + + return m_glxPixmap; +} - if (mContext) { - mContext->geometryChanged(); +uchar *QWaylandReadbackGlxWindow::buffer() +{ + return m_buffer->image()->bits(); +} + +void QWaylandReadbackGlxWindow::createSurface() +{ + QSize size(geometry().size()); + if (size.isEmpty()) { + //QGLWidget wants a context for a window without geometry + size = QSize(1,1); } + + waitForFrameSync(); + + m_buffer = new QWaylandShmBuffer(m_glxIntegration->waylandDisplay(), size, QImage::Format_ARGB32); + attach(m_buffer); + + int depth = XDefaultDepth(m_glxIntegration->xDisplay(), m_glxIntegration->screen()); + m_pixmap = XCreatePixmap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(), size.width(), size.height(), depth); + XSync(m_glxIntegration->xDisplay(), False); + + if (!m_config) + m_config = qglx_findConfig(m_glxIntegration->xDisplay(), m_glxIntegration->screen(), m_window->format()); + + m_glxPixmap = glXCreatePixmap(m_glxIntegration->xDisplay(), m_config, m_pixmap,0); + + if (!m_glxPixmap) + qDebug() << "Could not make glx surface out of pixmap :("; } + diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h index d478961d53..c92646c80d 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h @@ -49,17 +49,25 @@ class QWaylandReadbackGlxWindow : public QWaylandShmWindow { public: - QWaylandReadbackGlxWindow(QWidget *window, QWaylandReadbackGlxIntegration *glxIntegration); + QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; - void setGeometry(const QRect &rect); + Pixmap glxPixmap() const; + + uchar *buffer(); + private: - QWaylandReadbackGlxIntegration *mGlxIntegration; - QWaylandReadbackGlxContext *mContext; + void createSurface(); + + QWaylandReadbackGlxIntegration *m_glxIntegration; + QWaylandShmBuffer *m_buffer; + Pixmap m_pixmap; + GLXFBConfig m_config; + GLXPixmap m_glxPixmap; + QWindow *m_window; }; #endif // QWAYLANDREADBACKGLXWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri index f8ea005937..746d594fa2 100644 --- a/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri @@ -1,4 +1,3 @@ -include (../../../glxconvenience/glxconvenience.pri) HEADERS += \ $$PWD/qwaylandreadbackglxintegration.h \ $$PWD/qwaylandreadbackglxwindow.h \ diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp index d4deb01022..27f17a6153 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp @@ -44,11 +44,12 @@ #include "gl_integration/qwaylandglintegration.h" #include "qwaylandeglwindow.h" +#include "qwaylandglcontext.h" #include <QtCore/QDebug> QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) - : mWaylandDisplay(waylandDisplay) + : m_waylandDisplay(waylandDisplay) { qDebug() << "Using Wayland-EGL"; } @@ -56,31 +57,41 @@ QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay QWaylandEglIntegration::~QWaylandEglIntegration() { - eglTerminate(mEglDisplay); + eglTerminate(m_eglDisplay); } void QWaylandEglIntegration::initialize() { + QByteArray eglPlatform = qgetenv("EGL_PLATFORM"); + if (eglPlatform.isEmpty()) { + setenv("EGL_PLATFORM","wayland",true); + } + EGLint major,minor; - mEglDisplay = eglGetDisplay(mWaylandDisplay); - if (mEglDisplay == NULL) { + m_eglDisplay = eglGetDisplay(m_waylandDisplay); + if (m_eglDisplay == NULL) { qWarning("EGL not available"); } else { - if (!eglInitialize(mEglDisplay, &major, &minor)) { + if (!eglInitialize(m_eglDisplay, &major, &minor)) { qWarning("failed to initialize EGL display"); return; } } } -QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWidget *window) +QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWindow *window) { return new QWaylandEglWindow(window); } +QPlatformOpenGLContext *QWaylandEglIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandGLContext(m_eglDisplay, glFormat, share); +} + EGLDisplay QWaylandEglIntegration::eglDisplay() const { - return mEglDisplay; + return m_eglDisplay; } QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h index ea8b0f725c..7a26c57658 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h @@ -47,7 +47,7 @@ #include "qwaylandeglinclude.h" class QWaylandWindow; -class QWidget; +class QWindow; class QWaylandEglIntegration : public QWaylandGLIntegration { @@ -57,14 +57,15 @@ public: void initialize(); - QWaylandWindow *createEglWindow(QWidget *window); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; EGLDisplay eglDisplay() const; - struct wl_egl_display *nativeDisplay() const; + private: - struct wl_display *mWaylandDisplay; + struct wl_display *m_waylandDisplay; - EGLDisplay mEglDisplay; + EGLDisplay m_eglDisplay; }; #endif // QWAYLANDEGLINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp index cd8b5b3524..e0e1f772b9 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -44,19 +44,30 @@ #include "qwaylandscreen.h" #include "qwaylandglcontext.h" -QWaylandEglWindow::QWaylandEglWindow(QWidget *window) +#include <QtPlatformSupport/private/qeglconvenience_p.h> + +#include <QtGui/QWindow> +#include <QtGui/QWindowSystemInterface> + +QWaylandEglWindow::QWaylandEglWindow(QWindow *window) : QWaylandWindow(window) - , mGLContext(0) - , mWaylandEglWindow(0) + , m_waylandEglWindow(0) + , m_eglSurface(0) + , m_eglConfig(0) + , m_format(window->format()) { - mEglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration()); + m_eglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration()); + //super creates a new surface newSurfaceCreated(); } QWaylandEglWindow::~QWaylandEglWindow() { - delete mGLContext; + if (m_eglSurface) { + eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + m_eglSurface = 0; + } } QWaylandWindow::WindowType QWaylandEglWindow::windowType() const @@ -67,46 +78,48 @@ QWaylandWindow::WindowType QWaylandEglWindow::windowType() const void QWaylandEglWindow::setGeometry(const QRect &rect) { QWaylandWindow::setGeometry(rect); - if (mWaylandEglWindow) { - wl_egl_window_resize(mWaylandEglWindow,rect.width(),rect.height(),0,0); + if (m_waylandEglWindow){ + wl_egl_window_resize(m_waylandEglWindow, rect.width(), rect.height(), 0, 0); + QWindowSystemInterface::handleGeometryChange(window(), rect); } } -void QWaylandEglWindow::setParent(const QPlatformWindow *parent) +void QWaylandEglWindow::newSurfaceCreated() { - const QWaylandWindow *wParent = static_cast<const QWaylandWindow *>(parent); + if (m_waylandEglWindow) + wl_egl_window_destroy(m_waylandEglWindow); - mParentWindow = wParent; -} - -QPlatformGLContext * QWaylandEglWindow::glContext() const -{ - if (!mGLContext) { - QWaylandEglWindow *that = const_cast<QWaylandEglWindow *>(this); - that->mGLContext = new QWaylandGLContext(mEglIntegration->eglDisplay(),widget()->platformWindowFormat()); + wl_visual *visual = QWaylandScreen::waylandScreenFromWindow(window())->visual(); + QSize size = geometry().size(); + if (!size.isValid()) + size = QSize(0,0); - EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow)); - EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); - that->mGLContext->setEglSurface(surface); + if (m_eglSurface) { + eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + m_eglSurface = 0; } - return mGLContext; + m_waylandEglWindow = wl_egl_window_create(mSurface, size.width(), size.height(), visual); } -void QWaylandEglWindow::newSurfaceCreated() +QSurfaceFormat QWaylandEglWindow::format() const { - if (mWaylandEglWindow) { - wl_egl_window_destroy(mWaylandEglWindow); - } - wl_visual *visual = QWaylandScreen::waylandScreenFromWidget(widget())->visual(); - QSize size = geometry().size(); - if (!size.isValid()) - size = QSize(0,0); + return m_format; +} - mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual); - if (mGLContext) { - EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow)); - EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); - mGLContext->setEglSurface(surface); +EGLSurface QWaylandEglWindow::eglSurface() const +{ + if (!m_waylandEglWindow) + return 0; + + if (!m_eglSurface) { + if (!m_eglConfig) + m_eglConfig = q_configFromGLFormat(m_eglIntegration->eglDisplay(), window()->format(), true); + + EGLNativeWindowType window = m_waylandEglWindow; + m_eglSurface = eglCreateWindowSurface(m_eglIntegration->eglDisplay(), m_eglConfig, window, 0); } + + return m_eglSurface; } + diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h index 6d2038824a..d435a511c4 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h @@ -51,20 +51,28 @@ class QWaylandGLContext; class QWaylandEglWindow : public QWaylandWindow { public: - QWaylandEglWindow(QWidget *window); + QWaylandEglWindow(QWindow *window); ~QWaylandEglWindow(); WindowType windowType() const; void setGeometry(const QRect &rect); - void setParent(const QPlatformWindow *parent); - QPlatformGLContext *glContext() const; + + EGLSurface eglSurface() const; + + QSurfaceFormat format() const; + protected: void newSurfaceCreated(); + private: - QWaylandEglIntegration *mEglIntegration; - QWaylandGLContext *mGLContext; - struct wl_egl_window *mWaylandEglWindow; + QWaylandEglIntegration *m_eglIntegration; + struct wl_egl_window *m_waylandEglWindow; + + const QWaylandWindow *m_parentWindow; + + mutable EGLSurface m_eglSurface; + mutable EGLConfig m_eglConfig; - const QWaylandWindow *mParentWindow; + QSurfaceFormat m_format; }; #endif // QWAYLANDEGLWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp index 0f27501c71..aa61405eb6 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp @@ -43,26 +43,21 @@ #include "qwaylanddisplay.h" #include "qwaylandwindow.h" +#include "qwaylandeglwindow.h" -#include "../../../eglconvenience/qeglconvenience.h" +#include <QtPlatformSupport/private/qeglconvenience_p.h> -#include <QtGui/QPlatformGLContext> -#include <QtGui/QPlatformWindowFormat> +#include <QtGui/QPlatformOpenGLContext> +#include <QtGui/QSurfaceFormat> #include <QtCore/QMutex> -QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format) - : QPlatformGLContext() - , mEglDisplay(eglDisplay) - , mSurface(EGL_NO_SURFACE) - , mConfig(q_configFromQPlatformWindowFormat(mEglDisplay,format,true)) - , mFormat(qt_qPlatformWindowFormatFromConfig(mEglDisplay,mConfig)) +QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share) + : QPlatformOpenGLContext() + , m_eglDisplay(eglDisplay) + , m_config(q_configFromGLFormat(m_eglDisplay, format, true)) + , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) { - QPlatformGLContext *sharePlatformContext = 0; - sharePlatformContext = format.sharedGLContext(); - mFormat.setSharedContext(sharePlatformContext); - EGLContext shareEGLContext = EGL_NO_CONTEXT; - if (sharePlatformContext) - shareEGLContext = static_cast<const QWaylandGLContext*>(sharePlatformContext)->mContext; + EGLContext shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; eglBindAPI(EGL_OPENGL_ES_API); @@ -71,63 +66,38 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindo eglContextAttrs.append(2); eglContextAttrs.append(EGL_NONE); - mContext = eglCreateContext(mEglDisplay, mConfig, - shareEGLContext, eglContextAttrs.constData()); + m_context = eglCreateContext(m_eglDisplay, m_config, shareEGLContext, eglContextAttrs.constData()); } -QWaylandGLContext::QWaylandGLContext() - : QPlatformGLContext() - , mEglDisplay(0) - , mContext(EGL_NO_CONTEXT) - , mSurface(EGL_NO_SURFACE) - , mConfig(0) -{ } - QWaylandGLContext::~QWaylandGLContext() { - eglDestroyContext(mEglDisplay,mContext); + eglDestroyContext(m_eglDisplay, m_context); } -void QWaylandGLContext::makeCurrent() +bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) { - QPlatformGLContext::makeCurrent(); - if (mSurface == EGL_NO_SURFACE) { - qWarning("makeCurrent with EGL_NO_SURFACE"); - } - eglMakeCurrent(mEglDisplay, mSurface, mSurface, mContext); + EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface(); + return eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context); } void QWaylandGLContext::doneCurrent() { - QPlatformGLContext::doneCurrent(); - eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -} - -void QWaylandGLContext::swapBuffers() -{ - eglSwapBuffers(mEglDisplay,mSurface); + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } -void *QWaylandGLContext::getProcAddress(const QString &string) +void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) { - return (void *) eglGetProcAddress(string.toLatin1().data()); + EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface(); + eglSwapBuffers(m_eglDisplay, eglSurface); } -void QWaylandGLContext::setEglSurface(EGLSurface surface) +void (*QWaylandGLContext::getProcAddress(const QByteArray &procName)) () { - bool wasCurrent = false; - if (QPlatformGLContext::currentContext() == this) { - wasCurrent = true; - doneCurrent(); - } - mSurface = surface; - if (wasCurrent) { - makeCurrent(); - } + return eglGetProcAddress(procName.constData()); } EGLConfig QWaylandGLContext::eglConfig() const { - return mConfig; + return m_config; } diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h index 2c6feb498c..16d9fa4ada 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h @@ -44,36 +44,36 @@ #include "qwaylanddisplay.h" -#include <QtGui/QPlatformGLContext> +#include <QtGui/QPlatformOpenGLContext> #include "qwaylandeglinclude.h" class QWaylandWindow; class QWaylandGLWindowSurface; -class QWaylandGLContext : public QPlatformGLContext { +class QWaylandGLContext : public QPlatformOpenGLContext { public: - QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format); + QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share); ~QWaylandGLContext(); - void makeCurrent(); + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString&); - QPlatformWindowFormat platformWindowFormat() const { return mFormat; } + void (*getProcAddress(const QByteArray &procName)) (); - void setEglSurface(EGLSurface surface); - EGLConfig eglConfig() const; -private: - EGLDisplay mEglDisplay; + QSurfaceFormat format() const { return m_format; } - EGLContext mContext; - EGLSurface mSurface; - EGLConfig mConfig; - QPlatformWindowFormat mFormat; + EGLConfig eglConfig() const; + EGLContext eglContext() const { return m_context; } - QWaylandGLContext(); +private: + EGLDisplay m_eglDisplay; + EGLContext m_context; + EGLConfig m_config; + QSurfaceFormat m_format; }; diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri index cd0701150f..8b4b163b03 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri @@ -1,5 +1,3 @@ -include (../../../eglconvenience/eglconvenience.pri) - LIBS += -lwayland-egl -lEGL INCLUDEPATH += $$PWD SOURCES += $$PWD/qwaylandeglintegration.cpp \ diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp index 999a411397..f2f9d1ceb6 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp @@ -42,128 +42,31 @@ #include "qwaylandxcompositeeglcontext.h" #include "qwaylandxcompositeeglwindow.h" -#include "qwaylandxcompositebuffer.h" -#include "wayland-xcomposite-client-protocol.h" #include <QtCore/QDebug> +#include <QtGui/QRegion> -#include "qeglconvenience.h" -#include "qxlibeglintegration.h" +#include <QtPlatformSupport/private/qeglconvenience_p.h> -#include <X11/extensions/Xcomposite.h> - -QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window) - : QPlatformGLContext() - , mEglIntegration(glxIntegration) - , mWindow(window) - , mBuffer(0) - , mXWindow(0) - , mConfig(q_configFromQPlatformWindowFormat(glxIntegration->eglDisplay(),window->widget()->platformWindowFormat(),true,EGL_WINDOW_BIT)) - , mWaitingForSync(false) -{ - QVector<EGLint> eglContextAttrs; - eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); eglContextAttrs.append(2); - eglContextAttrs.append(EGL_NONE); - - mContext = eglCreateContext(glxIntegration->eglDisplay(),mConfig,EGL_NO_CONTEXT,eglContextAttrs.constData()); - if (mContext == EGL_NO_CONTEXT) { - qFatal("failed to find context"); - } - - geometryChanged(); -} - -void QWaylandXCompositeEGLContext::makeCurrent() -{ - QPlatformGLContext::makeCurrent(); - - eglMakeCurrent(mEglIntegration->eglDisplay(),mEglWindowSurface,mEglWindowSurface,mContext); -} - -void QWaylandXCompositeEGLContext::doneCurrent() +QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) + : QEGLPlatformContext(format, share, display) { - QPlatformGLContext::doneCurrent(); - eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT); } -void QWaylandXCompositeEGLContext::swapBuffers() +void QWaylandXCompositeEGLContext::swapBuffers(QPlatformSurface *surface) { - QSize size = mWindow->geometry().size(); + QEGLPlatformContext::swapBuffers(surface); - eglSwapBuffers(mEglIntegration->eglDisplay(),mEglWindowSurface); - mWindow->damage(QRect(QPoint(0,0),size)); - mWindow->waitForFrameSync(); -} + QWaylandXCompositeEGLWindow *w = + static_cast<QWaylandXCompositeEGLWindow *>(surface); -void * QWaylandXCompositeEGLContext::getProcAddress(const QString &procName) -{ - return (void *)eglGetProcAddress(qPrintable(procName)); -} + QSize size = w->geometry().size(); -QPlatformWindowFormat QWaylandXCompositeEGLContext::platformWindowFormat() const -{ - return qt_qPlatformWindowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig); + w->damage(QRect(QPoint(), size)); + w->waitForFrameSync(); } -void QWaylandXCompositeEGLContext::sync_function(void *data) +EGLSurface QWaylandXCompositeEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) { - QWaylandXCompositeEGLContext *that = static_cast<QWaylandXCompositeEGLContext *>(data); - that->mWaitingForSync = false; -} - -void QWaylandXCompositeEGLContext::geometryChanged() -{ - QSize size(mWindow->geometry().size()); - if (size.isEmpty()) { - //QGLWidget wants a context for a window without geometry - size = QSize(1,1); - } - - delete mBuffer; - //XFreePixmap deletes the glxPixmap as well - if (mXWindow) { - XDestroyWindow(mEglIntegration->xDisplay(),mXWindow); - } - - VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(mEglIntegration->xDisplay(),mEglIntegration->eglDisplay(),mConfig); - - XVisualInfo visualInfoTemplate; - memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); - visualInfoTemplate.visualid = visualId; - - int matchingCount = 0; - XVisualInfo *visualInfo = XGetVisualInfo(mEglIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount); - - Colormap cmap = XCreateColormap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),visualInfo->visual,AllocNone); - - XSetWindowAttributes a; - a.colormap = cmap; - mXWindow = XCreateWindow(mEglIntegration->xDisplay(), mEglIntegration->rootWindow(),0, 0, size.width(), size.height(), - 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWColormap, &a); - - XCompositeRedirectWindow(mEglIntegration->xDisplay(), mXWindow, CompositeRedirectManual); - XMapWindow(mEglIntegration->xDisplay(), mXWindow); - - mEglWindowSurface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mConfig,mXWindow,0); - if (mEglWindowSurface == EGL_NO_SURFACE) { - qFatal("Could not make eglsurface"); - } - - XSync(mEglIntegration->xDisplay(),False); - mBuffer = new QWaylandXCompositeBuffer(mEglIntegration->waylandXComposite(), - (uint32_t)mXWindow, - size, - mEglIntegration->waylandDisplay()->argbVisual()); - mWindow->attach(mBuffer); - wl_display_sync_callback(mEglIntegration->waylandDisplay()->wl_display(), - QWaylandXCompositeEGLContext::sync_function, - this); - - mWaitingForSync = true; - wl_display_sync(mEglIntegration->waylandDisplay()->wl_display(),0); - mEglIntegration->waylandDisplay()->flushRequests(); - while (mWaitingForSync) { - mEglIntegration->waylandDisplay()->readEvents(); - } + return static_cast<QWaylandXCompositeEGLWindow *>(surface)->eglSurface(); } diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h index 9d9dd53e0b..8420f2be13 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h @@ -42,41 +42,23 @@ #ifndef QWAYLANDXCOMPOSITEEGLCONTEXT_H #define QWAYLANDXCOMPOSITEEGLCONTEXT_H -#include <QtGui/QPlatformGLContext> +#include <QtGui/QPlatformOpenGLContext> -#include <QtCore/QWaitCondition> - -#include "qwaylandbuffer.h" #include "qwaylandxcompositeeglintegration.h" +#include <QtPlatformSupport/private/qeglplatformcontext_p.h> + class QWaylandXCompositeEGLWindow; -class QWaylandXCompositeEGLContext : public QPlatformGLContext +class QWaylandXCompositeEGLContext : public QEGLPlatformContext { public: - QWaylandXCompositeEGLContext(QWaylandXCompositeEGLIntegration *glxIntegration, QWaylandXCompositeEGLWindow *window); - - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display); - QPlatformWindowFormat platformWindowFormat() const; - - void geometryChanged(); + void swapBuffers(QPlatformSurface *surface); private: - QWaylandXCompositeEGLIntegration *mEglIntegration; - QWaylandXCompositeEGLWindow *mWindow; - QWaylandBuffer *mBuffer; - - Window mXWindow; - EGLConfig mConfig; - EGLContext mContext; - EGLSurface mEglWindowSurface; - - static void sync_function(void *data); - bool mWaitingForSync; + EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface); }; #endif // QWAYLANDXCOMPOSITEEGLCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp index 53199e87b8..d7e37f8e70 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp @@ -70,9 +70,14 @@ void QWaylandXCompositeEGLIntegration::initialize() { } -QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWidget *widget) +QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *window) { - return new QWaylandXCompositeEGLWindow(widget,this); + return new QWaylandXCompositeEGLWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandXCompositeEGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay()); } Display * QWaylandXCompositeEGLIntegration::xDisplay() const diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h index 1e8055944f..74ea930e9a 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h @@ -49,7 +49,9 @@ #include <QtCore/QDataStream> #include <QtCore/QMetaType> #include <QtCore/QVariant> -#include <QtGui/QWidget> +#include <QtGui/QWindow> + +#include <QPlatformOpenGLContext> #include <QWaitCondition> @@ -66,7 +68,8 @@ public: void initialize(); - QWaylandWindow *createEglWindow(QWidget *widget); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; QWaylandDisplay *waylandDisplay() const; struct wl_xcomposite *waylandXComposite() const; diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp index 1047cb8b0a..320113f58d 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp @@ -40,17 +40,29 @@ ****************************************************************************/ #include "qwaylandxcompositeeglwindow.h" +#include "qwaylandxcompositebuffer.h" + +#include <QtPlatformSupport/private/qeglconvenience_p.h> +#include <QtPlatformSupport/private/qxlibeglintegration_p.h> + +#include "wayland-xcomposite-client-protocol.h" + +#include <X11/extensions/Xcomposite.h> #include "qwaylandxcompositeeglintegration.h" #include "windowmanager_integration/qwaylandwindowmanagerintegration.h" #include <QtCore/QDebug> -QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration) +QWaylandXCompositeEGLWindow::QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration) : QWaylandWindow(window) - , mGlxIntegration(glxIntegration) - , mContext(0) + , m_glxIntegration(glxIntegration) + , m_context(0) + , m_buffer(0) + , m_xWindow(0) + , m_config(q_configFromGLFormat(glxIntegration->eglDisplay(), window->format(), true)) + , m_surface(0) + , m_waitingForSync(false) { - } QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const @@ -59,23 +71,83 @@ QWaylandWindow::WindowType QWaylandXCompositeEGLWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext * QWaylandXCompositeEGLWindow::glContext() const +void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect) { - if (!mContext) { - qDebug() << "creating glcontext;"; - QWaylandXCompositeEGLWindow *that = const_cast<QWaylandXCompositeEGLWindow *>(this); - that->mContext = new QWaylandXCompositeEGLContext(mGlxIntegration,that); + QWaylandWindow::setGeometry(rect); + + if (m_surface) { + eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface); + m_surface = 0; } - return mContext; } -void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect) +EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const { - QWaylandWindow::setGeometry(rect); + if (!m_surface) + const_cast<QWaylandXCompositeEGLWindow *>(this)->createEglSurface(); + return m_surface; +} + +void QWaylandXCompositeEGLWindow::createEglSurface() +{ + QSize size(geometry().size()); + if (size.isEmpty()) { + // QGLWidget wants a context for a window without geometry + size = QSize(1,1); + } - if (mContext) { - mContext->geometryChanged(); + delete m_buffer; + //XFreePixmap deletes the glxPixmap as well + if (m_xWindow) { + XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow); } + + VisualID visualId = QXlibEglIntegration::getCompatibleVisualId(m_glxIntegration->xDisplay(), m_glxIntegration->eglDisplay(), m_config); + + XVisualInfo visualInfoTemplate; + memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); + visualInfoTemplate.visualid = visualId; + + int matchingCount = 0; + XVisualInfo *visualInfo = XGetVisualInfo(m_glxIntegration->xDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount); + + Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(),m_glxIntegration->rootWindow(),visualInfo->visual,AllocNone); + + XSetWindowAttributes a; + a.colormap = cmap; + m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(), + 0, visualInfo->depth, InputOutput, visualInfo->visual, + CWColormap, &a); + + XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual); + XMapWindow(m_glxIntegration->xDisplay(), m_xWindow); + + m_surface = eglCreateWindowSurface(m_glxIntegration->eglDisplay(), m_config, m_xWindow,0); + if (m_surface == EGL_NO_SURFACE) { + qFatal("Could not make eglsurface"); + } + + XSync(m_glxIntegration->xDisplay(),False); + mBuffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(), + (uint32_t)m_xWindow, + size, + m_glxIntegration->waylandDisplay()->argbVisual()); + attach(m_buffer); + wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(), + QWaylandXCompositeEGLWindow::sync_function, + this); + + m_waitingForSync = true; + wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(),0); + m_glxIntegration->waylandDisplay()->flushRequests(); + while (m_waitingForSync) + m_glxIntegration->waylandDisplay()->readEvents(); +} + +void QWaylandXCompositeEGLWindow::sync_function(void *data) +{ + QWaylandXCompositeEGLWindow *that = static_cast<QWaylandXCompositeEGLWindow *>(data); + that->m_waitingForSync = false; } void QWaylandXCompositeEGLWindow::requestActivateWindow() diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h index ea4dd2d626..b2f8fbe6c4 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h @@ -43,24 +43,36 @@ #define QWAYLANDXCOMPOSITEEGLWINDOW_H #include "qwaylandwindow.h" +#include "qwaylandbuffer.h" + #include "qwaylandxcompositeeglintegration.h" #include "qwaylandxcompositeeglcontext.h" class QWaylandXCompositeEGLWindow : public QWaylandWindow { public: - QWaylandXCompositeEGLWindow(QWidget *window, QWaylandXCompositeEGLIntegration *glxIntegration); + QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; - void setGeometry(const QRect &rect); void requestActivateWindow(); + EGLSurface eglSurface() const; + private: - QWaylandXCompositeEGLIntegration *mGlxIntegration; - QWaylandXCompositeEGLContext *mContext; + void createEglSurface(); + + QWaylandXCompositeEGLIntegration *m_glxIntegration; + QWaylandXCompositeEGLContext *m_context; + QWaylandBuffer *m_buffer; + + Window m_xWindow; + EGLConfig m_config; + EGLSurface m_surface; + + bool m_waitingForSync; + static void sync_function(void *data); }; #endif // QWAYLANDXCOMPOSITEEGLWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri index c3533f9ce3..5f86bd9588 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri @@ -1,6 +1,4 @@ include (../xcomposite_share/xcomposite_share.pri) -include (../../../eglconvenience/eglconvenience.pri) -include (../../../eglconvenience/xlibeglintegration.pri) LIBS += -lXcomposite -lEGL diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp index 3d49790f3a..75881a7fdd 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp @@ -39,114 +39,56 @@ ** ****************************************************************************/ +#include <QtCore/QDebug> + #include "qwaylandxcompositeglxcontext.h" #include "qwaylandxcompositeglxwindow.h" -#include "qwaylandxcompositebuffer.h" -#include "wayland-xcomposite-client-protocol.h" -#include <QtCore/QDebug> +#include <QRegion> -#include <X11/extensions/Xcomposite.h> - -QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window) - : QPlatformGLContext() - , mGlxIntegration(glxIntegration) - , mWindow(window) - , mBuffer(0) - , mXWindow(0) - , mConfig(qglx_findConfig(glxIntegration->xDisplay(),glxIntegration->screen(),window->widget()->platformWindowFormat())) - , mWaitingForSyncCallback(false) +QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen) + : m_display(display) { - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(glxIntegration->xDisplay(),mConfig); - mContext = glXCreateContext(glxIntegration->xDisplay(),visualInfo,0,TRUE); - - geometryChanged(); + qDebug("creating XComposite-GLX context"); + GLXContext shareContext = share ? static_cast<QWaylandXCompositeGLXContext *>(share)->m_context : 0; + GLXFBConfig config = qglx_findConfig(display, screen, format); + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(display, config); + m_context = glXCreateContext(display, visualInfo, shareContext, true); + m_format = qglx_surfaceFormatFromGLXFBConfig(display, config, m_context); } -void QWaylandXCompositeGLXContext::makeCurrent() +bool QWaylandXCompositeGLXContext::makeCurrent(QPlatformSurface *surface) { - QPlatformGLContext::makeCurrent(); - glXMakeCurrent(mGlxIntegration->xDisplay(),mXWindow,mContext); + Window xWindow = static_cast<QWaylandXCompositeGLXWindow *>(surface)->xWindow(); + + return glXMakeCurrent(m_display, xWindow, m_context); } void QWaylandXCompositeGLXContext::doneCurrent() { - glXMakeCurrent(mGlxIntegration->xDisplay(),0,0); - QPlatformGLContext::doneCurrent(); + glXMakeCurrent(m_display, 0, 0); } -void QWaylandXCompositeGLXContext::swapBuffers() +void QWaylandXCompositeGLXContext::swapBuffers(QPlatformSurface *surface) { - QSize size = mWindow->geometry().size(); + QWaylandXCompositeGLXWindow *w = static_cast<QWaylandXCompositeGLXWindow *>(surface); - glXSwapBuffers(mGlxIntegration->xDisplay(),mXWindow); - mWindow->damage(QRect(QPoint(0,0),size)); - mWindow->waitForFrameSync(); -} + QSize size = w->geometry().size(); -void * QWaylandXCompositeGLXContext::getProcAddress(const QString &procName) -{ - return (void *) glXGetProcAddress(reinterpret_cast<GLubyte *>(procName.toLatin1().data())); -} + glXSwapBuffers(m_display, w->xWindow()); -QPlatformWindowFormat QWaylandXCompositeGLXContext::platformWindowFormat() const -{ - return qglx_platformWindowFromGLXFBConfig(mGlxIntegration->xDisplay(),mConfig,mContext); + w->damage(QRect(QPoint(), size)); + w->waitForFrameSync(); } -void QWaylandXCompositeGLXContext::sync_function(void *data) +void (*QWaylandXCompositeGLXContext::getProcAddress(const QByteArray &procName)) () { - QWaylandXCompositeGLXContext *that = static_cast<QWaylandXCompositeGLXContext *>(data); - that->mWaitingForSyncCallback = false; + return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData())); } -void QWaylandXCompositeGLXContext::waitForSync() +QSurfaceFormat QWaylandXCompositeGLXContext::format() const { - wl_display_sync_callback(mGlxIntegration->waylandDisplay()->wl_display(), - QWaylandXCompositeGLXContext::sync_function, - this); - mWaitingForSyncCallback = true; - wl_display_sync(mGlxIntegration->waylandDisplay()->wl_display(),0); - mGlxIntegration->waylandDisplay()->flushRequests(); - while (mWaitingForSyncCallback) { - mGlxIntegration->waylandDisplay()->readEvents(); - } + return m_format; } -void QWaylandXCompositeGLXContext::geometryChanged() -{ - QSize size(mWindow->geometry().size()); - if (size.isEmpty()) { - //QGLWidget wants a context for a window without geometry - size = QSize(1,1); - } - - delete mBuffer; - //XFreePixmap deletes the glxPixmap as well - if (mXWindow) { - XDestroyWindow(mGlxIntegration->xDisplay(),mXWindow); - } - - XVisualInfo *visualInfo = glXGetVisualFromFBConfig(mGlxIntegration->xDisplay(),mConfig); - Colormap cmap = XCreateColormap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),visualInfo->visual,AllocNone); - - XSetWindowAttributes a; - a.background_pixel = WhitePixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen()); - a.border_pixel = BlackPixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen()); - a.colormap = cmap; - mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(), - 0, visualInfo->depth, InputOutput, visualInfo->visual, - CWBackPixel|CWBorderPixel|CWColormap, &a); - - XCompositeRedirectWindow(mGlxIntegration->xDisplay(), mXWindow, CompositeRedirectManual); - XMapWindow(mGlxIntegration->xDisplay(), mXWindow); - - XSync(mGlxIntegration->xDisplay(),False); - mBuffer = new QWaylandXCompositeBuffer(mGlxIntegration->waylandXComposite(), - (uint32_t)mXWindow, - size, - mGlxIntegration->waylandDisplay()->argbVisual()); - mWindow->attach(mBuffer); - waitForSync(); -} diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h index b6ee2bbc23..3364d88ec4 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h @@ -42,44 +42,33 @@ #ifndef QWAYLANDXCOMPOSITEGLXCONTEXT_H #define QWAYLANDXCOMPOSITEGLXCONTEXT_H -#include <QtGui/QPlatformGLContext> +#include <QtGui/QPlatformOpenGLContext> -#include <QtCore/QWaitCondition> - -#include "qwaylandbuffer.h" #include "qwaylandxcompositeglxintegration.h" - -#include "qglxconvenience.h" +#include <QtPlatformSupport/private/qglxconvenience_p.h> class QWaylandXCompositeGLXWindow; class QWaylandShmBuffer; -class QWaylandXCompositeGLXContext : public QPlatformGLContext +class QWaylandXCompositeGLXContext : public QPlatformOpenGLContext { public: - QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window); + QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen); - void makeCurrent(); - void doneCurrent(); - void swapBuffers(); - void* getProcAddress(const QString& procName); + QSurfaceFormat format() const; - QPlatformWindowFormat platformWindowFormat() const; + void swapBuffers(QPlatformSurface *surface); - void geometryChanged(); + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); -private: - QWaylandXCompositeGLXIntegration *mGlxIntegration; - QWaylandXCompositeGLXWindow *mWindow; - QWaylandBuffer *mBuffer; + void (*getProcAddress(const QByteArray &procName)) (); - Window mXWindow; - GLXFBConfig mConfig; - GLXContext mContext; +private: + GLXContext m_context; - static void sync_function(void *data); - void waitForSync(); - bool mWaitingForSyncCallback; + Display *m_display; + QSurfaceFormat m_format; }; #endif // QWAYLANDXCOMPOSITEGLXCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp index e8dbea48c6..e1eb2e635a 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp @@ -52,12 +52,15 @@ QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDispl return new QWaylandXCompositeGLXIntegration(waylandDisplay); } -QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly) - : QWaylandGLIntegration() - , mWaylandDisplay(waylandDispaly) +QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay *waylandDisplay) + : mWaylandDisplay(waylandDisplay) + , mWaylandComposite(0) + , mDisplay(0) + , mScreen(0) + , mRootWindow(0) { qDebug() << "Using XComposite-GLX"; - wl_display_add_global_listener(waylandDispaly->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal, + wl_display_add_global_listener(waylandDisplay->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal, this); } @@ -70,9 +73,14 @@ void QWaylandXCompositeGLXIntegration::initialize() { } -QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWidget *widget) +QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWindow *window) { - return new QWaylandXCompositeGLXWindow(widget,this); + return new QWaylandXCompositeGLXWindow(window, this); +} + +QPlatformOpenGLContext *QWaylandXCompositeGLXIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandXCompositeGLXContext(glFormat, share, mDisplay, mScreen); } Display * QWaylandXCompositeGLXIntegration::xDisplay() const @@ -107,6 +115,7 @@ void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display { Q_UNUSED(version); if (strcmp(interface, "wl_xcomposite") == 0) { + qDebug("XComposite-GLX: got wl_xcomposite global"); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); integration->mWaylandComposite = wl_xcomposite_create(display,id,1); wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); @@ -119,6 +128,8 @@ void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite Q_UNUSED(xcomposite); QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); + qDebug("XComposite-GLX: xcomposite listener callback"); + integration->mDisplay = XOpenDisplay(display_name); integration->mRootWindow = (Window) root_window; integration->mScreen = XDefaultScreen(integration->mDisplay); diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h index 17f2f6d4e4..b028067d8e 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h @@ -49,7 +49,7 @@ #include <QtCore/QDataStream> #include <QtCore/QMetaType> #include <QtCore/QVariant> -#include <QtGui/QWidget> +#include <QtGui/QWindow> #include <X11/Xlib.h> @@ -63,7 +63,8 @@ public: void initialize(); - QWaylandWindow *createEglWindow(QWidget *widget); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; QWaylandDisplay *waylandDisplay() const; struct wl_xcomposite *waylandXComposite() const; diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp index cd7ae1964c..abaf3b16a9 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp @@ -40,15 +40,24 @@ ****************************************************************************/ #include "qwaylandxcompositeglxwindow.h" +#include "qwaylandxcompositebuffer.h" #include <QtCore/QDebug> -QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration) +#include "wayland-xcomposite-client-protocol.h" +#include <QtGui/QRegion> + +#include <X11/extensions/Xcomposite.h> + + +QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration) : QWaylandWindow(window) - , mGlxIntegration(glxIntegration) - , mContext(0) + , m_glxIntegration(glxIntegration) + , m_xWindow(0) + , m_config(qglx_findConfig(glxIntegration->xDisplay(), glxIntegration->screen(), window->format())) + , m_buffer(0) + , m_waitingForSync(false) { - } QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const @@ -57,21 +66,79 @@ QWaylandWindow::WindowType QWaylandXCompositeGLXWindow::windowType() const return QWaylandWindow::Egl; } -QPlatformGLContext * QWaylandXCompositeGLXWindow::glContext() const +void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect) { - if (!mContext) { - qDebug() << "creating glcontext;"; - QWaylandXCompositeGLXWindow *that = const_cast<QWaylandXCompositeGLXWindow *>(this); - that->mContext = new QWaylandXCompositeGLXContext(mGlxIntegration,that); + QWaylandWindow::setGeometry(rect); + + if (m_xWindow) { + delete m_buffer; + + XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow); + m_xWindow = 0; } - return mContext; } -void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect) +Window QWaylandXCompositeGLXWindow::xWindow() const { - QWaylandWindow::setGeometry(rect); + if (!m_xWindow) + const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface(); - if (mContext) { - mContext->geometryChanged(); + return m_xWindow; +} + +void QWaylandXCompositeGLXWindow::waitForSync() +{ + wl_display_sync_callback(m_glxIntegration->waylandDisplay()->wl_display(), + QWaylandXCompositeGLXWindow::sync_function, + this); + m_waitingForSync= true; + wl_display_sync(m_glxIntegration->waylandDisplay()->wl_display(), 0); + m_glxIntegration->waylandDisplay()->flushRequests(); + while (m_waitingForSync) + m_glxIntegration->waylandDisplay()->readEvents(); +} + + +void QWaylandXCompositeGLXWindow::createSurface() +{ + QSize size(geometry().size()); + if (size.isEmpty()) { + //QGLWidget wants a context for a window without geometry + size = QSize(1,1); } + + if (!m_glxIntegration->xDisplay()) { + qWarning("XCompositeGLXWindow: X display still null?!"); + return; + } + + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_glxIntegration->xDisplay(), m_config); + Colormap cmap = XCreateColormap(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(), + visualInfo->visual, AllocNone); + + XSetWindowAttributes a; + a.background_pixel = WhitePixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen()); + a.border_pixel = BlackPixel(m_glxIntegration->xDisplay(), m_glxIntegration->screen()); + a.colormap = cmap; + m_xWindow = XCreateWindow(m_glxIntegration->xDisplay(), m_glxIntegration->rootWindow(),0, 0, size.width(), size.height(), + 0, visualInfo->depth, InputOutput, visualInfo->visual, + CWBackPixel|CWBorderPixel|CWColormap, &a); + + XCompositeRedirectWindow(m_glxIntegration->xDisplay(), m_xWindow, CompositeRedirectManual); + XMapWindow(m_glxIntegration->xDisplay(), m_xWindow); + + XSync(m_glxIntegration->xDisplay(), False); + m_buffer = new QWaylandXCompositeBuffer(m_glxIntegration->waylandXComposite(), + (uint32_t)m_xWindow, + size, + m_glxIntegration->waylandDisplay()->argbVisual()); + attach(m_buffer); + waitForSync(); +} + +void QWaylandXCompositeGLXWindow::sync_function(void *data) +{ + QWaylandXCompositeGLXWindow *that = static_cast<QWaylandXCompositeGLXWindow *>(data); + that->m_waitingForSync = false; } + diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h index 8808f2d482..acf6c8e63e 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h @@ -46,20 +46,34 @@ #include "qwaylandxcompositeglxintegration.h" #include "qwaylandxcompositeglxcontext.h" +#include <QtCore/QWaitCondition> + +#include "qwaylandbuffer.h" + class QWaylandXCompositeGLXWindow : public QWaylandWindow { public: - QWaylandXCompositeGLXWindow(QWidget *window, QWaylandXCompositeGLXIntegration *glxIntegration); + QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration); WindowType windowType() const; - QPlatformGLContext *glContext() const; - void setGeometry(const QRect &rect); + Window xWindow() const; + private: - QWaylandXCompositeGLXIntegration *mGlxIntegration; - QWaylandXCompositeGLXContext *mContext; + void createSurface(); + + QWaylandXCompositeGLXIntegration *m_glxIntegration; + + Window m_xWindow; + GLXFBConfig m_config; + + QWaylandBuffer *m_buffer; + + void waitForSync(); + bool m_waitingForSync; + static void sync_function(void *data); }; #endif // QWAYLANDXCOMPOSITEGLXWINDOW_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri index 43295e91e7..bbd6c12e42 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri @@ -1,5 +1,4 @@ include (../xcomposite_share/xcomposite_share.pri) -include (../../../glxconvenience/glxconvenience.pri) LIBS += -lXcomposite SOURCES += \ diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp index 7d309ef877..f4bacc3c1f 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp @@ -42,6 +42,7 @@ #include "qwaylandxcompositebuffer.h" #include "wayland-client.h" +#include "wayland-xcomposite-client-protocol.h" QWaylandXCompositeBuffer::QWaylandXCompositeBuffer(wl_xcomposite *xcomposite, uint32_t window, const QSize &size, wl_visual *visual) :mSize(size) diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h index cbd40ad381..02176d7850 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h @@ -43,8 +43,10 @@ #define QWAYLANDXCOMPOSITEBUFFER_H #include "qwaylandbuffer.h" +#include <stdint.h> -#include "wayland-xcomposite-client-protocol.h" +struct wl_xcomposite; +struct wl_visual; class QWaylandXCompositeBuffer : public QWaylandBuffer { diff --git a/src/plugins/platforms/wayland/main.cpp b/src/plugins/platforms/wayland/main.cpp index ba365ca3a1..e4d420d68a 100644 --- a/src/plugins/platforms/wayland/main.cpp +++ b/src/plugins/platforms/wayland/main.cpp @@ -54,8 +54,7 @@ public: QStringList QWaylandIntegrationPlugin::keys() const { QStringList list; - list << "Wayland"; - list << "WaylandGL"; + list << "wayland"; return list; } @@ -63,9 +62,7 @@ QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, c { Q_UNUSED(paramList); if (system.toLower() == "wayland") - return new QWaylandIntegration; - if (system.toLower() == "waylandgl") - return new QWaylandIntegration(true); + return new QWaylandIntegration(); return 0; } diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp index 45f0abc00a..f90d1a9802 100644 --- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp @@ -44,7 +44,7 @@ #include "qwaylandinputdevice.h" #include "qwaylandmime.h" #include <QtGui/QPlatformNativeInterface> -#include <QtGui/QApplication> +#include <QtGui/QGuiApplication> #include <QtCore/QMimeData> #include <QtCore/QStringList> #include <QtCore/QFile> diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp index 87b846cefb..bbbab6dca7 100644 --- a/src/plugins/platforms/wayland/qwaylandcursor.cpp +++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp @@ -43,10 +43,11 @@ #include "qwaylanddisplay.h" #include "qwaylandinputdevice.h" -#include "qwaylandshmsurface.h" #include "qwaylandscreen.h" +#include "qwaylandshmbackingstore.h" #include <QtGui/QImageReader> +#include <QDebug> #define DATADIR "/usr/share" @@ -108,14 +109,15 @@ QWaylandCursor::QWaylandCursor(QWaylandScreen *screen) { } -void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget) +void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) { const struct pointer_image *p; - if (widget == NULL) + if (window == NULL) return; p = NULL; + bool isBitmap = false; switch (cursor->shape()) { case Qt::ArrowCursor: @@ -152,32 +154,53 @@ void QWaylandCursor::changeCursor(QCursor *cursor, QWidget *widget) p = &pointer_images[cursor->shape()]; break; - default: case Qt::BitmapCursor: + isBitmap = true; + break; + + default: break; } - if (!p) { + if (!p && !isBitmap) { p = &pointer_images[0]; qWarning("unhandled cursor %d", cursor->shape()); } - QImageReader reader(p->filename); - - if (!reader.canRead()) - return; - - if (mBuffer == NULL || mBuffer->size() != reader.size()) { - if (mBuffer) + if (isBitmap && !cursor->pixmap().isNull()) { + setupPixmapCursor(cursor); + } else if (isBitmap && cursor->bitmap()) { + qWarning("unsupported QBitmap cursor"); + } else { + QImageReader reader(p->filename); + if (!reader.canRead()) + return; + if (mBuffer == NULL || mBuffer->size() != reader.size()) { delete mBuffer; + mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(), + QImage::Format_ARGB32); + } + reader.read(mBuffer->image()); + mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y); + } +} - mBuffer = new QWaylandShmBuffer(mDisplay, reader.size(), +void QWaylandCursor::setupPixmapCursor(QCursor *cursor) +{ + if (!cursor) { + delete mBuffer; + mBuffer = 0; + return; + } + if (!mBuffer || mBuffer->size() != cursor->pixmap().size()) { + delete mBuffer; + mBuffer = new QWaylandShmBuffer(mDisplay, cursor->pixmap().size(), QImage::Format_ARGB32); } - - reader.read(mBuffer->image()); - - mDisplay->setCursor(mBuffer, p->hotspot_x, p->hotspot_y); + QImage src = cursor->pixmap().toImage().convertToFormat(QImage::Format_ARGB32); + for (int y = 0; y < src.height(); ++y) + qMemCopy(mBuffer->image()->scanLine(y), src.scanLine(y), src.bytesPerLine()); + mDisplay->setCursor(mBuffer, cursor->hotSpot().x(), cursor->hotSpot().y()); } void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y) @@ -189,3 +212,19 @@ void QWaylandDisplay::setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y) inputDevice->attach(buffer, x, y); } } + +void QWaylandCursor::pointerEvent(const QMouseEvent &event) +{ + mLastPos = event.globalPos(); +} + +QPoint QWaylandCursor::pos() const +{ + return mLastPos; +} + +void QWaylandCursor::setPos(const QPoint &pos) +{ + Q_UNUSED(pos); + qWarning() << "QWaylandCursor::setPos: not implemented"; +} diff --git a/src/plugins/platforms/wayland/qwaylandcursor.h b/src/plugins/platforms/wayland/qwaylandcursor.h index 236bfc56ee..8753aa5698 100644 --- a/src/plugins/platforms/wayland/qwaylandcursor.h +++ b/src/plugins/platforms/wayland/qwaylandcursor.h @@ -48,13 +48,23 @@ class QWaylandShmBuffer; class QWaylandDisplay; class QWaylandScreen; -class QWaylandCursor : QPlatformCursor { +class QWaylandCursor : public QPlatformCursor +{ public: QWaylandCursor(QWaylandScreen *screen); - void changeCursor(QCursor *cursor, QWidget *widget); + void changeCursor(QCursor *cursor, QWindow *window); + void pointerEvent(const QMouseEvent &event); + QPoint pos() const; + void setPos(const QPoint &pos); + + void setupPixmapCursor(QCursor *cursor); + QWaylandShmBuffer *mBuffer; QWaylandDisplay *mDisplay; + +private: + QPoint mLastPos; }; #endif // QWAYLANDCURSOR_H diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 26e0e8ebeb..588096933c 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -46,6 +46,7 @@ #include "qwaylandcursor.h" #include "qwaylandinputdevice.h" #include "qwaylandclipboard.h" +#include "qwaylanddnd.h" #ifdef QT_WAYLAND_GL_SUPPORT #include "gl_integration/qwaylandglintegration.h" @@ -56,8 +57,7 @@ #endif #include <QtCore/QAbstractEventDispatcher> -#include <QtGui/QApplication> -#include <QtGui/private/qapplication_p.h> +#include <QtGui/private/qguiapplication_p.h> #include <unistd.h> #include <fcntl.h> @@ -142,6 +142,13 @@ QWaylandDisplay::QWaylandDisplay(void) wl_display_add_global_listener(mDisplay, QWaylandDisplay::displayHandleGlobal, this); + mFd = wl_display_get_fd(mDisplay, sourceUpdate, this); + QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; + connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(flushRequests())); + + mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this); + connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents())); + #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif @@ -156,13 +163,6 @@ QWaylandDisplay::QWaylandDisplay(void) mEglIntegration->initialize(); #endif - connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(flushRequests())); - - mFd = wl_display_get_fd(mDisplay, sourceUpdate, this); - - mReadNotifier = new QSocketNotifier(mFd, QSocketNotifier::Read, this); - connect(mReadNotifier, SIGNAL(activated(int)), this, SLOT(readEvents())); - waitForScreens(); } @@ -313,6 +313,8 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id, mInputDevices.append(inputDevice); } else if (interface == "wl_selection_offer") { QWaylandClipboard::instance(display)->createSelectionOffer(id); + } else if (interface == "wl_drag_offer") { + QWaylandDrag::instance(display)->createDragOffer(id); } } diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h index 4dff24d086..2b7f33f4f6 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -49,6 +49,7 @@ #include <wayland-client.h> +class QAbstractEventDispatcher; class QWaylandInputDevice; class QSocketNotifier; class QWaylandBuffer; @@ -142,6 +143,7 @@ private: static void handleVisual(void *data, struct wl_compositor *compositor, uint32_t id, uint32_t token); + #ifdef QT_WAYLAND_GL_SUPPORT QWaylandGLIntegration *mEglIntegration; #endif diff --git a/src/plugins/platforms/wayland/qwaylanddnd.cpp b/src/plugins/platforms/wayland/qwaylanddnd.cpp new file mode 100644 index 0000000000..5368daaf63 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylanddnd.cpp @@ -0,0 +1,423 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylanddnd.h" +#include "qwaylandinputdevice.h" +#include <QStringList> +#include <QFile> +#include <QtGui/private/qdnd_p.h> +#include <QGuiApplication> +#include <QSocketNotifier> +#include <sys/time.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <QDebug> + +#include <QPlatformCursor> +#include "qwaylandcursor.h" + +class QWaylandDragWrapper +{ +public: + QWaylandDragWrapper(QWaylandDisplay *display, QMimeData *data); + ~QWaylandDragWrapper(); + QMimeData *mimeData() const { return mData; } + +private: + static void target(void *data, wl_drag *drag, const char *mimeType); + static void finish(void *data, wl_drag *drag, int fd); + static void reject(void *data, wl_drag *drag); + static const wl_drag_listener dragListener; + + QWaylandDisplay *mDisplay; + wl_drag *mDrag; + QMimeData *mData; + QString mAcceptedType; +}; + +class QWaylandDragOfferWrapper +{ +public: + QWaylandDragOfferWrapper(QWaylandDisplay *display, QMimeData *data, uint32_t id); + ~QWaylandDragOfferWrapper(); + +private: + static void offer(void *data, struct wl_drag_offer *offer, const char *mimeType); + static void pointerFocus(void *data, struct wl_drag_offer *offer, uint32_t time, + wl_surface *surface, + int32_t x, int32_t y, + int32_t surfaceX, int32_t surfaceY); + static void motion(void *data, struct wl_drag_offer *offer, uint32_t time, + int32_t x, int32_t y, + int32_t surfaceX, int32_t surfaceY); + static void drop(void *data, struct wl_drag_offer *offer); + static const wl_drag_offer_listener dragOfferListener; + + void sendEventToWindow(struct wl_drag_offer *offer, uint32_t time, + wl_surface *surface, const QPoint &pos); + + QWaylandDisplay *mDisplay; + QMimeData *mData; + struct wl_drag_offer *mOffer; + QMimeData mOfferedTypes; // no data in this one, just the formats + wl_surface *mFocusSurface; + bool mAccepted; + QPoint mLastEventPos; + friend class QWaylandDrag; +}; + +static QWaylandDrag *dnd = 0; + +QWaylandDrag *QWaylandDrag::instance(QWaylandDisplay *display) +{ + if (!dnd) + dnd = new QWaylandDrag(display); + return dnd; +} + +QWaylandDrag::QWaylandDrag(QWaylandDisplay *display) + : mDisplay(display), mDropData(0), mCurrentDrag(0), mCurrentOffer(0) +{ + mDropData = new QMimeData; +} + +QWaylandDrag::~QWaylandDrag() +{ + delete mCurrentDrag; + delete mCurrentOffer; + delete mDropData; +} + +QMimeData *QWaylandDrag::platformDropData() +{ + return mDropData; +} + +static void showDragPixmap(bool show) +{ + QCursor c(QDragManager::self()->object->pixmap()); + QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances(); + foreach (QWeakPointer<QPlatformCursor> cursor, cursors) + if (cursor) + static_cast<QWaylandCursor *>(cursor.data())->setupPixmapCursor(show ? &c : 0); +} + + +QWaylandDragWrapper::QWaylandDragWrapper(QWaylandDisplay *display, QMimeData *data) + : mDisplay(display), mDrag(0), mData(data) +{ + QWaylandWindow *w = mDisplay->inputDevices().at(0)->pointerFocus(); + if (!w) { + qWarning("QWaylandDragWrapper: No window with pointer focus?!"); + return; + } + qDebug() << "QWaylandDragWrapper" << data->formats(); + struct wl_shell *shell = display->wl_shell(); + mDrag = wl_shell_create_drag(shell); + wl_drag_add_listener(mDrag, &dragListener, this); + foreach (const QString &format, data->formats()) + wl_drag_offer(mDrag, format.toLatin1().constData()); + struct timeval tv; + gettimeofday(&tv, 0); + wl_drag_activate(mDrag, + w->wl_surface(), + display->inputDevices().at(0)->wl_input_device(), + tv.tv_sec * 1000 + tv.tv_usec / 1000); + showDragPixmap(true); +} + +QWaylandDragWrapper::~QWaylandDragWrapper() +{ + QWaylandDrag *dragHandler = QWaylandDrag::instance(mDisplay); + if (dragHandler->mCurrentDrag == this) + dragHandler->mCurrentDrag = 0; + wl_drag_destroy(mDrag); +} + +const wl_drag_listener QWaylandDragWrapper::dragListener = { + QWaylandDragWrapper::target, + QWaylandDragWrapper::finish, + QWaylandDragWrapper::reject +}; + +void QWaylandDragWrapper::target(void *data, wl_drag *drag, const char *mimeType) +{ + Q_UNUSED(drag); + QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data); + self->mAcceptedType = mimeType ? QString::fromLatin1(mimeType) : QString(); + qDebug() << "target" << self->mAcceptedType; + QDragManager *manager = QDragManager::self(); + if (mimeType) + manager->global_accepted_action = manager->defaultAction(manager->possible_actions, + QGuiApplication::keyboardModifiers()); + else + manager->global_accepted_action = Qt::IgnoreAction; +} + +void QWaylandDragWrapper::finish(void *data, wl_drag *drag, int fd) +{ + Q_UNUSED(drag); + QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data); + qDebug() << "finish" << self->mAcceptedType; + if (self->mAcceptedType.isEmpty()) + return; // no drag target was valid when the drag finished + QByteArray content = self->mData->data(self->mAcceptedType); + if (!content.isEmpty()) { + QFile f; + if (f.open(fd, QIODevice::WriteOnly)) + f.write(content); + } + close(fd); + // Drag finished on source side with drop. + + QDragManager::self()->stopDrag(); + showDragPixmap(false); + delete self; + qDebug() << " *** DRAG OVER WITH DROP"; +} + +void QWaylandDragWrapper::reject(void *data, wl_drag *drag) +{ + Q_UNUSED(drag); + QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data); + self->mAcceptedType = QString(); + qDebug() << "reject"; + QDragManager::self()->global_accepted_action = Qt::IgnoreAction; +} + + +QWaylandDragOfferWrapper::QWaylandDragOfferWrapper(QWaylandDisplay *display, + QMimeData *data, + uint32_t id) + : mDisplay(display), mData(data), mOffer(0), mFocusSurface(0), + mAccepted(false) +{ + mOffer = wl_drag_offer_create(mDisplay->wl_display(), id, 1); + wl_drag_offer_add_listener(mOffer, &dragOfferListener, this); +} + +QWaylandDragOfferWrapper::~QWaylandDragOfferWrapper() +{ + QWaylandDrag *dragHandler = QWaylandDrag::instance(mDisplay); + if (dragHandler->mCurrentOffer == this) + dragHandler->mCurrentOffer = 0; + wl_drag_offer_destroy(mOffer); +} + +const wl_drag_offer_listener QWaylandDragOfferWrapper::dragOfferListener = { + QWaylandDragOfferWrapper::offer, + QWaylandDragOfferWrapper::pointerFocus, + QWaylandDragOfferWrapper::motion, + QWaylandDragOfferWrapper::drop +}; + +void QWaylandDragOfferWrapper::offer(void *data, struct wl_drag_offer *offer, const char *mimeType) +{ + // Called for each type before pointerFocus. + Q_UNUSED(offer); + QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data); + self->mOfferedTypes.setData(QString::fromLatin1(mimeType), QByteArray()); +} + +void QWaylandDragOfferWrapper::pointerFocus(void *data, struct wl_drag_offer *offer, uint32_t time, + wl_surface *surface, + int32_t x, int32_t y, + int32_t surfaceX, int32_t surfaceY) +{ + qDebug() << "pointerFocus" << surface << x << y << surfaceX << surfaceY; + QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data); + QWaylandDrag *mgr = QWaylandDrag::instance(self->mDisplay); + + if (!surface) { + if (self->mFocusSurface) { + // This is a DragLeave. + QWindow *window = static_cast<QWaylandWindow *>( + wl_surface_get_user_data(self->mFocusSurface))->window(); + QWindowSystemInterface::handleDrag(window, 0, QPoint()); + if (self->mAccepted) { + wl_drag_offer_reject(offer); + self->mAccepted = false; + } + if (!mgr->mCurrentDrag) // no drag -> this is not the source side -> offer can be destroyed + delete mgr->mCurrentOffer; + } else { + // Drag finished on source side without drop. + QDragManager::self()->stopDrag(); + showDragPixmap(false); + delete mgr->mCurrentDrag; + qDebug() << " *** DRAG OVER WITHOUT DROP"; + } + } + + self->mFocusSurface = surface; + + // This is a DragMove or DragEnter+DragMove. + if (surface) + self->sendEventToWindow(offer, time, surface, QPoint(surfaceX, surfaceY)); +} + +void QWaylandDragOfferWrapper::motion(void *data, struct wl_drag_offer *offer, uint32_t time, + int32_t x, int32_t y, + int32_t surfaceX, int32_t surfaceY) +{ + Q_UNUSED(x); + Q_UNUSED(y); + QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data); + if (!self->mFocusSurface) + return; +// qDebug() << "motion" << self->mFocusSurface << x << y << surfaceX << surfaceY; + self->sendEventToWindow(offer, time, self->mFocusSurface, QPoint(surfaceX, surfaceY)); +} + +void QWaylandDragOfferWrapper::sendEventToWindow(struct wl_drag_offer *offer, uint32_t time, + wl_surface *surface, const QPoint &pos) +{ + QWindow *window = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface))->window(); + Qt::DropAction action = QWindowSystemInterface::handleDrag(window, &mOfferedTypes, pos); + bool accepted = (action != Qt::IgnoreAction && !mOfferedTypes.formats().isEmpty()); + if (accepted != mAccepted) { + mAccepted = accepted; + if (mAccepted) { + // What can we do, just accept the first type... + QByteArray ba = mOfferedTypes.formats().first().toLatin1(); + qDebug() << "wl_drag_offer_accept" << ba; + wl_drag_offer_accept(offer, time, ba.constData()); + } else { + qDebug() << "wl_drag_offer_reject"; + wl_drag_offer_reject(offer); + } + } + mLastEventPos = pos; +} + +void QWaylandDragOfferWrapper::drop(void *data, struct wl_drag_offer *offer) +{ + QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data); + if (!self->mAccepted) { + wl_drag_offer_reject(offer); + return; + } + + QWaylandDrag *mgr = QWaylandDrag::instance(self->mDisplay); + QMimeData *mimeData = QWaylandDrag::instance(self->mDisplay)->platformDropData(); + mimeData->clear(); + if (mgr->mCurrentDrag) { // means this offer is the client's own + QMimeData *localData = mgr->mCurrentDrag->mimeData(); + foreach (const QString &format, localData->formats()) + mimeData->setData(format, localData->data(format)); + QWindow *window = static_cast<QWaylandWindow *>( + wl_surface_get_user_data(self->mFocusSurface))->window(); + QWindowSystemInterface::handleDrop(window, mimeData, self->mLastEventPos); + // Drag finished with drop (source == target). + QDragManager::self()->stopDrag(); + showDragPixmap(false); + delete mgr->mCurrentOffer; + qDebug() << " *** DRAG OVER WITH DROP, SOURCE == TARGET"; + } else { + // ### TODO + // This is a bit broken: The QMimeData will only contain the data for + // the first type. The Wayland protocol and QDropEvents/QMimeData do not + // match perfectly at the moment. + QString format = self->mOfferedTypes.formats().first(); + QByteArray mimeTypeBa = format.toLatin1(); + int pipefd[2]; + if (pipe(pipefd) == -1) { + qWarning("QWaylandDragOfferWrapper: pipe() failed"); + return; + } + fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL, 0) | O_NONBLOCK); + wl_drag_offer_receive(offer, pipefd[1]); + mgr->mPipeData.clear(); + mgr->mMimeFormat = format; + mgr->mPipeWriteEnd = pipefd[1]; + mgr->mPipeWatcher = new QSocketNotifier(pipefd[0], QSocketNotifier::Read); + QObject::connect(mgr->mPipeWatcher, SIGNAL(activated(int)), mgr, SLOT(pipeReadable(int))); + } +} + + +void QWaylandDrag::pipeReadable(int fd) +{ + if (mPipeWriteEnd) { + close(mPipeWriteEnd); + mPipeWriteEnd = 0; + } + char buf[256]; + int n; + while ((n = read(fd, &buf, sizeof buf)) > 0 || errno == EINTR) + if (n > 0) + mPipeData.append(buf, n); + if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) + return; + delete mPipeWatcher; + close(fd); + + QMimeData *mimeData = platformDropData(); + mimeData->setData(mMimeFormat, mPipeData); + foreach (const QString &format, mimeData->formats()) + qDebug() << " got type" << format << "with data" << mimeData->data(format); + + QWindow *window = static_cast<QWaylandWindow *>( + wl_surface_get_user_data(mCurrentOffer->mFocusSurface))->window(); + QWindowSystemInterface::handleDrop(window, mimeData, mCurrentOffer->mLastEventPos); + + // Drag finished on target side with drop. + delete mCurrentOffer; + qDebug() << " *** DRAG OVER ON TARGET WITH DROP"; +} + +void QWaylandDrag::createDragOffer(uint32_t id) +{ + delete mCurrentOffer; + mCurrentOffer = new QWaylandDragOfferWrapper(mDisplay, mDropData, id); +} + +void QWaylandDrag::startDrag() +{ + QDragManager *manager = QDragManager::self(); + + // No need for the traditional desktop-oriented event handling in QDragManager. + manager->unmanageEvents(); + + delete mCurrentDrag; + mCurrentDrag = new QWaylandDragWrapper(mDisplay, manager->dropData()); +} diff --git a/src/plugins/platforms/wayland/qwaylanddnd.h b/src/plugins/platforms/wayland/qwaylanddnd.h new file mode 100644 index 0000000000..ebafd960ec --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylanddnd.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDDND_H +#define QWAYLANDDND_H + +#include <QtGui/QPlatformDrag> +#include <QtCore/QMimeData> +#include "qwaylanddisplay.h" + +class QWaylandDragWrapper; +class QWaylandDragOfferWrapper; +class QSocketNotifier; + +class QWaylandDrag : public QObject, public QPlatformDrag +{ + Q_OBJECT + +public: + static QWaylandDrag *instance(QWaylandDisplay *display); + ~QWaylandDrag(); + void createDragOffer(uint32_t id); + + QMimeData *platformDropData(); + void startDrag(); + void move(const QMouseEvent *) { } + void drop(const QMouseEvent *) { } + void cancel() { } + +private slots: + void pipeReadable(int fd); + +private: + QWaylandDrag(QWaylandDisplay *display); + + QWaylandDisplay *mDisplay; + QMimeData *mDropData; + QWaylandDragWrapper *mCurrentDrag; + QWaylandDragOfferWrapper *mCurrentOffer; + int mPipeWriteEnd; + QSocketNotifier *mPipeWatcher; + QByteArray mPipeData; + QString mMimeFormat; + friend class QWaylandDragWrapper; + friend class QWaylandDragOfferWrapper; +}; + +#endif // QWAYLANDDND_H diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 3c9afafada..c1e2325766 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -113,7 +113,7 @@ void QWaylandInputDevice::inputHandleMotion(void *data, inputDevice->mSurfacePos = QPoint(surface_x, surface_y); inputDevice->mGlobalPos = QPoint(x, y); inputDevice->mTime = time; - QWindowSystemInterface::handleMouseEvent(window->widget(), + QWindowSystemInterface::handleMouseEvent(window->window(), time, inputDevice->mSurfacePos, inputDevice->mGlobalPos, @@ -155,7 +155,7 @@ void QWaylandInputDevice::inputHandleButton(void *data, inputDevice->mButtons &= ~qt_button; inputDevice->mTime = time; - QWindowSystemInterface::handleMouseEvent(window->widget(), + QWindowSystemInterface::handleMouseEvent(window->window(), time, inputDevice->mSurfacePos, inputDevice->mGlobalPos, @@ -272,7 +272,7 @@ void QWaylandInputDevice::inputHandleKey(void *data, sym = translateKey(sym, s, sizeof s); if (window) { - QWindowSystemInterface::handleKeyEvent(window->widget(), + QWindowSystemInterface::handleKeyEvent(window->window(), time, type, sym, inputDevice->mModifiers, QString::fromLatin1(s)); @@ -295,13 +295,13 @@ void QWaylandInputDevice::inputHandlePointerFocus(void *data, if (inputDevice->mPointerFocus) { window = inputDevice->mPointerFocus; - QWindowSystemInterface::handleLeaveEvent(window->widget()); + QWindowSystemInterface::handleLeaveEvent(window->window()); inputDevice->mPointerFocus = NULL; } if (surface) { window = (QWaylandWindow *) wl_surface_get_user_data(surface); - QWindowSystemInterface::handleEnterEvent(window->widget()); + QWindowSystemInterface::handleEnterEvent(window->window()); inputDevice->mPointerFocus = window; } @@ -333,7 +333,7 @@ void QWaylandInputDevice::inputHandleKeyboardFocus(void *data, if (surface) { window = (QWaylandWindow *) wl_surface_get_user_data(surface); inputDevice->mKeyboardFocus = window; - QWindowSystemInterface::handleWindowActivated(window->widget()); + QWindowSystemInterface::handleWindowActivated(window->window()); } else { inputDevice->mKeyboardFocus = NULL; QWindowSystemInterface::handleWindowActivated(0); diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h index 008ecf144d..05ebe05969 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h @@ -63,6 +63,7 @@ public: void attach(QWaylandBuffer *buffer, int x, int y); void handleWindowDestroyed(QWaylandWindow *window); struct wl_input_device *wl_input_device() const { return mInputDevice; } + QWaylandWindow *pointerFocus() const { return mPointerFocus; } private: QWaylandDisplay *mQDisplay; diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 5df71dc936..e17c2f8d95 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -42,30 +42,36 @@ #include "qwaylandintegration.h" #include "qwaylanddisplay.h" -#include "qwaylandshmsurface.h" +#include "qwaylandshmbackingstore.h" #include "qwaylandshmwindow.h" #include "qwaylandnativeinterface.h" #include "qwaylandclipboard.h" +#include "qwaylanddnd.h" -#include "qgenericunixfontdatabase.h" +#include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h" +#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> + +#include <QtGui/private/qguiapplication_p.h> #include <QtGui/QWindowSystemInterface> #include <QtGui/QPlatformCursor> -#include <QtGui/QPlatformWindowFormat> +#include <QtGui/QSurfaceFormat> +#include <QtGui/QOpenGLContext> -#include <QtGui/private/qpixmap_raster_p.h> #ifdef QT_WAYLAND_GL_SUPPORT #include "gl_integration/qwaylandglintegration.h" -#include "gl_integration/qwaylandglwindowsurface.h" -#include <QtOpenGL/private/qpixmapdata_gl_p.h> #endif -QWaylandIntegration::QWaylandIntegration(bool useOpenGL) +QWaylandIntegration::QWaylandIntegration() : mFontDb(new QGenericUnixFontDatabase()) - , mDisplay(new QWaylandDisplay()) - , mUseOpenGL(useOpenGL) + , mEventDispatcher(createUnixEventDispatcher()) , mNativeInterface(new QWaylandNativeInterface) { + QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); + mDisplay = new QWaylandDisplay(); + + foreach (QPlatformScreen *screen, mDisplay->screens()) + screenAdded(screen); } QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const @@ -73,68 +79,63 @@ QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const return mNativeInterface; } -QList<QPlatformScreen *> -QWaylandIntegration::screens() const -{ - return mDisplay->screens(); -} - bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { case ThreadedPixmaps: return true; - case OpenGL: return hasOpenGL(); + case OpenGL: +#ifdef QT_WAYLAND_GL_SUPPORT + return true; +#else + return false; +#endif + case ThreadedOpenGL: + return hasCapability(OpenGL); default: return QPlatformIntegration::hasCapability(cap); } } -QPixmapData *QWaylandIntegration::createPixmapData(QPixmapData::PixelType type) const +QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const { #ifdef QT_WAYLAND_GL_SUPPORT - if (mUseOpenGL) - return new QGLPixmapData(type); + if (window->surfaceType() == QWindow::OpenGLSurface) + return mDisplay->eglIntegration()->createEglWindow(window); #endif - return new QRasterPixmapData(type); + return new QWaylandShmWindow(window); } -QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWidget *widget, WId winId) const +QPlatformOpenGLContext *QWaylandIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - Q_UNUSED(winId); #ifdef QT_WAYLAND_GL_SUPPORT - bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL); - if (useOpenGL) - return mDisplay->eglIntegration()->createEglWindow(widget); + return mDisplay->eglIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle()); +#else + Q_UNUSED(glFormat); + Q_UNUSED(share); + return 0; #endif - return new QWaylandShmWindow(widget); } -QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId winId) const +QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const { - Q_UNUSED(winId); - Q_UNUSED(winId); -#ifdef QT_WAYLAND_GL_SUPPORT - bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL); - if (useOpenGL) - return new QWaylandGLWindowSurface(widget); -#endif - return new QWaylandShmWindowSurface(widget); + return new QWaylandShmBackingStore(window); } -QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const +QAbstractEventDispatcher *QWaylandIntegration::guiThreadEventDispatcher() const { - return mFontDb; + return mEventDispatcher; } -bool QWaylandIntegration::hasOpenGL() const +QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const { -#ifdef QT_WAYLAND_GL_SUPPORT - return true; -#else - return false; -#endif + return mFontDb; } QPlatformClipboard *QWaylandIntegration::clipboard() const { return QWaylandClipboard::instance(mDisplay); } + +QPlatformDrag *QWaylandIntegration::drag() const +{ + return QWaylandDrag::instance(mDisplay); +} diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index f617d9697b..61e8559a7d 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -48,18 +48,19 @@ QT_BEGIN_NAMESPACE class QWaylandBuffer; class QWaylandDisplay; +class QAbstractEventDispatcher; class QWaylandIntegration : public QPlatformIntegration { public: - QWaylandIntegration(bool useOpenGL = false); + QWaylandIntegration(); bool hasCapability(QPlatformIntegration::Capability cap) const; - QPixmapData *createPixmapData(QPixmapData::PixelType type) const; - QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const; - QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; - QList<QPlatformScreen *> screens() const; + QAbstractEventDispatcher *guiThreadEventDispatcher() const; QPlatformFontDatabase *fontDatabase() const; @@ -67,12 +68,12 @@ public: QPlatformClipboard *clipboard() const; -private: - bool hasOpenGL() const; + QPlatformDrag *drag() const; +private: QPlatformFontDatabase *mFontDb; + QAbstractEventDispatcher *mEventDispatcher; QWaylandDisplay *mDisplay; - bool mUseOpenGL; QPlatformNativeInterface *mNativeInterface; }; diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp index 17736968c6..d81fa350e9 100644 --- a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp @@ -42,34 +42,33 @@ #include "qwaylandnativeinterface.h" #include "qwaylanddisplay.h" #include "qwaylandwindow.h" +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/QScreen> #include "windowmanager_integration/qwaylandwindowmanagerintegration.h" -#include <QtGui/private/qapplication_p.h> -#include <QDebug> - -void *QWaylandNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget) +void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) { QByteArray lowerCaseResource = resourceString.toLower(); if (lowerCaseResource == "display") - return qPlatformScreenForWidget(widget)->display()->wl_display(); + return qPlatformScreenForWindow(window)->display()->wl_display(); if (lowerCaseResource == "surface") { - return ((QWaylandWindow *) widget->platformWindow())->wl_surface(); + return ((QWaylandWindow *) window->handle())->wl_surface(); } return NULL; } -QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWidget(QWidget *widget) +QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWindow(QWindow *window) { QWaylandScreen *screen; - if (widget) { - screen = static_cast<QWaylandScreen *>(QPlatformScreen::platformScreenForWidget(widget)); + if (window) { + screen = static_cast<QWaylandScreen *>(window->screen()->handle()); } else { - screen = static_cast<QWaylandScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]); + screen = static_cast<QWaylandScreen *>(QGuiApplication::primaryScreen()->handle()); } return screen; } diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.h b/src/plugins/platforms/wayland/qwaylandnativeinterface.h index c92b44eb03..9db442a265 100644 --- a/src/plugins/platforms/wayland/qwaylandnativeinterface.h +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.h @@ -49,8 +49,8 @@ class QWaylandNativeInterface : public QPlatformNativeInterface { public: - void *nativeResourceForWidget(const QByteArray &resourceString, - QWidget *widget); + void *nativeResourceForWindow(const QByteArray &resourceString, + QWindow *window); QVariantMap windowProperties(QPlatformWindow *window) const; QVariant windowProperty(QPlatformWindow *window, const QString &name) const; @@ -58,7 +58,7 @@ public: void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value); private: - static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget); + static QWaylandScreen *qPlatformScreenForWindow(QWindow *window); private: QHash<QPlatformWindow*, QVariantMap> m_windowProperties; diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp index be6dcb2e88..7b064bac40 100644 --- a/src/plugins/platforms/wayland/qwaylandscreen.cpp +++ b/src/plugins/platforms/wayland/qwaylandscreen.cpp @@ -53,7 +53,6 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output , mFormat(QImage::Format_ARGB32_Premultiplied) , mWaylandCursor(new QWaylandCursor(this)) { - moveToThread(waylandDisplay->thread()); } QWaylandScreen::~QWaylandScreen() @@ -81,9 +80,9 @@ QImage::Format QWaylandScreen::format() const return mFormat; } -QWaylandScreen * QWaylandScreen::waylandScreenFromWidget(QWidget *widget) +QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window) { - QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWidget(widget); + QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window); return static_cast<QWaylandScreen *>(platformScreen); } diff --git a/src/plugins/platforms/wayland/qwaylandscreen.h b/src/plugins/platforms/wayland/qwaylandscreen.h index f2b3bcefbc..9bf4f6574a 100644 --- a/src/plugins/platforms/wayland/qwaylandscreen.h +++ b/src/plugins/platforms/wayland/qwaylandscreen.h @@ -62,7 +62,7 @@ public: wl_visual *visual() const; - static QWaylandScreen *waylandScreenFromWidget(QWidget *widget); + static QWaylandScreen *waylandScreenFromWindow(QWindow *window); private: QWaylandDisplay *mWaylandDisplay; diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp index b24c419424..25a1b466d4 100644 --- a/src/plugins/platforms/wayland/qwaylandshmsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -38,10 +38,9 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include "qwaylandshmsurface.h" +#include "qwaylandshmbackingstore.h" #include <QtCore/qdebug.h> -#include <QtGui/private/qapplication_p.h> #include "qwaylanddisplay.h" #include "qwaylandshmwindow.h" @@ -91,34 +90,34 @@ QWaylandShmBuffer::~QWaylandShmBuffer(void) wl_buffer_destroy(mBuffer); } -QWaylandShmWindowSurface::QWaylandShmWindowSurface(QWidget *window) - : QWindowSurface(window) +QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window) + : QPlatformBackingStore(window) , mBuffer(0) - , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display()) + , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) { } -QWaylandShmWindowSurface::~QWaylandShmWindowSurface() +QWaylandShmBackingStore::~QWaylandShmBackingStore() { } -QPaintDevice *QWaylandShmWindowSurface::paintDevice() +QPaintDevice *QWaylandShmBackingStore::paintDevice() { return mBuffer->image(); } -void QWaylandShmWindowSurface::beginPaint(const QRegion &) +void QWaylandShmBackingStore::beginPaint(const QRegion &) { - QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow()); + QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); waylandWindow->waitForFrameSync(); } -void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) +void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { - Q_UNUSED(widget); + Q_UNUSED(window); Q_UNUSED(offset); - QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow()); + QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window->handle()); Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); QVector<QRect> rects = region.rects(); for (int i = 0; i < rects.size(); i++) { @@ -128,13 +127,12 @@ void QWaylandShmWindowSurface::flush(QWidget *widget, const QRegion ®ion, con } } -void QWaylandShmWindowSurface::resize(const QSize &size) +void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) { - QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->platformWindow()); + QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); - QWindowSurface::resize(size); - QImage::Format format = QPlatformScreen::platformScreenForWidget(window())->format(); + QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format(); if (mBuffer != NULL && mBuffer->size() == size) return; diff --git a/src/plugins/platforms/wayland/qwaylandshmsurface.h b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h index f3db8b86e5..5e6959dc2f 100644 --- a/src/plugins/platforms/wayland/qwaylandshmsurface.h +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h @@ -39,12 +39,12 @@ ** ****************************************************************************/ -#ifndef QWINDOWSURFACE_WAYLAND_H -#define QWINDOWSURFACE_WAYLAND_H +#ifndef QWAYLANDSHMBACKINGSTORE_H +#define QWAYLANDSHMBACKINGSTORE_H #include "qwaylandbuffer.h" -#include <QtGui/private/qwindowsurface_p.h> - +#include <QtGui/QPlatformBackingStore> +#include <QtGui/QImage> #include <QtGui/QPlatformWindow> QT_BEGIN_NAMESPACE @@ -62,15 +62,15 @@ private: QImage mImage; }; -class QWaylandShmWindowSurface : public QWindowSurface +class QWaylandShmBackingStore : public QPlatformBackingStore { public: - QWaylandShmWindowSurface(QWidget *window); - ~QWaylandShmWindowSurface(); + QWaylandShmBackingStore(QWindow *window); + ~QWaylandShmBackingStore(); QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - void resize(const QSize &size); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); void beginPaint(const QRegion &); private: diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp index a6b7050f7a..ba5e46cab1 100644 --- a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp @@ -47,8 +47,8 @@ #include <QtCore/QDebug> -QWaylandShmWindow::QWaylandShmWindow(QWidget *widget) - : QWaylandWindow(widget) +QWaylandShmWindow::QWaylandShmWindow(QWindow *window) + : QWaylandWindow(window) { newSurfaceCreated(); } @@ -63,9 +63,3 @@ QWaylandWindow::WindowType QWaylandShmWindow::windowType() const return QWaylandWindow::Shm; } -QPlatformGLContext * QWaylandShmWindow::glContext() const -{ - qWarning("Trying to retrieve a glContext from a Raster window surface!"); - return 0; -} - diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h index 8033703391..36f9f225b7 100644 --- a/src/plugins/platforms/wayland/qwaylandshmwindow.h +++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h @@ -48,11 +48,11 @@ class QWaylandShmWindow : public QWaylandWindow { public: - QWaylandShmWindow(QWidget *widget); + QWaylandShmWindow(QWindow *window); ~QWaylandShmWindow(); WindowType windowType() const; - QPlatformGLContext *glContext() const; + QSurfaceFormat format() const { return QSurfaceFormat(); } }; #endif // QWAYLANDSHMWINDOW_H diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 099ebabb06..6011621044 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -46,20 +46,21 @@ #include "qwaylandinputdevice.h" #include "qwaylandscreen.h" +#include <QtGui/QWindow> + #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT #include "windowmanager_integration/qwaylandwindowmanagerintegration.h" #endif #include <QCoreApplication> -#include <QtGui/QWidget> #include <QtGui/QWindowSystemInterface> #include <QDebug> -QWaylandWindow::QWaylandWindow(QWidget *window) +QWaylandWindow::QWaylandWindow(QWindow *window) : QPlatformWindow(window) , mSurface(0) - , mDisplay(QWaylandScreen::waylandScreenFromWidget(window)->display()) + , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) , mBuffer(0) , mWaitingForFrameSync(false) { @@ -112,11 +113,11 @@ void QWaylandWindow::configure(uint32_t time, uint32_t edges, { Q_UNUSED(time); Q_UNUSED(edges); - QRect geometry = QRect(x, y, width, height); + QRect geometry = QRect(x, y, width, height); setGeometry(geometry); - QWindowSystemInterface::handleGeometryChange(widget(), geometry); + QWindowSystemInterface::handleGeometryChange(window(), geometry); } void QWaylandWindow::attach(QWaylandBuffer *buffer) @@ -124,6 +125,7 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer) mBuffer = buffer; if (mSurface) { wl_surface_attach(mSurface, buffer->buffer(),0,0); + QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); } } diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h index b91f6b6eb8..4f1e2c8183 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.h +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -59,7 +59,7 @@ public: Egl }; - QWaylandWindow(QWidget *window); + QWaylandWindow(QWindow *window); ~QWaylandWindow(); virtual WindowType windowType() const = 0; diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro index 1e0bbe6cdd..fd6ffc06de 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -1,19 +1,23 @@ TARGET = qwayland load(qt_plugin) -QT+=gui-private core-private opengl-private +CONFIG += qpa/genericunixfontdatabase DESTDIR = $$QT.gui.plugins/platforms DEFINES += Q_PLATFORM_WAYLAND DEFINES += $$QMAKE_DEFINES_WAYLAND -QT += core-private gui-private opengl-private +mac { + DEFINES += QT_NO_WAYLAND_XKB +} + +QT += core-private gui-private opengl-private platformsupport-private SOURCES = main.cpp \ qwaylandintegration.cpp \ qwaylandnativeinterface.cpp \ - qwaylandshmsurface.cpp \ + qwaylandshmbackingstore.cpp \ qwaylandinputdevice.cpp \ qwaylandcursor.cpp \ qwaylanddisplay.cpp \ @@ -21,6 +25,7 @@ SOURCES = main.cpp \ qwaylandscreen.cpp \ qwaylandshmwindow.cpp \ qwaylandclipboard.cpp \ + qwaylanddnd.cpp \ qwaylandmime.cpp HEADERS = qwaylandintegration.h \ @@ -29,23 +34,23 @@ HEADERS = qwaylandintegration.h \ qwaylanddisplay.h \ qwaylandwindow.h \ qwaylandscreen.h \ - qwaylandshmsurface.h \ + qwaylandshmbackingstore.h \ qwaylandbuffer.h \ qwaylandshmwindow.h \ qwaylandclipboard.h \ + qwaylanddnd.h \ qwaylandmime.h INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND LIBS += $$QMAKE_LIBS_WAYLAND -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND - -INCLUDEPATH += $$PWD +mac { + LIBS += -lwayland-client +} -include ($$PWD/gl_integration/gl_integration.pri) -include ($$PWD/windowmanager_integration/windowmanager_integration.pri) - -include (../fontdatabases/genericunix/genericunix.pri) +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND target.path += $$[QT_INSTALL_PLUGINS]/platforms INSTALLS += target +include ($$PWD/gl_integration/gl_integration.pri) +include ($$PWD/windowmanager_integration/windowmanager_integration.pri) diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp index 798900bbce..7d68571c24 100644 --- a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp +++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp @@ -49,8 +49,7 @@ #include <QtGui/QPlatformNativeInterface> #include <QtGui/QPlatformWindow> #include <QtGui/QtEvents> -#include <QtGui/QWidget> -#include <QtGui/QApplication> +#include <QtGui/QGuiApplication> #include <QDebug> @@ -237,15 +236,15 @@ void QWaylandWindowManagerIntegration::wlHandleWindowPropertyChange(void *data, QPlatformNativeInterface *nativeInterface = qApp->platformNativeInterface(); QWaylandWindowManagerIntegration *inst = QWaylandWindowManagerIntegration::instance(); - QWidgetList widgets = qApp->topLevelWidgets(); - foreach (QWidget *widget, widgets) { - QPlatformWindow *platformWindowForWidget = widget->platformWindow(); - if (!platformWindowForWidget) + QList<QWindow *> windows = qApp->topLevelWindows(); + foreach (QWindow *window, windows) { + QPlatformWindow *platformWindowForWindow = window->handle(); + if (!platformWindowForWindow) continue; - QWaylandWindow *window = static_cast<QWaylandWindow*>(platformWindowForWidget); - wl_surface *windowSurface = (wl_surface*)nativeInterface->nativeResourceForWidget(QByteArray("surface"), widget); + QWaylandWindow *waylandWindow = static_cast<QWaylandWindow*>(platformWindowForWindow); + wl_surface *windowSurface = (wl_surface*)nativeInterface->nativeResourceForWindow(QByteArray("surface"), window); if (windowSurface == surface) { - inst->handleWindowPropertyChange(window, QString(propertyName), variantValue); + inst->handleWindowPropertyChange(waylandWindow, QString(propertyName), variantValue); break; } } |