summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wayland
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wayland')
-rw-r--r--src/plugins/platforms/wayland/gl_integration/gl_integration.pri13
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h8
-rw-r--r--src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp184
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp106
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h (renamed from src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.h)33
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp82
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h71
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp106
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.h70
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_cgl/readback_cgl.pri10
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp16
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h3
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h6
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp101
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h27
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp65
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h18
-rw-r--r--src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp25
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h11
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp80
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h22
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp70
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h28
-rw-r--r--src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp123
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h30
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp9
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h7
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp100
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h22
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri2
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp110
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h33
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp23
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h5
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp95
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h24
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp1
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h4
-rw-r--r--src/plugins/platforms/wayland/main.cpp7
-rw-r--r--src/plugins/platforms/wayland/qwaylandclipboard.cpp2
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.cpp73
-rw-r--r--src/plugins/platforms/wayland/qwaylandcursor.h14
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp20
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylanddnd.cpp423
-rw-r--r--src/plugins/platforms/wayland/qwaylanddnd.h86
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp12
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.h1
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp85
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h17
-rw-r--r--src/plugins/platforms/wayland/qwaylandnativeinterface.cpp17
-rw-r--r--src/plugins/platforms/wayland/qwaylandnativeinterface.h6
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.cpp5
-rw-r--r--src/plugins/platforms/wayland/qwaylandscreen.h2
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp (renamed from src/plugins/platforms/wayland/qwaylandshmsurface.cpp)30
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmbackingstore.h (renamed from src/plugins/platforms/wayland/qwaylandshmsurface.h)18
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.cpp10
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmwindow.h4
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp12
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h2
-rw-r--r--src/plugins/platforms/wayland/wayland.pro27
70 files changed, 1755 insertions, 898 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..2b4f9fe028 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 QPlatformGLContext;
+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 QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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 &region, 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..d0712a3989
--- /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/QGuiGLContext>
+#include <QtCore/QDebug>
+
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/glu.h>
+
+#include <QtPlatformSupport/private/cglconvenience_p.h>
+
+QWaylandReadbackCGLContext::QWaylandReadbackCGLContext(QPlatformGLContext *share)
+ : QPlatformGLContext()
+{
+ 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 (QGuiGLContext::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..7f727ae8f9 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 <QPlatformGLContext>
-#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 QPlatformGLContext
{
public:
- QWaylandGLWindowSurface(QWidget *window);
- ~QWaylandGLWindowSurface();
+ QWaylandReadbackCGLContext(QPlatformGLContext *share);
- void beginPaint(const QRegion &);
+ QSurfaceFormat format() const;
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, 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..c9cc7b4fa1
--- /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);
+}
+
+QPlatformGLContext *QWaylandReadbackCGLIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..63b95f5efa
--- /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);
+ QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..cd6ab188f7 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);
@@ -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..f57ac46667 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h
@@ -43,7 +43,6 @@
#define QWAYLANDREADBACKEGLGLCONTEXT_H
#include <QPlatformGLContext>
-#include <QtGui/QWidget>
#include "qwaylandreadbackeglintegration.h"
#include "qwaylandreadbackeglwindow.h"
@@ -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..773087f513 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);
+}
+
+QPlatformGLContext *QWaylandReadbackEglWindow::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..d96e6cface 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);
+ QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..39ccafec5c 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)
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..63ab7a55ae 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h
@@ -50,7 +50,7 @@ class QWaylandReadbackEglContext;
class QWaylandReadbackEglWindow : public QWaylandShmWindow
{
public:
- QWaylandReadbackEglWindow(QWidget *window, QWaylandReadbackEglIntegration *eglIntegration);
+ QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration);
WindowType windowType() const;
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..dec2cdd428 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/QGuiGLContext>
#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,
+ QPlatformGLContext *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 QGuiGLContext::currentContext()
+ if (QGuiGLContext::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..d3a028f51a 100644
--- a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h
@@ -43,10 +43,11 @@
#define QWAYLANDREADBACKGLXCONTEXT_H
#include <QPlatformGLContext>
+#include <QSurfaceFormat>
#include "qwaylandreadbackglxintegration.h"
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
class QWaylandReadbackGlxWindow;
class QWaylandShmBuffer;
@@ -54,26 +55,22 @@ class QWaylandShmBuffer;
class QWaylandReadbackGlxContext : public QPlatformGLContext
{
public:
- QWaylandReadbackGlxContext(QWaylandReadbackGlxIntegration *glxIntegration, QWaylandReadbackGlxWindow *window);
+ QWaylandReadbackGlxContext(const QSurfaceFormat &format, QPlatformGLContext *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..22ff5dc0c6 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);
+}
+
+QPlatformGLContext *QWaylandReadbackGlxIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..05c224263b 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);
+ QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..6e72a45bcd 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);
}
+QPlatformGLContext *QWaylandEglIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..5e39e39fe8 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);
+ QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..245097ef6c 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,29 @@
#include "qwaylandscreen.h"
#include "qwaylandglcontext.h"
-QWaylandEglWindow::QWaylandEglWindow(QWidget *window)
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+
+#include <QtGui/QWindow>
+
+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 +77,46 @@ 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);
}
-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..d3ece7c7a9 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/QSurfaceFormat>
#include <QtCore/QMutex>
-QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format)
+QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformGLContext *share)
: QPlatformGLContext()
- , mEglDisplay(eglDisplay)
- , mSurface(EGL_NO_SURFACE)
- , mConfig(q_configFromQPlatformWindowFormat(mEglDisplay,format,true))
- , mFormat(qt_qPlatformWindowFormatFromConfig(mEglDisplay,mConfig))
+ , 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..592f3d18f5 100644
--- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h
@@ -53,27 +53,27 @@ class QWaylandGLWindowSurface;
class QWaylandGLContext : public QPlatformGLContext {
public:
- QWaylandGLContext(EGLDisplay eglDisplay, const QPlatformWindowFormat &format);
+ QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformGLContext *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..6c1018d79a 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, QPlatformGLContext *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..f0e96a19af 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h
@@ -44,39 +44,21 @@
#include <QtGui/QPlatformGLContext>
-#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, QPlatformGLContext *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..47454dccab 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);
+}
+
+QPlatformGLContext *QWaylandXCompositeEGLIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..1f67bf28e1 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 <QPlatformGLContext>
#include <QWaitCondition>
@@ -66,7 +68,8 @@ public:
void initialize();
- QWaylandWindow *createEglWindow(QWidget *widget);
+ QWaylandWindow *createEglWindow(QWindow *window);
+ QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..20fb0396f8 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, QPlatformGLContext *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..cabdbe1a82 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h
@@ -44,12 +44,8 @@
#include <QtGui/QPlatformGLContext>
-#include <QtCore/QWaitCondition>
-
-#include "qwaylandbuffer.h"
#include "qwaylandxcompositeglxintegration.h"
-
-#include "qglxconvenience.h"
+#include <QtPlatformSupport/private/qglxconvenience_p.h>
class QWaylandXCompositeGLXWindow;
class QWaylandShmBuffer;
@@ -57,29 +53,22 @@ class QWaylandShmBuffer;
class QWaylandXCompositeGLXContext : public QPlatformGLContext
{
public:
- QWaylandXCompositeGLXContext(QWaylandXCompositeGLXIntegration *glxIntegration, QWaylandXCompositeGLXWindow *window);
+ QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformGLContext *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..8c27fa1cd8 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);
+}
+
+QPlatformGLContext *QWaylandXCompositeGLXIntegration::createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..5a779bf58a 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);
+ QPlatformGLContext *createPlatformGLContext(const QSurfaceFormat &glFormat, QPlatformGLContext *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..eefd86dbf1 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/QGuiGLContext>
-#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,61 @@ 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
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
+QPlatformGLContext *QWaylandIntegration::createPlatformGLContext(QGuiGLContext *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()->createPlatformGLContext(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..69b8863ebc 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;
+ QPlatformGLContext *createPlatformGLContext(QGuiGLContext *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 43be74a6ea..3158c73605 100644
--- a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp
@@ -43,30 +43,31 @@
#include "qwaylanddisplay.h"
#include "qwaylandwindow.h"
-#include <QtGui/private/qapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QScreen>
-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 d33a41b00b..f1d4fe9402 100644
--- a/src/plugins/platforms/wayland/qwaylandnativeinterface.h
+++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.h
@@ -49,11 +49,11 @@
class QWaylandNativeInterface : public QPlatformNativeInterface
{
public:
- void *nativeResourceForWidget(const QByteArray &resourceString,
- QWidget *widget);
+ void *nativeResourceForWindow(const QByteArray &resourceString,
+ QWindow *window);
private:
- static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget);
+ static QWaylandScreen *qPlatformScreenForWindow(QWindow *window);
};
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 &region, const QPoint &offset)
+void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, 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 &region, 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 &region, const QPoint &offset);
- void resize(const QSize &size);
+ void flush(QWindow *window, const QRegion &region, 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 ef2047e0f3..f685dae729 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::handleExposeEvent(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)