diff options
author | Paul Olav Tvete <paul.tvete@nokia.com> | 2011-09-13 13:03:01 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@nokia.com> | 2011-09-13 13:03:01 +0200 |
commit | 97796083f8a31e536e65c4e125feffddeaf826ac (patch) | |
tree | 6d11856a9f97bc757fa9147045e8ab8584e1a96c | |
parent | 21a2ce41a8efb6c5ab4ab2674458309bc9f031b7 (diff) | |
parent | f4b7aaaf4e3aade89120b3754733981c6cd9a911 (diff) |
Merge branch 'refactor'
84 files changed, 8487 insertions, 0 deletions
diff --git a/src/plugins/platforms/wayland/gl_integration/gl_integration.pri b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri new file mode 100644 index 0000000..20c3aa0 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/gl_integration.pri @@ -0,0 +1,62 @@ +contains(QT_CONFIG, opengl) { + DEFINES += QT_WAYLAND_GL_SUPPORT + QT += opengl + +HEADERS += \ + $$PWD/qwaylandglintegration.h + +SOURCES += \ + $$PWD/qwaylandglintegration.cpp + + QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) + contains(QT_CONFIG, opengles2) { + isEqual(QT_WAYLAND_GL_CONFIG, wayland_egl) { + QT_WAYLAND_GL_INTEGRATION = $$QT_WAYLAND_GL_CONFIG + CONFIG += wayland_egl + } else:isEqual(QT_WAYLAND_GL_CONFIG,readback) { + QT_WAYLAND_GL_INTEGRATION = readback_egl + CONFIG += readback_egl + } else { + 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 + CONFIG += readback_glx + } else { + QT_WAYLAND_GL_INTEGRATION = xcomposite_glx + CONFIG += xcomposite_glx + } + } + + message("Wayland GL Integration: $$QT_WAYLAND_GL_INTEGRATION") +} + + +wayland_egl { + include ($$PWD/wayland_egl/wayland_egl.pri) +} + +readback_egl { + include ($$PWD/readback_egl/readback_egl.pri) +} + +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) +} + +xcomposite_egl { + include ($$PWD/xcomposite_egl/xcomposite_egl.pri) +} diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp new file mode 100644 index 0000000..dedd86b --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** 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 "qwaylandglintegration.h" + +QWaylandGLIntegration::QWaylandGLIntegration() +{ + +} + +QWaylandGLIntegration::~QWaylandGLIntegration() +{ + +} diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h new file mode 100644 index 0000000..4f688e4 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglintegration.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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 QWAYLANDGLINTEGRATION_H +#define QWAYLANDGLINTEGRATION_H + +class QWaylandWindow; +class QWaylandDisplay; +class QWindow; + +class QPlatformOpenGLContext; +class QSurfaceFormat; + +class QWaylandGLIntegration +{ +public: + QWaylandGLIntegration(); + virtual ~QWaylandGLIntegration(); + + virtual void initialize() = 0; + + virtual QWaylandWindow *createEglWindow(QWindow *window) = 0; + virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0; + + static QWaylandGLIntegration *createGLIntegration(QWaylandDisplay *waylandDisplay); +}; + +#endif // QWAYLANDGLINTEGRATION_H 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 0000000..5f7663e --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandreadbackcglcontext.h" + +#include "qwaylandshmbackingstore.h" +#include "qwaylandreadbackcglwindow.h" + +#include <QtGui/QOpenGLContext> +#include <QtCore/QDebug> + +#include <OpenGL/OpenGL.h> +#include <OpenGL/glext.h> +#include <OpenGL/glu.h> + +#include <QtPlatformSupport/private/cglconvenience_p.h> + +QWaylandReadbackCGLContext::QWaylandReadbackCGLContext(QPlatformOpenGLContext *share) + : QPlatformOpenGLContext() +{ + Q_UNUSED(share); + m_glContext = qcgl_createGlContext(); +} + +QSurfaceFormat QWaylandReadbackCGLContext::format() const +{ + return qcgl_surfaceFormat(); +} + +bool QWaylandReadbackCGLContext::makeCurrent(QPlatformSurface *surface) +{ + QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface); + CGLSetPBuffer(m_glContext, window->pixelBuffer(), 0, 0, 0); + CGLSetCurrentContext(m_glContext); + return true; +} + +void QWaylandReadbackCGLContext::doneCurrent() +{ + CGLSetCurrentContext(0); +} + +void QWaylandReadbackCGLContext::swapBuffers(QPlatformSurface *surface) +{ + Q_UNUSED(surface); + + if (QOpenGLContext::currentContext()->handle() != this) { + makeCurrent(surface); + } + CGLFlushDrawable(m_glContext); + + QWaylandReadbackCGLWindow *window = static_cast<QWaylandReadbackCGLWindow *>(surface); + QSize size = window->geometry().size(); + + uchar *dstBits = const_cast<uchar *>(window->buffer()); + glReadPixels(0,0, size.width(), size.height(), GL_BGRA,GL_UNSIGNED_BYTE, dstBits); + + window->damage(QRect(QPoint(0,0),size)); + + // ### Should sync here but this call deadlocks with the server. + //window->waitForFrameSync(); +} + +void (*QWaylandReadbackCGLContext::getProcAddress(const QByteArray &procName)) () +{ + return qcgl_getProcAddress(procName); +} + diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h new file mode 100644 index 0000000..eb065c3 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglcontext.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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 QWAYLANDREADBACKCGLCONTEXT_H +#define QWAYLANDREADBACKCGLCONTEXT_H + +#include <QPlatformOpenGLContext> + +#include "qwaylandreadbackcglintegration.h" + +#include <OpenGL/OpenGL.h> + +class QWaylandReadbackCGLWindow; +class QWaylandShmBuffer; + +class QWaylandReadbackCGLContext : public QPlatformOpenGLContext +{ +public: + QWaylandReadbackCGLContext(QPlatformOpenGLContext *share); + + QSurfaceFormat format() const; + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + void swapBuffers(QPlatformSurface *surface); + void (*getProcAddress(const QByteArray &procName)) (); + + void geometryChanged(); + +private: + CGLContextObj m_glContext; +}; + +#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 0000000..2878f9e --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandreadbackcglintegration.h" +#include "qwaylandreadbackcglcontext.h" +#include "qwaylandreadbackcglwindow.h" + +#include <QtCore/QDebug> + +QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandReadbackCGLIntegration(waylandDisplay); +} + +QWaylandReadbackCGLIntegration::QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly) + : QWaylandGLIntegration() + , mWaylandDisplay(waylandDispaly) +{ + qDebug() << "Using Readback-CGL"; +} + +QWaylandReadbackCGLIntegration::~QWaylandReadbackCGLIntegration() +{ + +} + +void QWaylandReadbackCGLIntegration::initialize() +{ +} + +QWaylandWindow * QWaylandReadbackCGLIntegration::createEglWindow(QWindow *window) +{ + return new QWaylandReadbackCGLWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandReadbackCGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandReadbackCGLContext(share); +} + +QWaylandDisplay * QWaylandReadbackCGLIntegration::waylandDisplay() const +{ + return mWaylandDisplay; +} diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h new file mode 100644 index 0000000..34c8d00 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglintegration.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDREADBACKGLXINTEGRATION_H +#define QWAYLANDREADBACKGLXINTEGRATION_H + +#include "gl_integration/qwaylandglintegration.h" + +#include <QtCore/QTextStream> +#include <QtCore/QDataStream> +#include <QtCore/QMetaType> +#include <QtCore/QVariant> +#include <QtGui/QWindow> + +#include <X11/Xlib.h> + +class QWaylandReadbackCGLIntegration : public QWaylandGLIntegration +{ +public: + QWaylandReadbackCGLIntegration(QWaylandDisplay * waylandDispaly); + ~QWaylandReadbackCGLIntegration(); + + void initialize(); + + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + QWaylandDisplay *waylandDisplay() const; + +private: + QWaylandDisplay *mWaylandDisplay; +}; + +#endif // QWAYLANDREADBACKGLXINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_cgl/qwaylandreadbackcglwindow.cpp new file mode 100644 index 0000000..9e7f852 --- /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 0000000..0598cf9 --- /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 0000000..91cb90a --- /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 new file mode 100644 index 0000000..c03e8a9 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** 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 "qwaylandreadbackeglcontext.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" + + +static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) +{ + const int width = img.width(); + const int height = img.height(); + + if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV + || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) + { + for (int i = 0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x = 0; x < width; ++x) + p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); + } + } else { + for (int i = 0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x = 0; x < width; ++x) + p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff); + } + } +} + +QWaylandReadbackEglContext::QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window) + : mEglIntegration(eglIntegration) + , mWindow(window) + , mBuffer(0) + , mPixmap(0) + , mConfig(q_configFromQWindowFormat(eglIntegration->eglDisplay(),window->window()->requestedWindowFormat(),true,EGL_PIXMAP_BIT)) + , mPixmapSurface(EGL_NO_SURFACE) +{ + QVector<EGLint> eglContextAttrs; + eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); + eglContextAttrs.append(2); + eglContextAttrs.append(EGL_NONE); + + mContext = eglCreateContext(eglIntegration->eglDisplay(),mConfig,0,eglContextAttrs.constData()); + + geometryChanged(); +} + +QWaylandReadbackEglContext::~QWaylandReadbackEglContext() +{ + eglDestroyContext(mEglIntegration->eglDisplay(),mContext); +} + +void QWaylandReadbackEglContext::makeCurrent() +{ + mWindow->waitForFrameSync(); + + eglMakeCurrent(mEglIntegration->eglDisplay(),mPixmapSurface,mPixmapSurface,mContext); +} + +void QWaylandReadbackEglContext::doneCurrent() +{ + QPlatformOpenGLContext::doneCurrent(); + eglMakeCurrent(mEglIntegration->eglDisplay(),EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT); +} + +void QWaylandReadbackEglContext::swapBuffers() +{ + eglSwapBuffers(mEglIntegration->eglDisplay(),mPixmapSurface); + + if (QWindowContext::currentContext()->handle() != this) { + makeCurrent(); + } + + QSize size = mWindow->geometry().size(); + + 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); + + img = img.mirrored(); + qgl_byteSwapImage(img,GL_UNSIGNED_INT_8_8_8_8_REV); + constBits = img.bits(); + + const uchar *constDstBits = mBuffer->image()->bits(); + uchar *dstBits = const_cast<uchar *>(constDstBits); + memcpy(dstBits,constBits,(img.width()*4) * img.height()); + + + mWindow->damage(QRegion(QRect(QPoint(0,0),size))); +} + +void * QWaylandReadbackEglContext::getProcAddress(const QString &procName) +{ + return (void *) eglGetProcAddress(procName.toLatin1().data()); +} + +QWindowFormat QWaylandReadbackEglContext::windowFormat() const +{ + return q_windowFormatFromConfig(mEglIntegration->eglDisplay(),mConfig); +} + +void QWaylandReadbackEglContext::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; + if (mPixmap) + XFreePixmap(mEglIntegration->xDisplay(),mPixmap); + + mBuffer = new QWaylandShmBuffer(mEglIntegration->waylandDisplay(),size,QImage::Format_ARGB32); + mWindow->attach(mBuffer); + mPixmap = XCreatePixmap(mEglIntegration->xDisplay(),mEglIntegration->rootWindow(),size.width(),size.height(),mEglIntegration->depth()); + XSync(mEglIntegration->xDisplay(),False); + + mPixmapSurface = eglCreatePixmapSurface(mEglIntegration->eglDisplay(),mConfig,mPixmap,0); + if (mPixmapSurface == EGL_NO_SURFACE) { + qDebug() << "Could not make egl surface out of pixmap :("; + } +} diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h new file mode 100644 index 0000000..75755fb --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglcontext.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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 QWAYLANDREADBACKEGLGLCONTEXT_H +#define QWAYLANDREADBACKEGLGLCONTEXT_H + +#include <QPlatformOpenGLContext> + +#include "qwaylandreadbackeglintegration.h" +#include "qwaylandreadbackeglwindow.h" + +class QWaylandShmBuffer; + +class QWaylandReadbackEglContext : public QPlatformOpenGLContext +{ +public: + QWaylandReadbackEglContext(QWaylandReadbackEglIntegration *eglIntegration, QWaylandReadbackEglWindow *window); + ~QWaylandReadbackEglContext(); + + void makeCurrent(); + void doneCurrent(); + void swapBuffers(); + void* getProcAddress(const QString& procName); + + virtual QWindowFormat windowFormat() const; + + void geometryChanged(); + +private: + QWaylandReadbackEglIntegration *mEglIntegration; + QWaylandReadbackEglWindow *mWindow; + QWaylandShmBuffer *mBuffer; + + Pixmap mPixmap; + + EGLConfig mConfig; + EGLContext mContext; + EGLSurface mPixmapSurface; +}; + +#endif // QWAYLANDREADBACKEGLGLCONTEXT_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp new file mode 100644 index 0000000..39fa3d5 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** 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 "qwaylandreadbackeglintegration.h" + +#include <QDebug> + +#include "qwaylandreadbackeglwindow.h" + +QWaylandReadbackEglIntegration::QWaylandReadbackEglIntegration(QWaylandDisplay *display) + : QWaylandGLIntegration() + , mWaylandDisplay(display) +{ + qDebug() << "Using Readback-EGL"; + char *display_name = getenv("DISPLAY"); + mDisplay = XOpenDisplay(display_name); + mScreen = XDefaultScreen(mDisplay); + mRootWindow = XDefaultRootWindow(mDisplay); + XSync(mDisplay, False); +} + +QWaylandReadbackEglIntegration::~QWaylandReadbackEglIntegration() +{ + XCloseDisplay(mDisplay); +} + + +QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandReadbackEglIntegration(waylandDisplay); +} + +void QWaylandReadbackEglIntegration::initialize() +{ + eglBindAPI(EGL_OPENGL_ES_API); + mEglDisplay = eglGetDisplay(mDisplay); + EGLint major, minor; + EGLBoolean initialized = eglInitialize(mEglDisplay,&major,&minor); + if (initialized) { + qDebug() << "EGL initialized successfully" << major << "," << minor; + } else { + qDebug() << "EGL could not initialized. All EGL and GL operations will fail"; + } +} + +QWaylandWindow * QWaylandReadbackEglIntegration::createEglWindow(QWindow *window) +{ + return new QWaylandReadbackEglWindow(window, this); +} + +QPlatformOpenGLContext *QWaylandReadbackEglWindow::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandReadbackEglContext(glFormat, share, this); +} + +EGLDisplay QWaylandReadbackEglIntegration::eglDisplay() +{ + return mEglDisplay; +} + +Window QWaylandReadbackEglIntegration::rootWindow() const +{ + return mRootWindow; +} + +int QWaylandReadbackEglIntegration::depth() const +{ + return XDefaultDepth(mDisplay,mScreen); +} + +Display * QWaylandReadbackEglIntegration::xDisplay() const +{ + return mDisplay; +} + +QWaylandDisplay * QWaylandReadbackEglIntegration::waylandDisplay() const +{ + return mWaylandDisplay; +} diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h new file mode 100644 index 0000000..0d6aa55 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglintegration.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** 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 QWAYLANDREADBACKEGLINTEGRATION_H +#define QWAYLANDREADBACKEGLINTEGRATION_H + +#include "gl_integration/qwaylandglintegration.h" + +#include <QtCore/QTextStream> +#include <QtCore/QDataStream> +#include <QtCore/QMetaType> +#include <QtCore/QVariant> +#include <QtCore/QEvent> +#include <QtGui/QCursor> + +#include <X11/Xlib.h> + +#include <EGL/egl.h> + +class QWaylandReadbackEglIntegration : public QWaylandGLIntegration +{ +public: + QWaylandReadbackEglIntegration(QWaylandDisplay *display); + ~QWaylandReadbackEglIntegration(); + + void initialize(); + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + + QWaylandDisplay *waylandDisplay() const; + Display *xDisplay() const; + Window rootWindow() const; + int depth() const; + + EGLDisplay eglDisplay(); + +private: + QWaylandDisplay *mWaylandDisplay; + Display *mDisplay; + int mScreen; + Window mRootWindow; + EGLDisplay mEglDisplay; + +}; + +#endif // QWAYLANDREADBACKEGLINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp new file mode 100644 index 0000000..f4bc637 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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 "qwaylandreadbackeglwindow.h" + +#include "qwaylandreadbackeglcontext.h" + +QWaylandReadbackEglWindow::QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration) + : QWaylandShmWindow(window) + , mEglIntegration(eglIntegration) + , mContext(0) +{ +} + +QWaylandWindow::WindowType QWaylandReadbackEglWindow::windowType() const +{ + //We'r lying, maybe we should add a type, but for now it will do + //since this is primarly used by the windowsurface. + return QWaylandWindow::Egl; +} + +QPlatformOpenGLContext *QWaylandReadbackEglWindow::glContext() const +{ + if (!mContext) { + QWaylandReadbackEglWindow *that = const_cast<QWaylandReadbackEglWindow *>(this); + that->mContext = new QWaylandReadbackEglContext(mEglIntegration,that); + } + return mContext; +} + +void QWaylandReadbackEglWindow::setGeometry(const QRect &rect) +{ + QPlatformWindow::setGeometry(rect); + + if (mContext) + mContext->geometryChanged(); +} + diff --git a/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h new file mode 100644 index 0000000..0852a8e --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/qwaylandreadbackeglwindow.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** 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 QWAYLANDREADBACKEGLWINDOW_H +#define QWAYLANDREADBACKEGLWINDOW_H + +#include "qwaylandshmwindow.h" +#include "qwaylandreadbackeglintegration.h" + +class QWaylandReadbackEglContext; + +class QWaylandReadbackEglWindow : public QWaylandShmWindow +{ +public: + QWaylandReadbackEglWindow(QWindow *window, QWaylandReadbackEglIntegration *eglIntegration); + + WindowType windowType() const; + + QPlatformOpenGLContext *glContext() const; + + void setGeometry(const QRect &rect); + +private: + QWaylandReadbackEglIntegration *mEglIntegration; + QWaylandReadbackEglContext *mContext; +}; + +#endif // QWAYLANDREADBACKEGLWINDOW_H 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 new file mode 100644 index 0000000..3325fe8 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_egl/readback_egl.pri @@ -0,0 +1,12 @@ +LIBS += -lX11 -lXext -lEGL + +load(qpa/egl/convenience) +HEADERS += \ + $$PWD/qwaylandreadbackeglintegration.h \ + $$PWD/qwaylandreadbackeglcontext.h \ + $$PWD/qwaylandreadbackeglwindow.h \ + +SOURCES += \ + $$PWD/qwaylandreadbackeglintegration.cpp \ + $$PWD/qwaylandreadbackeglwindow.cpp \ + $$PWD/qwaylandreadbackeglcontext.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 new file mode 100644 index 0000000..850e7bb --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** 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 "qwaylandreadbackglxcontext.h" + +#include "qwaylandshmbackingstore.h" +#include "qwaylandreadbackglxwindow.h" + +#include <QtGui/QOpenGLContext> +#include <QtCore/QDebug> + +static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) +{ + const int width = img.width(); + const int height = img.height(); + + if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV + || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) + { + for (int i = 0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x = 0; x < width; ++x) + p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); + } + } else { + for (int i = 0; i < height; ++i) { + uint *p = (uint *) img.scanLine(i); + for (int x = 0; x < width; ++x) + p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff); + } + } +} + +QWaylandReadbackGlxContext::QWaylandReadbackGlxContext(const QSurfaceFormat &format, + QPlatformOpenGLContext *share, Display *display, int screen) + : m_display(display) +{ + GLXFBConfig config = qglx_findConfig(display, screen, format, GLX_PIXMAP_BIT); + + 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; +} + +bool QWaylandReadbackGlxContext::makeCurrent(QPlatformSurface *surface) +{ + GLXPixmap glxPixmap = static_cast<QWaylandReadbackGlxWindow *>(surface)->glxPixmap(); + + return glXMakeCurrent(m_display, glxPixmap, m_context); +} + +void QWaylandReadbackGlxContext::doneCurrent() +{ + glXMakeCurrent(m_display, 0, 0); +} + +void QWaylandReadbackGlxContext::swapBuffers(QPlatformSurface *surface) +{ + // #### makeCurrent() directly on the platform context doesn't update QOpenGLContext::currentContext() + if (QOpenGLContext::currentContext()->handle() != this) + makeCurrent(surface); + + QWaylandReadbackGlxWindow *w = static_cast<QWaylandReadbackGlxWindow *>(surface); + + QSize size = w->geometry().size(); + + 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); + + img = img.mirrored(); + qgl_byteSwapImage(img, GL_UNSIGNED_INT_8_8_8_8_REV); + constBits = img.bits(); + + const uchar *constDstBits = w->buffer(); + uchar *dstBits = const_cast<uchar *>(constDstBits); + memcpy(dstBits, constBits, (img.width() * 4) * img.height()); + + w->damage(QRect(QPoint(), size)); + + w->waitForFrameSync(); +} + +void (*QWaylandReadbackGlxContext::getProcAddress(const QByteArray &procName)) () +{ + 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 new file mode 100644 index 0000000..7b5eeec --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxcontext.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** 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 QWAYLANDREADBACKGLXCONTEXT_H +#define QWAYLANDREADBACKGLXCONTEXT_H + +#include <QPlatformOpenGLContext> +#include <QSurfaceFormat> + +#include "qwaylandreadbackglxintegration.h" + +#include <QtPlatformSupport/private/qglxconvenience_p.h> + +class QWaylandReadbackGlxWindow; +class QWaylandShmBuffer; + +class QWaylandReadbackGlxContext : public QPlatformOpenGLContext +{ +public: + QWaylandReadbackGlxContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen); + + QSurfaceFormat format() const; + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + + void (*getProcAddress(const QByteArray &procName)) (); + +private: + GLXContext m_context; + + 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 new file mode 100644 index 0000000..752bb06 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.cpp @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** 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 "qwaylandreadbackglxintegration.h" + +#include "qwaylandreadbackglxwindow.h" + +#include <QtCore/QDebug> + +QWaylandReadbackGlxIntegration::QWaylandReadbackGlxIntegration(QWaylandDisplay * waylandDispaly) + : QWaylandGLIntegration() + , mWaylandDisplay(waylandDispaly) +{ + qDebug() << "Using Readback-GLX"; + char *display_name = getenv("DISPLAY"); + mDisplay = XOpenDisplay(display_name); + mScreen = XDefaultScreen(mDisplay); + mRootWindow = XDefaultRootWindow(mDisplay); + XSync(mDisplay, False); +} + +QWaylandReadbackGlxIntegration::~QWaylandReadbackGlxIntegration() +{ + XCloseDisplay(mDisplay); +} + +void QWaylandReadbackGlxIntegration::initialize() +{ +} + +QWaylandWindow * QWaylandReadbackGlxIntegration::createEglWindow(QWindow *window) +{ + return new QWaylandReadbackGlxWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandReadbackGlxIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandReadbackGlxContext(glFormat, share, mDisplay, mScreen); +} + +QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandReadbackGlxIntegration(waylandDisplay); +} + +Display * QWaylandReadbackGlxIntegration::xDisplay() const +{ + return mDisplay; +} + +int QWaylandReadbackGlxIntegration::screen() const +{ + return mScreen; +} + +Window QWaylandReadbackGlxIntegration::rootWindow() const +{ + return mRootWindow; +} + +QWaylandDisplay * QWaylandReadbackGlxIntegration::waylandDisplay() const +{ + return mWaylandDisplay; +} diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h new file mode 100644 index 0000000..ee50d74 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxintegration.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** 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 QWaylandReadbackGlxIntegration : public QWaylandGLIntegration +{ +public: + QWaylandReadbackGlxIntegration(QWaylandDisplay * waylandDispaly); + ~QWaylandReadbackGlxIntegration(); + + void initialize(); + + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + + QWaylandDisplay *waylandDisplay() const; + + Display *xDisplay() const; + int screen() const; + Window rootWindow() const; + +private: + QWaylandDisplay *mWaylandDisplay; + + Display *mDisplay; + int mScreen; + Window mRootWindow; + +}; + +#endif // QWAYLANDREADBACKGLXINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp new file mode 100644 index 0000000..35c3ca3 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** 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 <QtDebug> + +#include "qwaylandreadbackglxwindow.h" +#include "qwaylandshmbackingstore.h" + +QWaylandReadbackGlxWindow::QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration) + : QWaylandShmWindow(window) + , m_glxIntegration(glxIntegration) + , m_buffer(0) + , m_pixmap(0) + , m_config(0) + , m_glxPixmap(0) + , m_window(window) +{ +} + +QWaylandWindow::WindowType QWaylandReadbackGlxWindow::windowType() const +{ + //yeah. this type needs a new name + return QWaylandWindow::Egl; +} + +void QWaylandReadbackGlxWindow::setGeometry(const QRect &rect) +{ + QWaylandShmWindow::setGeometry(rect); + + if (m_pixmap) { + delete mBuffer; + //XFreePixmap deletes the glxPixmap as well + XFreePixmap(m_glxIntegration->xDisplay(), m_pixmap); + m_pixmap = 0; + } +} + +GLXPixmap QWaylandReadbackGlxWindow::glxPixmap() const +{ + if (!m_pixmap) + const_cast<QWaylandReadbackGlxWindow *>(this)->createSurface(); + + return m_glxPixmap; +} + +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 new file mode 100644 index 0000000..c92646c --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/qwaylandreadbackglxwindow.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** 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 "qwaylandreadbackglxintegration.h" +#include "qwaylandreadbackglxcontext.h" + +class QWaylandReadbackGlxWindow : public QWaylandShmWindow +{ +public: + QWaylandReadbackGlxWindow(QWindow *window, QWaylandReadbackGlxIntegration *glxIntegration); + WindowType windowType() const; + + void setGeometry(const QRect &rect); + + Pixmap glxPixmap() const; + + uchar *buffer(); + +private: + 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 new file mode 100644 index 0000000..746d594 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/readback_glx/readback_glx.pri @@ -0,0 +1,11 @@ +HEADERS += \ + $$PWD/qwaylandreadbackglxintegration.h \ + $$PWD/qwaylandreadbackglxwindow.h \ + $$PWD/qwaylandreadbackglxcontext.h + +SOURCES += \ + $$PWD/qwaylandreadbackglxintegration.cpp \ + $$PWD/qwaylandreadbackglxwindow.cpp \ + $$PWD/qwaylandreadbackglxcontext.cpp + +LIBS += -lX11 diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h new file mode 100644 index 0000000..7130054 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglinclude.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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 QWAYLANDEGLINCLUDE_H +#define QWAYLANDEGLINCLUDE_H + +#include <wayland-client.h> + +#include <wayland-egl.h> + +#define GL_GLEXT_PROTOTYPES +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#define EGL_EGLEXT_PROTOTYPES +#include <EGL/egl.h> +#include <EGL/eglext.h> + +#endif // QWAYLANDEGLINCLUDE_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 new file mode 100644 index 0000000..27f17a6 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** 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 "qwaylandeglintegration.h" + +#include "gl_integration/qwaylandglintegration.h" + +#include "qwaylandeglwindow.h" +#include "qwaylandglcontext.h" + +#include <QtCore/QDebug> + +QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) + : m_waylandDisplay(waylandDisplay) +{ + qDebug() << "Using Wayland-EGL"; +} + + +QWaylandEglIntegration::~QWaylandEglIntegration() +{ + eglTerminate(m_eglDisplay); +} + +void QWaylandEglIntegration::initialize() +{ + QByteArray eglPlatform = qgetenv("EGL_PLATFORM"); + if (eglPlatform.isEmpty()) { + setenv("EGL_PLATFORM","wayland",true); + } + + EGLint major,minor; + m_eglDisplay = eglGetDisplay(m_waylandDisplay); + if (m_eglDisplay == NULL) { + qWarning("EGL not available"); + } else { + if (!eglInitialize(m_eglDisplay, &major, &minor)) { + qWarning("failed to initialize EGL display"); + return; + } + } +} + +QWaylandWindow *QWaylandEglIntegration::createEglWindow(QWindow *window) +{ + return new QWaylandEglWindow(window); +} + +QPlatformOpenGLContext *QWaylandEglIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandGLContext(m_eglDisplay, glFormat, share); +} + +EGLDisplay QWaylandEglIntegration::eglDisplay() const +{ + return m_eglDisplay; +} + +QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandEglIntegration(waylandDisplay->wl_display()); +} diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h new file mode 100644 index 0000000..7a26c57 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.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 QWAYLANDEGLINTEGRATION_H +#define QWAYLANDEGLINTEGRATION_H + +#include "gl_integration/qwaylandglintegration.h" + +#include "qwaylandeglinclude.h" + +class QWaylandWindow; +class QWindow; + +class QWaylandEglIntegration : public QWaylandGLIntegration +{ +public: + QWaylandEglIntegration(struct wl_display *waylandDisplay); + ~QWaylandEglIntegration(); + + void initialize(); + + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + + EGLDisplay eglDisplay() const; + +private: + struct wl_display *m_waylandDisplay; + + 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 new file mode 100644 index 0000000..e0e1f77 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** 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 "qwaylandeglwindow.h" + +#include "qwaylandscreen.h" +#include "qwaylandglcontext.h" + +#include <QtPlatformSupport/private/qeglconvenience_p.h> + +#include <QtGui/QWindow> +#include <QtGui/QWindowSystemInterface> + +QWaylandEglWindow::QWaylandEglWindow(QWindow *window) + : QWaylandWindow(window) + , m_waylandEglWindow(0) + , m_eglSurface(0) + , m_eglConfig(0) + , m_format(window->format()) +{ + m_eglIntegration = static_cast<QWaylandEglIntegration *>(mDisplay->eglIntegration()); + + //super creates a new surface + newSurfaceCreated(); +} + +QWaylandEglWindow::~QWaylandEglWindow() +{ + if (m_eglSurface) { + eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + m_eglSurface = 0; + } +} + +QWaylandWindow::WindowType QWaylandEglWindow::windowType() const +{ + return QWaylandWindow::Egl; +} + +void QWaylandEglWindow::setGeometry(const QRect &rect) +{ + QWaylandWindow::setGeometry(rect); + if (m_waylandEglWindow){ + wl_egl_window_resize(m_waylandEglWindow, rect.width(), rect.height(), 0, 0); + QWindowSystemInterface::handleGeometryChange(window(), rect); + } +} + +void QWaylandEglWindow::newSurfaceCreated() +{ + if (m_waylandEglWindow) + wl_egl_window_destroy(m_waylandEglWindow); + + wl_visual *visual = QWaylandScreen::waylandScreenFromWindow(window())->visual(); + QSize size = geometry().size(); + if (!size.isValid()) + size = QSize(0,0); + + if (m_eglSurface) { + eglDestroySurface(m_eglIntegration->eglDisplay(), m_eglSurface); + m_eglSurface = 0; + } + + m_waylandEglWindow = wl_egl_window_create(mSurface, size.width(), size.height(), visual); +} + +QSurfaceFormat QWaylandEglWindow::format() const +{ + return m_format; +} + +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 new file mode 100644 index 0000000..d435a51 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** 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 QWAYLANDEGLWINDOW_H +#define QWAYLANDEGLWINDOW_H + +#include "qwaylandwindow.h" +#include "qwaylandeglinclude.h" +#include "qwaylandeglintegration.h" + +class QWaylandGLContext; + +class QWaylandEglWindow : public QWaylandWindow +{ +public: + QWaylandEglWindow(QWindow *window); + ~QWaylandEglWindow(); + WindowType windowType() const; + void setGeometry(const QRect &rect); + + EGLSurface eglSurface() const; + + QSurfaceFormat format() const; + +protected: + void newSurfaceCreated(); + +private: + QWaylandEglIntegration *m_eglIntegration; + struct wl_egl_window *m_waylandEglWindow; + + const QWaylandWindow *m_parentWindow; + + mutable EGLSurface m_eglSurface; + mutable EGLConfig m_eglConfig; + + 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 new file mode 100644 index 0000000..aa61405 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** 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 "qwaylandglcontext.h" + +#include "qwaylanddisplay.h" +#include "qwaylandwindow.h" +#include "qwaylandeglwindow.h" + +#include <QtPlatformSupport/private/qeglconvenience_p.h> + +#include <QtGui/QPlatformOpenGLContext> +#include <QtGui/QSurfaceFormat> +#include <QtCore/QMutex> + +QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share) + : QPlatformOpenGLContext() + , m_eglDisplay(eglDisplay) + , m_config(q_configFromGLFormat(m_eglDisplay, format, true)) + , m_format(q_glFormatFromConfig(m_eglDisplay, m_config)) +{ + EGLContext shareEGLContext = share ? static_cast<QWaylandGLContext *>(share)->eglContext() : EGL_NO_CONTEXT; + + eglBindAPI(EGL_OPENGL_ES_API); + + QVector<EGLint> eglContextAttrs; + eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); + eglContextAttrs.append(2); + eglContextAttrs.append(EGL_NONE); + + m_context = eglCreateContext(m_eglDisplay, m_config, shareEGLContext, eglContextAttrs.constData()); +} + +QWaylandGLContext::~QWaylandGLContext() +{ + eglDestroyContext(m_eglDisplay, m_context); +} + +bool QWaylandGLContext::makeCurrent(QPlatformSurface *surface) +{ + EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface(); + return eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_context); +} + +void QWaylandGLContext::doneCurrent() +{ + eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); +} + +void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) +{ + EGLSurface eglSurface = static_cast<QWaylandEglWindow *>(surface)->eglSurface(); + eglSwapBuffers(m_eglDisplay, eglSurface); +} + +void (*QWaylandGLContext::getProcAddress(const QByteArray &procName)) () +{ + return eglGetProcAddress(procName.constData()); +} + +EGLConfig QWaylandGLContext::eglConfig() const +{ + 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 new file mode 100644 index 0000000..16d9fa4 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** 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 QWAYLANDGLCONTEXT_H +#define QWAYLANDGLCONTEXT_H + +#include "qwaylanddisplay.h" + +#include <QtGui/QPlatformOpenGLContext> + +#include "qwaylandeglinclude.h" + +class QWaylandWindow; +class QWaylandGLWindowSurface; + +class QWaylandGLContext : public QPlatformOpenGLContext { +public: + QWaylandGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share); + ~QWaylandGLContext(); + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + + void (*getProcAddress(const QByteArray &procName)) (); + + QSurfaceFormat format() const { return m_format; } + + EGLConfig eglConfig() const; + EGLContext eglContext() const { return m_context; } + +private: + EGLDisplay m_eglDisplay; + + EGLContext m_context; + EGLConfig m_config; + QSurfaceFormat m_format; +}; + + +#endif // QWAYLANDGLCONTEXT_H 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 new file mode 100644 index 0000000..8b4b163 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri @@ -0,0 +1,9 @@ +LIBS += -lwayland-egl -lEGL +INCLUDEPATH += $$PWD +SOURCES += $$PWD/qwaylandeglintegration.cpp \ + $$PWD/qwaylandglcontext.cpp \ + $$PWD/qwaylandeglwindow.cpp + +HEADERS += $$PWD/qwaylandeglintegration.h \ + $$PWD/qwaylandglcontext.h \ + $$PWD/qwaylandeglwindow.h diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp new file mode 100644 index 0000000..f2f9d1c --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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 "qwaylandxcompositeeglcontext.h" + +#include "qwaylandxcompositeeglwindow.h" + +#include <QtCore/QDebug> +#include <QtGui/QRegion> + +#include <QtPlatformSupport/private/qeglconvenience_p.h> + +QWaylandXCompositeEGLContext::QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) + : QEGLPlatformContext(format, share, display) +{ +} + +void QWaylandXCompositeEGLContext::swapBuffers(QPlatformSurface *surface) +{ + QEGLPlatformContext::swapBuffers(surface); + + QWaylandXCompositeEGLWindow *w = + static_cast<QWaylandXCompositeEGLWindow *>(surface); + + QSize size = w->geometry().size(); + + w->damage(QRect(QPoint(), size)); + w->waitForFrameSync(); +} + +EGLSurface QWaylandXCompositeEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) +{ + 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 new file mode 100644 index 0000000..8420f2b --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglcontext.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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 QWAYLANDXCOMPOSITEEGLCONTEXT_H +#define QWAYLANDXCOMPOSITEEGLCONTEXT_H + +#include <QtGui/QPlatformOpenGLContext> + +#include "qwaylandxcompositeeglintegration.h" + +#include <QtPlatformSupport/private/qeglplatformcontext_p.h> + +class QWaylandXCompositeEGLWindow; + +class QWaylandXCompositeEGLContext : public QEGLPlatformContext +{ +public: + QWaylandXCompositeEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display); + + void swapBuffers(QPlatformSurface *surface); + +private: + 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 new file mode 100644 index 0000000..d7e37f8 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** 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 "qwaylandxcompositeeglintegration.h" + +#include "qwaylandxcompositeeglwindow.h" + +#include <QtCore/QDebug> + +#include "wayland-xcomposite-client-protocol.h" + +QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandXCompositeEGLIntegration(waylandDisplay); +} + +QWaylandXCompositeEGLIntegration::QWaylandXCompositeEGLIntegration(QWaylandDisplay * waylandDispaly) + : QWaylandGLIntegration() + , mWaylandDisplay(waylandDispaly) +{ + qDebug() << "Using XComposite-EGL"; + wl_display_add_global_listener(mWaylandDisplay->wl_display(), QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal, + this); +} + +QWaylandXCompositeEGLIntegration::~QWaylandXCompositeEGLIntegration() +{ + XCloseDisplay(mDisplay); +} + +void QWaylandXCompositeEGLIntegration::initialize() +{ +} + +QWaylandWindow * QWaylandXCompositeEGLIntegration::createEglWindow(QWindow *window) +{ + return new QWaylandXCompositeEGLWindow(window,this); +} + +QPlatformOpenGLContext *QWaylandXCompositeEGLIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandXCompositeEGLContext(glFormat, share, eglDisplay()); +} + +Display * QWaylandXCompositeEGLIntegration::xDisplay() const +{ + return mDisplay; +} + +EGLDisplay QWaylandXCompositeEGLIntegration::eglDisplay() const +{ + return mEglDisplay; +} + +int QWaylandXCompositeEGLIntegration::screen() const +{ + return mScreen; +} + +Window QWaylandXCompositeEGLIntegration::rootWindow() const +{ + return mRootWindow; +} + +QWaylandDisplay * QWaylandXCompositeEGLIntegration::waylandDisplay() const +{ + return mWaylandDisplay; +} +wl_xcomposite * QWaylandXCompositeEGLIntegration::waylandXComposite() const +{ + return mWaylandComposite; +} + +const struct wl_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite_listener = { + QWaylandXCompositeEGLIntegration::rootInformation +}; + +void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data) +{ + Q_UNUSED(version); + if (strcmp(interface, "wl_xcomposite") == 0) { + QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); + integration->mWaylandComposite = wl_xcomposite_create(display,id,1); + wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); + } + +} + +void QWaylandXCompositeEGLIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window) +{ + Q_UNUSED(xcomposite); + QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); + + integration->mDisplay = XOpenDisplay(display_name); + integration->mRootWindow = (Window) root_window; + integration->mScreen = XDefaultScreen(integration->mDisplay); + integration->mEglDisplay = eglGetDisplay(integration->mDisplay); + eglBindAPI(EGL_OPENGL_ES_API); + EGLint minor,major; + if (!eglInitialize(integration->mEglDisplay,&major,&minor)) { + qFatal("Failed to initialize EGL"); + } + eglSwapInterval(integration->eglDisplay(),0); + qDebug() << "ROOT INFORMATION" << integration->mDisplay << integration->mRootWindow << integration->mScreen; +} + diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h new file mode 100644 index 0000000..74ea930 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** 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 QWAYLANDXCOMPOSITEEGLINTEGRATION_H +#define QWAYLANDXCOMPOSITEEGLINTEGRATION_H + +#include "gl_integration/qwaylandglintegration.h" +#include "wayland-client.h" + +#include <QtCore/QTextStream> +#include <QtCore/QDataStream> +#include <QtCore/QMetaType> +#include <QtCore/QVariant> +#include <QtGui/QWindow> + +#include <QPlatformOpenGLContext> + +#include <QWaitCondition> + +#include <X11/Xlib.h> +#include <EGL/egl.h> + +struct wl_xcomposite; + +class QWaylandXCompositeEGLIntegration : public QWaylandGLIntegration +{ +public: + QWaylandXCompositeEGLIntegration(QWaylandDisplay * waylandDispaly); + ~QWaylandXCompositeEGLIntegration(); + + void initialize(); + + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + + QWaylandDisplay *waylandDisplay() const; + struct wl_xcomposite *waylandXComposite() const; + + Display *xDisplay() const; + EGLDisplay eglDisplay() const; + int screen() const; + Window rootWindow() const; + +private: + QWaylandDisplay *mWaylandDisplay; + struct wl_xcomposite *mWaylandComposite; + + Display *mDisplay; + EGLDisplay mEglDisplay; + int mScreen; + Window mRootWindow; + + static void wlDisplayHandleGlobal(struct wl_display *display, uint32_t id, + const char *interface, uint32_t version, void *data); + + static const struct wl_xcomposite_listener xcomposite_listener; + static void rootInformation(void *data, + struct wl_xcomposite *xcomposite, + const char *display_name, + uint32_t root_window); +}; + +#endif // QWAYLANDXCOMPOSITEEGLINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp new file mode 100644 index 0000000..320113f --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** 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 "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(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration) + : QWaylandWindow(window) + , 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 +{ + //yeah. this type needs a new name + return QWaylandWindow::Egl; +} + +void QWaylandXCompositeEGLWindow::setGeometry(const QRect &rect) +{ + QWaylandWindow::setGeometry(rect); + + if (m_surface) { + eglDestroySurface(m_glxIntegration->eglDisplay(), m_surface); + m_surface = 0; + } +} + +EGLSurface QWaylandXCompositeEGLWindow::eglSurface() const +{ + 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); + } + + 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() +{ +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT + mDisplay->windowManagerIntegration()->authenticateWithToken(); +#endif + + QWaylandWindow::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 new file mode 100644 index 0000000..b2f8fbe --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** 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 QWAYLANDXCOMPOSITEEGLWINDOW_H +#define QWAYLANDXCOMPOSITEEGLWINDOW_H + +#include "qwaylandwindow.h" +#include "qwaylandbuffer.h" + +#include "qwaylandxcompositeeglintegration.h" +#include "qwaylandxcompositeeglcontext.h" + +class QWaylandXCompositeEGLWindow : public QWaylandWindow +{ +public: + QWaylandXCompositeEGLWindow(QWindow *window, QWaylandXCompositeEGLIntegration *glxIntegration); + WindowType windowType() const; + + void setGeometry(const QRect &rect); + void requestActivateWindow(); + + EGLSurface eglSurface() const; + +private: + 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 new file mode 100644 index 0000000..5f86bd9 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/xcomposite_egl.pri @@ -0,0 +1,13 @@ +include (../xcomposite_share/xcomposite_share.pri) + +LIBS += -lXcomposite -lEGL + +SOURCES += \ + $$PWD/qwaylandxcompositeeglcontext.cpp \ + $$PWD/qwaylandxcompositeeglintegration.cpp \ + $$PWD/qwaylandxcompositeeglwindow.cpp + +HEADERS += \ + $$PWD/qwaylandxcompositeeglcontext.h \ + $$PWD/qwaylandxcompositeeglintegration.h \ + $$PWD/qwaylandxcompositeeglwindow.h diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp new file mode 100644 index 0000000..75881a7 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** 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 <QtCore/QDebug> + +#include "qwaylandxcompositeglxcontext.h" + +#include "qwaylandxcompositeglxwindow.h" + +#include <QRegion> + +QWaylandXCompositeGLXContext::QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen) + : m_display(display) +{ + 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); +} + +bool QWaylandXCompositeGLXContext::makeCurrent(QPlatformSurface *surface) +{ + Window xWindow = static_cast<QWaylandXCompositeGLXWindow *>(surface)->xWindow(); + + return glXMakeCurrent(m_display, xWindow, m_context); +} + +void QWaylandXCompositeGLXContext::doneCurrent() +{ + glXMakeCurrent(m_display, 0, 0); +} + +void QWaylandXCompositeGLXContext::swapBuffers(QPlatformSurface *surface) +{ + QWaylandXCompositeGLXWindow *w = static_cast<QWaylandXCompositeGLXWindow *>(surface); + + QSize size = w->geometry().size(); + + glXSwapBuffers(m_display, w->xWindow()); + + w->damage(QRect(QPoint(), size)); + w->waitForFrameSync(); +} + +void (*QWaylandXCompositeGLXContext::getProcAddress(const QByteArray &procName)) () +{ + return glXGetProcAddress(reinterpret_cast<const GLubyte *>(procName.constData())); +} + +QSurfaceFormat QWaylandXCompositeGLXContext::format() const +{ + return m_format; +} + diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h new file mode 100644 index 0000000..3364d88 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxcontext.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** 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 QWAYLANDXCOMPOSITEGLXCONTEXT_H +#define QWAYLANDXCOMPOSITEGLXCONTEXT_H + +#include <QtGui/QPlatformOpenGLContext> + +#include "qwaylandxcompositeglxintegration.h" +#include <QtPlatformSupport/private/qglxconvenience_p.h> + +class QWaylandXCompositeGLXWindow; +class QWaylandShmBuffer; + +class QWaylandXCompositeGLXContext : public QPlatformOpenGLContext +{ +public: + QWaylandXCompositeGLXContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, Display *display, int screen); + + QSurfaceFormat format() const; + + void swapBuffers(QPlatformSurface *surface); + + bool makeCurrent(QPlatformSurface *surface); + void doneCurrent(); + + void (*getProcAddress(const QByteArray &procName)) (); + +private: + GLXContext m_context; + + 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 new file mode 100644 index 0000000..e1eb2e6 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** 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 "qwaylandxcompositeglxintegration.h" + +#include "qwaylandxcompositeglxwindow.h" + +#include <QtCore/QDebug> + +#include "wayland-xcomposite-client-protocol.h" + +QWaylandGLIntegration * QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandXCompositeGLXIntegration(waylandDisplay); +} + +QWaylandXCompositeGLXIntegration::QWaylandXCompositeGLXIntegration(QWaylandDisplay *waylandDisplay) + : mWaylandDisplay(waylandDisplay) + , mWaylandComposite(0) + , mDisplay(0) + , mScreen(0) + , mRootWindow(0) +{ + qDebug() << "Using XComposite-GLX"; + wl_display_add_global_listener(waylandDisplay->wl_display(), QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal, + this); +} + +QWaylandXCompositeGLXIntegration::~QWaylandXCompositeGLXIntegration() +{ + XCloseDisplay(mDisplay); +} + +void QWaylandXCompositeGLXIntegration::initialize() +{ +} + +QWaylandWindow * QWaylandXCompositeGLXIntegration::createEglWindow(QWindow *window) +{ + return new QWaylandXCompositeGLXWindow(window, this); +} + +QPlatformOpenGLContext *QWaylandXCompositeGLXIntegration::createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const +{ + return new QWaylandXCompositeGLXContext(glFormat, share, mDisplay, mScreen); +} + +Display * QWaylandXCompositeGLXIntegration::xDisplay() const +{ + return mDisplay; +} + +int QWaylandXCompositeGLXIntegration::screen() const +{ + return mScreen; +} + +Window QWaylandXCompositeGLXIntegration::rootWindow() const +{ + return mRootWindow; +} + +QWaylandDisplay * QWaylandXCompositeGLXIntegration::waylandDisplay() const +{ + return mWaylandDisplay; +} +wl_xcomposite * QWaylandXCompositeGLXIntegration::waylandXComposite() const +{ + return mWaylandComposite; +} + +const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite_listener = { + QWaylandXCompositeGLXIntegration::rootInformation +}; + +void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data) +{ + 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); + } + +} + +void QWaylandXCompositeGLXIntegration::rootInformation(void *data, wl_xcomposite *xcomposite, const char *display_name, uint32_t root_window) +{ + 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 new file mode 100644 index 0000000..b028067 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** 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 QWAYLANDXCOMPOSITEGLXINTEGRATION_H +#define QWAYLANDXCOMPOSITEGLXINTEGRATION_H + +#include "gl_integration/qwaylandglintegration.h" +#include "wayland-client.h" + +#include <QtCore/QTextStream> +#include <QtCore/QDataStream> +#include <QtCore/QMetaType> +#include <QtCore/QVariant> +#include <QtGui/QWindow> + +#include <X11/Xlib.h> + +struct wl_xcomposite; + +class QWaylandXCompositeGLXIntegration : public QWaylandGLIntegration +{ +public: + QWaylandXCompositeGLXIntegration(QWaylandDisplay * waylandDispaly); + ~QWaylandXCompositeGLXIntegration(); + + void initialize(); + + QWaylandWindow *createEglWindow(QWindow *window); + QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const; + + QWaylandDisplay *waylandDisplay() const; + struct wl_xcomposite *waylandXComposite() const; + + Display *xDisplay() const; + int screen() const; + Window rootWindow() const; + +private: + QWaylandDisplay *mWaylandDisplay; + struct wl_xcomposite *mWaylandComposite; + + Display *mDisplay; + int mScreen; + Window mRootWindow; + + static void wlDisplayHandleGlobal(struct wl_display *display, uint32_t id, + const char *interface, uint32_t version, void *data); + + static const struct wl_xcomposite_listener xcomposite_listener; + static void rootInformation(void *data, + struct wl_xcomposite *xcomposite, + const char *display_name, + uint32_t root_window); +}; + +#endif // QWAYLANDXCOMPOSITEGLXINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp new file mode 100644 index 0000000..abaf3b1 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** 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 "qwaylandxcompositeglxwindow.h" +#include "qwaylandxcompositebuffer.h" + +#include <QtCore/QDebug> + +#include "wayland-xcomposite-client-protocol.h" +#include <QtGui/QRegion> + +#include <X11/extensions/Xcomposite.h> + + +QWaylandXCompositeGLXWindow::QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration) + : QWaylandWindow(window) + , 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 +{ + //yeah. this type needs a new name + return QWaylandWindow::Egl; +} + +void QWaylandXCompositeGLXWindow::setGeometry(const QRect &rect) +{ + QWaylandWindow::setGeometry(rect); + + if (m_xWindow) { + delete m_buffer; + + XDestroyWindow(m_glxIntegration->xDisplay(), m_xWindow); + m_xWindow = 0; + } +} + +Window QWaylandXCompositeGLXWindow::xWindow() const +{ + if (!m_xWindow) + const_cast<QWaylandXCompositeGLXWindow *>(this)->createSurface(); + + 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 new file mode 100644 index 0000000..acf6c8e --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxwindow.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** 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 QWAYLANDXCOMPOSITEGLXWINDOW_H +#define QWAYLANDXCOMPOSITEGLXWINDOW_H + +#include "qwaylandwindow.h" +#include "qwaylandxcompositeglxintegration.h" +#include "qwaylandxcompositeglxcontext.h" + +#include <QtCore/QWaitCondition> + +#include "qwaylandbuffer.h" + +class QWaylandXCompositeGLXWindow : public QWaylandWindow +{ +public: + QWaylandXCompositeGLXWindow(QWindow *window, QWaylandXCompositeGLXIntegration *glxIntegration); + WindowType windowType() const; + + void setGeometry(const QRect &rect); + + Window xWindow() const; + +private: + 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 new file mode 100644 index 0000000..bbd6c12 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/xcomposite_glx.pri @@ -0,0 +1,12 @@ +include (../xcomposite_share/xcomposite_share.pri) + +LIBS += -lXcomposite +SOURCES += \ + $$PWD/qwaylandxcompositeglxcontext.cpp \ + $$PWD/qwaylandxcompositeglxintegration.cpp \ + $$PWD/qwaylandxcompositeglxwindow.cpp + +HEADERS += \ + $$PWD/qwaylandxcompositeglxcontext.h \ + $$PWD/qwaylandxcompositeglxintegration.h \ + $$PWD/qwaylandxcompositeglxwindow.h diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp new file mode 100644 index 0000000..f4bacc3 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** 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 "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) +{ + mBuffer = wl_xcomposite_create_buffer(xcomposite, + window, + size.width(), + size.height(), + visual); +} + +QSize QWaylandXCompositeBuffer::size() const +{ + return mSize; +} diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h new file mode 100644 index 0000000..02176d7 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/qwaylandxcompositebuffer.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** 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 QWAYLANDXCOMPOSITEBUFFER_H +#define QWAYLANDXCOMPOSITEBUFFER_H + +#include "qwaylandbuffer.h" +#include <stdint.h> + +struct wl_xcomposite; +struct wl_visual; + +class QWaylandXCompositeBuffer : public QWaylandBuffer +{ +public: + QWaylandXCompositeBuffer(struct wl_xcomposite *xcomposite, + uint32_t window, + const QSize &size, + struct wl_visual *visual); + + QSize size() const; +private: + QSize mSize; +}; + +#endif // QWAYLANDXCOMPOSITEBUFFER_H diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h new file mode 100644 index 0000000..309252a --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** 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 XCOMPOSITE_CLIENT_PROTOCOL_H +#define XCOMPOSITE_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <stddef.h> +#include "wayland-util.h" + +struct wl_client; + +struct wl_xcomposite; + +extern const struct wl_interface wl_xcomposite_interface; + +struct wl_xcomposite_listener { + void (*root)(void *data, + struct wl_xcomposite *wl_xcomposite, + const char *display_name, + uint32_t root_window); +}; + +static inline int +wl_xcomposite_add_listener(struct wl_xcomposite *wl_xcomposite, + const struct wl_xcomposite_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_xcomposite, + (void (**)(void)) listener, data); +} + +#define WL_XCOMPOSITE_CREATE_BUFFER 0 + +static inline struct wl_xcomposite * +wl_xcomposite_create(struct wl_display *display, uint32_t id, uint32_t version) +{ + wl_display_bind(display, id, "wl_xcomposite", version); + + return (struct wl_xcomposite *) + wl_proxy_create_for_id(display, &wl_xcomposite_interface, id); +} + +static inline void +wl_xcomposite_set_user_data(struct wl_xcomposite *wl_xcomposite, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_xcomposite, user_data); +} + +static inline void * +wl_xcomposite_get_user_data(struct wl_xcomposite *wl_xcomposite) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_xcomposite); +} + +static inline void +wl_xcomposite_destroy(struct wl_xcomposite *wl_xcomposite) +{ + wl_proxy_destroy((struct wl_proxy *) wl_xcomposite); +} + +static inline struct wl_buffer * +wl_xcomposite_create_buffer(struct wl_xcomposite *wl_xcomposite, uint32_t x_window, int width, int height, struct wl_visual *visual) +{ + struct wl_proxy *id; + + id = wl_proxy_create((struct wl_proxy *) wl_xcomposite, + &wl_buffer_interface); + if (!id) + return NULL; + + wl_proxy_marshal((struct wl_proxy *) wl_xcomposite, + WL_XCOMPOSITE_CREATE_BUFFER, id, x_window, width, height, visual); + + return (struct wl_buffer *) id; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c new file mode 100644 index 0000000..f79b510 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** 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 <stdlib.h> +#include <stdint.h> +#include "wayland-util.h" + +static const struct wl_message wl_xcomposite_requests[] = { + { "create_buffer", "nuiio" }, +}; + +static const struct wl_message wl_xcomposite_events[] = { + { "root", "su" }, +}; + +WL_EXPORT const struct wl_interface wl_xcomposite_interface = { + "wl_xcomposite", 1, + ARRAY_LENGTH(wl_xcomposite_requests), wl_xcomposite_requests, + ARRAY_LENGTH(wl_xcomposite_events), wl_xcomposite_events, +}; + diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri new file mode 100644 index 0000000..03b3521 --- /dev/null +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/xcomposite_share.pri @@ -0,0 +1,9 @@ +INCLUDEPATH += $$PWD + +HEADERS += \ + $$PWD/wayland-xcomposite-client-protocol.h \ + gl_integration/xcomposite_share/qwaylandxcompositebuffer.h + +SOURCES += \ + $$PWD/wayland-xcomposite-protocol.c \ + gl_integration/xcomposite_share/qwaylandxcompositebuffer.cpp diff --git a/src/plugins/platforms/wayland/main.cpp b/src/plugins/platforms/wayland/main.cpp new file mode 100644 index 0000000..e4d420d --- /dev/null +++ b/src/plugins/platforms/wayland/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** 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 <QtGui/QPlatformIntegrationPlugin> +#include "qwaylandintegration.h" + +QT_BEGIN_NAMESPACE + +class QWaylandIntegrationPlugin : public QPlatformIntegrationPlugin +{ +public: + QStringList keys() const; + QPlatformIntegration *create(const QString&, const QStringList&); +}; + +QStringList QWaylandIntegrationPlugin::keys() const +{ + QStringList list; + list << "wayland"; + return list; +} + +QPlatformIntegration *QWaylandIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + Q_UNUSED(paramList); + if (system.toLower() == "wayland") + return new QWaylandIntegration(); + + return 0; +} + +Q_EXPORT_PLUGIN2(wayland, QWaylandIntegrationPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylandbuffer.h b/src/plugins/platforms/wayland/qwaylandbuffer.h new file mode 100644 index 0000000..e8be6fa --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandbuffer.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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 QWAYLANDBUFFER_H +#define QWAYLANDBUFFER_H + +#include <QtCore/QSize> + +#include <wayland-client.h> +#include <wayland-client-protocol.h> + +class QWaylandBuffer { +public: + QWaylandBuffer() { } + virtual ~QWaylandBuffer() { } + wl_buffer *buffer() {return mBuffer;} + virtual QSize size() const = 0; + +protected: + struct wl_buffer *mBuffer; +}; + +#endif // QWAYLANDBUFFER_H diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp new file mode 100644 index 0000000..f90d1a9 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp @@ -0,0 +1,301 @@ +/**************************************************************************** +** +** 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 "qwaylandclipboard.h" +#include "qwaylanddisplay.h" +#include "qwaylandinputdevice.h" +#include "qwaylandmime.h" +#include <QtGui/QPlatformNativeInterface> +#include <QtGui/QGuiApplication> +#include <QtCore/QMimeData> +#include <QtCore/QStringList> +#include <QtCore/QFile> +#include <QtCore/QtDebug> +#include <QtGui/private/qdnd_p.h> +#include <QtCore/private/qcore_unix_p.h> // for QT_READ + +static QWaylandClipboard *clipboard = 0; + +class QWaylandClipboardMimeData : public QInternalMimeData +{ +public: + void clearAll(); + void setFormats(const QStringList &formatList); + bool hasFormat_sys(const QString &mimeType) const; + QStringList formats_sys() const; + QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const; +private: + QStringList mFormatList; +}; + +void QWaylandClipboardMimeData::clearAll() +{ + clear(); + mFormatList.clear(); +} + +void QWaylandClipboardMimeData::setFormats(const QStringList &formatList) +{ + mFormatList = formatList; +} + +bool QWaylandClipboardMimeData::hasFormat_sys(const QString &mimeType) const +{ + return formats().contains(mimeType); +} + +QStringList QWaylandClipboardMimeData::formats_sys() const +{ + return mFormatList; +} + +QVariant QWaylandClipboardMimeData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const +{ + return clipboard->retrieveData(mimeType, type); +} + +class QWaylandSelection +{ +public: + QWaylandSelection(QWaylandDisplay *display, QMimeData *data); + ~QWaylandSelection(); + + static uint32_t getTime(); + static void send(void *data, struct wl_selection *selection, const char *mime_type, int fd); + static void cancelled(void *data, struct wl_selection *selection); + static const struct wl_selection_listener selectionListener; + + QMimeData *mMimeData; + struct wl_selection *mSelection; +}; + +const struct wl_selection_listener QWaylandSelection::selectionListener = { + QWaylandSelection::send, + QWaylandSelection::cancelled +}; + +uint32_t QWaylandSelection::getTime() +{ + struct timeval tv; + gettimeofday(&tv, 0); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +QWaylandSelection::QWaylandSelection(QWaylandDisplay *display, QMimeData *data) + : mMimeData(data), mSelection(0) +{ + struct wl_shell *shell = display->wl_shell(); + mSelection = wl_shell_create_selection(shell); + wl_selection_add_listener(mSelection, &selectionListener, this); + foreach (const QString &format, data->formats()) + wl_selection_offer(mSelection, format.toLatin1().constData()); + wl_selection_activate(mSelection, + display->inputDevices().at(0)->wl_input_device(), + getTime()); +} + +QWaylandSelection::~QWaylandSelection() +{ + if (mSelection) { + clipboard->unregisterSelection(this); + wl_selection_destroy(mSelection); + } + delete mMimeData; +} + +void QWaylandSelection::send(void *data, + struct wl_selection *selection, + const char *mime_type, + int fd) +{ + Q_UNUSED(selection); + QWaylandSelection *self = static_cast<QWaylandSelection *>(data); + QString mimeType = QString::fromLatin1(mime_type); + QByteArray content = QWaylandMimeHelper::getByteArray(self->mMimeData, mimeType); + if (!content.isEmpty()) { + QFile f; + if (f.open(fd, QIODevice::WriteOnly)) + f.write(content); + } + close(fd); +} + +void QWaylandSelection::cancelled(void *data, struct wl_selection *selection) +{ + Q_UNUSED(selection); + delete static_cast<QWaylandSelection *>(data); +} + +QWaylandClipboard *QWaylandClipboard::instance(QWaylandDisplay *display) +{ + if (!clipboard) + clipboard = new QWaylandClipboard(display); + return clipboard; +} + +QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display) + : mDisplay(display), mMimeDataIn(0), mOffer(0) +{ +} + +QWaylandClipboard::~QWaylandClipboard() +{ + if (mOffer) + wl_selection_offer_destroy(mOffer); + delete mMimeDataIn; + qDeleteAll(mSelections); +} + +void QWaylandClipboard::unregisterSelection(QWaylandSelection *selection) +{ + mSelections.removeOne(selection); +} + +void QWaylandClipboard::syncCallback(void *data) +{ + *static_cast<bool *>(data) = true; +} + +void QWaylandClipboard::forceRoundtrip(struct wl_display *display) +{ + bool done = false; + wl_display_sync_callback(display, syncCallback, &done); + wl_display_iterate(display, WL_DISPLAY_WRITABLE); + while (!done) + wl_display_iterate(display, WL_DISPLAY_READABLE); +} + +QVariant QWaylandClipboard::retrieveData(const QString &mimeType, QVariant::Type type) const +{ + Q_UNUSED(type); + if (mOfferedMimeTypes.isEmpty() || !mOffer) + return QVariant(); + int pipefd[2]; + if (pipe(pipefd) == -1) { + qWarning("QWaylandClipboard: pipe() failed"); + return QVariant(); + } + QByteArray mimeTypeBa = mimeType.toLatin1(); + wl_selection_offer_receive(mOffer, mimeTypeBa.constData(), pipefd[1]); + QByteArray content; + forceRoundtrip(mDisplay->wl_display()); + char buf[256]; + int n; + close(pipefd[1]); + while ((n = QT_READ(pipefd[0], &buf, sizeof buf)) > 0) + content.append(buf, n); + close(pipefd[0]); + return content; +} + +QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode) +{ + Q_ASSERT(mode == QClipboard::Clipboard); + if (!mSelections.isEmpty()) + return mSelections.last()->mMimeData; + if (!mMimeDataIn) + mMimeDataIn = new QWaylandClipboardMimeData; + mMimeDataIn->clearAll(); + if (!mOfferedMimeTypes.isEmpty() && mOffer) + mMimeDataIn->setFormats(mOfferedMimeTypes); + return mMimeDataIn; +} + +void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) +{ + Q_ASSERT(mode == QClipboard::Clipboard); + if (!mDisplay->inputDevices().isEmpty()) { + if (!data) + data = new QMimeData; + mSelections.append(new QWaylandSelection(mDisplay, data)); + } else { + qWarning("QWaylandClipboard::setMimeData: No input devices"); + } +} + +bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const +{ + return mode == QClipboard::Clipboard; +} + +const struct wl_selection_offer_listener QWaylandClipboard::selectionOfferListener = { + QWaylandClipboard::offer, + QWaylandClipboard::keyboardFocus +}; + +void QWaylandClipboard::createSelectionOffer(uint32_t id) +{ + mOfferedMimeTypes.clear(); + if (mOffer) + wl_selection_offer_destroy(mOffer); + mOffer = 0; + struct wl_selection_offer *offer = wl_selection_offer_create(mDisplay->wl_display(), id, 1); + wl_selection_offer_add_listener(offer, &selectionOfferListener, this); +} + +void QWaylandClipboard::offer(void *data, + struct wl_selection_offer *selection_offer, + const char *type) +{ + Q_UNUSED(data); + Q_UNUSED(selection_offer); + clipboard->mOfferedMimeTypes.append(QString::fromLatin1(type)); +} + +void QWaylandClipboard::keyboardFocus(void *data, + struct wl_selection_offer *selection_offer, + wl_input_device *input_device) +{ + Q_UNUSED(data); + if (!input_device) { + wl_selection_offer_destroy(selection_offer); + clipboard->mOffer = 0; + return; + } + clipboard->mOffer = selection_offer; + if (clipboard->mSelections.isEmpty()) + QMetaObject::invokeMethod(&clipboard->mEmitter, "emitChanged", Qt::QueuedConnection); +} + +void QWaylandClipboardSignalEmitter::emitChanged() +{ + clipboard->emitChanged(QClipboard::Clipboard); +} diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.h b/src/plugins/platforms/wayland/qwaylandclipboard.h new file mode 100644 index 0000000..6b113ae --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandclipboard.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** 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 QWAYLANDCLIPBOARD_H +#define QWAYLANDCLIPBOARD_H + +#include <QtGui/QPlatformClipboard> +#include <QtCore/QStringList> +#include <QtCore/QVariant> + +class QWaylandDisplay; +class QWaylandSelection; +class QWaylandClipboardMimeData; +struct wl_selection_offer; + +class QWaylandClipboardSignalEmitter : public QObject +{ + Q_OBJECT +public slots: + void emitChanged(); +}; + +class QWaylandClipboard : public QPlatformClipboard +{ +public: + static QWaylandClipboard *instance(QWaylandDisplay *display); + + ~QWaylandClipboard(); + + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); + bool supportsMode(QClipboard::Mode mode) const; + + void unregisterSelection(QWaylandSelection *selection); + + void createSelectionOffer(uint32_t id); + + QVariant retrieveData(const QString &mimeType, QVariant::Type type) const; + +private: + QWaylandClipboard(QWaylandDisplay *display); + + static void offer(void *data, + struct wl_selection_offer *selection_offer, + const char *type); + static void keyboardFocus(void *data, + struct wl_selection_offer *selection_offer, + struct wl_input_device *input_device); + static const struct wl_selection_offer_listener selectionOfferListener; + + static void syncCallback(void *data); + static void forceRoundtrip(struct wl_display *display); + + QWaylandDisplay *mDisplay; + QWaylandClipboardMimeData *mMimeDataIn; + QList<QWaylandSelection *> mSelections; + QStringList mOfferedMimeTypes; + struct wl_selection_offer *mOffer; + QWaylandClipboardSignalEmitter mEmitter; +}; + +#endif // QWAYLANDCLIPBOARD_H diff --git a/src/plugins/platforms/wayland/qwaylandcursor.cpp b/src/plugins/platforms/wayland/qwaylandcursor.cpp new file mode 100644 index 0000000..bbbab6d --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandcursor.cpp @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** 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 "qwaylandcursor.h" + +#include "qwaylanddisplay.h" +#include "qwaylandinputdevice.h" +#include "qwaylandscreen.h" +#include "qwaylandshmbackingstore.h" + +#include <QtGui/QImageReader> +#include <QDebug> + +#define DATADIR "/usr/share" + +static const struct pointer_image { + const char *filename; + int hotspot_x, hotspot_y; +} pointer_images[] = { + /* FIXME: Half of these are wrong... */ + /* Qt::ArrowCursor */ + { DATADIR "/wayland/left_ptr.png", 10, 5 }, + /* Qt::UpArrowCursor */ + { DATADIR "/wayland/top_side.png", 18, 8 }, + /* Qt::CrossCursor */ + { DATADIR "/wayland/top_side.png", 18, 8 }, + /* Qt::WaitCursor */ + { DATADIR "/wayland/top_side.png", 18, 8 }, + /* Qt::IBeamCursor */ + { DATADIR "/wayland/xterm.png", 15, 15 }, + /* Qt::SizeVerCursor */ + { DATADIR "/wayland/top_side.png", 18, 8 }, + /* Qt::SizeHorCursor */ + { DATADIR "/wayland/bottom_left_corner.png", 6, 30 }, + /* Qt::SizeBDiagCursor */ + { DATADIR "/wayland/bottom_right_corner.png", 28, 28 }, + /* Qt::SizeFDiagCursor */ + { DATADIR "/wayland/bottom_side.png", 16, 20 }, + /* Qt::SizeAllCursor */ + { DATADIR "/wayland/left_side.png", 10, 20 }, + /* Qt::BlankCursor */ + { DATADIR "/wayland/right_side.png", 30, 19 }, + /* Qt::SplitVCursor */ + { DATADIR "/wayland/sb_v_double_arrow.png", 15, 15 }, + /* Qt::SplitHCursor */ + { DATADIR "/wayland/sb_h_double_arrow.png", 15, 15 }, + /* Qt::PointingHandCursor */ + { DATADIR "/wayland/hand2.png", 14, 8 }, + /* Qt::ForbiddenCursor */ + { DATADIR "/wayland/top_right_corner.png", 26, 8 }, + /* Qt::WhatsThisCursor */ + { DATADIR "/wayland/top_right_corner.png", 26, 8 }, + /* Qt::BusyCursor */ + { DATADIR "/wayland/top_right_corner.png", 26, 8 }, + /* Qt::OpenHandCursor */ + { DATADIR "/wayland/hand1.png", 18, 11 }, + /* Qt::ClosedHandCursor */ + { DATADIR "/wayland/grabbing.png", 20, 17 }, + /* Qt::DragCopyCursor */ + { DATADIR "/wayland/dnd-copy.png", 13, 13 }, + /* Qt::DragMoveCursor */ + { DATADIR "/wayland/dnd-move.png", 13, 13 }, + /* Qt::DragLinkCursor */ + { DATADIR "/wayland/dnd-link.png", 13, 13 }, +}; + +QWaylandCursor::QWaylandCursor(QWaylandScreen *screen) + : QPlatformCursor(screen) + , mBuffer(0) + , mDisplay(screen->display()) +{ +} + +void QWaylandCursor::changeCursor(QCursor *cursor, QWindow *window) +{ + const struct pointer_image *p; + + if (window == NULL) + return; + + p = NULL; + bool isBitmap = false; + + switch (cursor->shape()) { + case Qt::ArrowCursor: + p = &pointer_images[cursor->shape()]; + break; + case Qt::UpArrowCursor: + case Qt::CrossCursor: + case Qt::WaitCursor: + break; + case Qt::IBeamCursor: + p = &pointer_images[cursor->shape()]; + break; + case Qt::SizeVerCursor: /* 5 */ + case Qt::SizeHorCursor: + case Qt::SizeBDiagCursor: + case Qt::SizeFDiagCursor: + case Qt::SizeAllCursor: + case Qt::BlankCursor: /* 10 */ + break; + case Qt::SplitVCursor: + case Qt::SplitHCursor: + case Qt::PointingHandCursor: + p = &pointer_images[cursor->shape()]; + break; + case Qt::ForbiddenCursor: + case Qt::WhatsThisCursor: /* 15 */ + case Qt::BusyCursor: + break; + case Qt::OpenHandCursor: + case Qt::ClosedHandCursor: + case Qt::DragCopyCursor: + case Qt::DragMoveCursor: /* 20 */ + case Qt::DragLinkCursor: + p = &pointer_images[cursor->shape()]; + break; + + case Qt::BitmapCursor: + isBitmap = true; + break; + + default: + break; + } + + if (!p && !isBitmap) { + p = &pointer_images[0]; + qWarning("unhandled cursor %d", cursor->shape()); + } + + 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); + } +} + +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); + } + 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) +{ + /* Qt doesn't tell us which input device we should set the cursor + * for, so set it for all devices. */ + for (int i = 0; i < mInputDevices.count(); i++) { + QWaylandInputDevice *inputDevice = mInputDevices.at(i); + 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 new file mode 100644 index 0000000..8753aa5 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandcursor.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 QWAYLANDCURSOR_H +#define QWAYLANDCURSOR_H + +#include <QtGui/QPlatformCursor> + +class QWaylandShmBuffer; +class QWaylandDisplay; +class QWaylandScreen; + +class QWaylandCursor : public QPlatformCursor +{ +public: + QWaylandCursor(QWaylandScreen *screen); + + 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 new file mode 100644 index 0000000..5880969 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -0,0 +1,339 @@ +/**************************************************************************** +** +** 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 "qwaylanddisplay.h" + +#include "qwaylandwindow.h" +#include "qwaylandscreen.h" +#include "qwaylandcursor.h" +#include "qwaylandinputdevice.h" +#include "qwaylandclipboard.h" +#include "qwaylanddnd.h" + +#ifdef QT_WAYLAND_GL_SUPPORT +#include "gl_integration/qwaylandglintegration.h" +#endif + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT +#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" +#endif + +#include <QtCore/QAbstractEventDispatcher> +#include <QtGui/private/qguiapplication_p.h> + +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <errno.h> + +struct wl_surface *QWaylandDisplay::createSurface(void *handle) +{ + struct wl_surface * surface = wl_compositor_create_surface(mCompositor); + wl_surface_set_user_data(surface, handle); + return surface; +} + +struct wl_buffer *QWaylandDisplay::createShmBuffer(int fd, + int width, int height, + uint32_t stride, + struct wl_visual *visual) +{ + return wl_shm_create_buffer(mShm, fd, width, height, stride, visual); +} + +struct wl_visual *QWaylandDisplay::rgbVisual() +{ + return rgb_visual; +} + +struct wl_visual *QWaylandDisplay::argbVisual() +{ + return argb_visual; +} + +struct wl_visual *QWaylandDisplay::argbPremultipliedVisual() +{ + return premultiplied_argb_visual; +} + +#ifdef QT_WAYLAND_GL_SUPPORT +QWaylandGLIntegration * QWaylandDisplay::eglIntegration() +{ + return mEglIntegration; +} +#endif + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT +QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() +{ + return mWindowManagerIntegration; +} +#endif + +void QWaylandDisplay::shellHandleConfigure(void *data, struct wl_shell *shell, + uint32_t time, uint32_t edges, + struct wl_surface *surface, + int32_t width, int32_t height) +{ + Q_UNUSED(data); + Q_UNUSED(shell); + Q_UNUSED(time); + Q_UNUSED(edges); + QWaylandWindow *ww = (QWaylandWindow *) wl_surface_get_user_data(surface); + + ww->configure(time, edges, 0, 0, width, height); +} + +const struct wl_shell_listener QWaylandDisplay::shellListener = { + QWaylandDisplay::shellHandleConfigure, +}; + +static QWaylandDisplay *display = 0; + +QWaylandDisplay::QWaylandDisplay(void) + : argb_visual(0), premultiplied_argb_visual(0), rgb_visual(0) +{ + display = this; + qRegisterMetaType<uint32_t>("uint32_t"); + + mDisplay = wl_display_connect(NULL); + if (mDisplay == NULL) { + qErrnoWarning(errno, "Failed to create display"); + qFatal("No wayland connection available."); + } + + 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 + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT + mWindowManagerIntegration = QWaylandWindowManagerIntegration::createIntegration(this); +#endif + + blockingReadEvents(); + +#ifdef QT_WAYLAND_GL_SUPPORT + mEglIntegration->initialize(); +#endif + + waitForScreens(); +} + +QWaylandDisplay::~QWaylandDisplay(void) +{ + close(mFd); +#ifdef QT_WAYLAND_GL_SUPPORT + delete mEglIntegration; +#endif + wl_display_destroy(mDisplay); +} + +void QWaylandDisplay::createNewScreen(struct wl_output *output, QRect geometry) +{ + QWaylandScreen *waylandScreen = new QWaylandScreen(this,output,geometry); + mScreens.append(waylandScreen); +} + +void QWaylandDisplay::syncCallback(wl_display_sync_func_t func, void *data) +{ + wl_display_sync_callback(mDisplay, func, data); +} + +void QWaylandDisplay::frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data) +{ + wl_display_frame_callback(mDisplay, surface, func, data); +} + +void QWaylandDisplay::flushRequests() +{ + if (mSocketMask & WL_DISPLAY_WRITABLE) + wl_display_iterate(mDisplay, WL_DISPLAY_WRITABLE); +} + +void QWaylandDisplay::readEvents() +{ +// verify that there is still data on the socket + fd_set fds; + FD_ZERO(&fds); + FD_SET(mFd, &fds); + fd_set nds; + FD_ZERO(&nds); + fd_set rs = fds; + fd_set ws = nds; + fd_set es = nds; + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + int ret = ::select(mFd+1, &rs, &ws, &es, &timeout ); + + if (ret <= 0) { + //qDebug("QWaylandDisplay::readEvents() No data... blocking avoided"); + return; + } + + wl_display_iterate(mDisplay, WL_DISPLAY_READABLE); +} + +void QWaylandDisplay::blockingReadEvents() +{ + wl_display_iterate(mDisplay, WL_DISPLAY_READABLE); +} + +int QWaylandDisplay::sourceUpdate(uint32_t mask, void *data) +{ + QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data); + waylandDisplay->mSocketMask = mask; + + return 0; +} + +void QWaylandDisplay::outputHandleGeometry(void *data, + wl_output *output, + int32_t x, int32_t y, + int32_t physicalWidth, + int32_t physicalHeight, + int subpixel, + const char *make, const char *model) +{ + QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data); + QRect outputRect = QRect(x, y, physicalWidth, physicalHeight); + waylandDisplay->createNewScreen(output,outputRect); +} + +void QWaylandDisplay::mode(void *data, + struct wl_output *wl_output, + uint32_t flags, + int width, + int height, + int refresh) +{ + Q_UNUSED(data); + Q_UNUSED(wl_output); + Q_UNUSED(flags); + Q_UNUSED(width); + Q_UNUSED(height); + Q_UNUSED(refresh); +} + +const struct wl_output_listener QWaylandDisplay::outputListener = { + QWaylandDisplay::outputHandleGeometry, + QWaylandDisplay::mode +}; + +const struct wl_compositor_listener QWaylandDisplay::compositorListener = { + QWaylandDisplay::handleVisual, +}; + + +void QWaylandDisplay::waitForScreens() +{ + flushRequests(); + while (mScreens.isEmpty()) + blockingReadEvents(); +} + +void QWaylandDisplay::displayHandleGlobal(struct wl_display *display, + uint32_t id, + const char *interface, + uint32_t version, + void *data) +{ + Q_UNUSED(display); + QWaylandDisplay *that = static_cast<QWaylandDisplay *>(data); + that->displayHandleGlobal(id, QByteArray(interface), version); +} + +void QWaylandDisplay::displayHandleGlobal(uint32_t id, + const QByteArray &interface, + uint32_t version) +{ + Q_UNUSED(version); + if (interface == "wl_output") { + struct wl_output *output = wl_output_create(mDisplay, id, 1); + wl_output_add_listener(output, &outputListener, this); + } else if (interface == "wl_compositor") { + mCompositor = wl_compositor_create(mDisplay, id, 1); + wl_compositor_add_listener(mCompositor, + &compositorListener, this); + } else if (interface == "wl_shm") { + mShm = wl_shm_create(mDisplay, id, 1); + } else if (interface == "wl_shell"){ + mShell = wl_shell_create(mDisplay, id, 1); + wl_shell_add_listener(mShell, &shellListener, this); + } else if (interface == "wl_input_device") { + QWaylandInputDevice *inputDevice = + new QWaylandInputDevice(this, 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); + } +} + +void QWaylandDisplay::handleVisual(void *data, + struct wl_compositor *compositor, + uint32_t id, uint32_t token) +{ + QWaylandDisplay *self = static_cast<QWaylandDisplay *>(data); + + switch (token) { + case WL_COMPOSITOR_VISUAL_ARGB32: + self->argb_visual = wl_visual_create(self->mDisplay, id, 1); + break; + case WL_COMPOSITOR_VISUAL_PREMULTIPLIED_ARGB32: + self->premultiplied_argb_visual = + wl_visual_create(self->mDisplay, id, 1); + break; + case WL_COMPOSITOR_VISUAL_XRGB32: + self->rgb_visual = wl_visual_create(self->mDisplay, id, 1); + break; + } +} diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h new file mode 100644 index 0000000..2b7f33f --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** 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 QWAYLANDDISPLAY_H +#define QWAYLANDDISPLAY_H + +#include <QtCore/QObject> +#include <QtCore/QRect> + +#include <QtCore/QWaitCondition> + +#include <wayland-client.h> + +class QAbstractEventDispatcher; +class QWaylandInputDevice; +class QSocketNotifier; +class QWaylandBuffer; +class QPlatformScreen; +class QWaylandScreen; +class QWaylandGLIntegration; +class QWaylandWindowManagerIntegration; + +class QWaylandDisplay : public QObject { + Q_OBJECT + +public: + QWaylandDisplay(void); + ~QWaylandDisplay(void); + + QList<QPlatformScreen *> screens() const { return mScreens; } + struct wl_surface *createSurface(void *handle); + struct wl_buffer *createShmBuffer(int fd, int width, int height, + uint32_t stride, + struct wl_visual *visual); + struct wl_visual *rgbVisual(); + struct wl_visual *argbVisual(); + struct wl_visual *argbPremultipliedVisual(); + +#ifdef QT_WAYLAND_GL_SUPPORT + QWaylandGLIntegration *eglIntegration(); +#endif + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT + QWaylandWindowManagerIntegration *windowManagerIntegration(); +#endif + + void setCursor(QWaylandBuffer *buffer, int32_t x, int32_t y); + + void syncCallback(wl_display_sync_func_t func, void *data); + void frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data); + + struct wl_display *wl_display() const { return mDisplay; } + struct wl_shell *wl_shell() const { return mShell; } + + QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; } + +public slots: + void createNewScreen(struct wl_output *output, QRect geometry); + void readEvents(); + void blockingReadEvents(); + void flushRequests(); + +private: + void waitForScreens(); + void displayHandleGlobal(uint32_t id, + const QByteArray &interface, + uint32_t version); + + struct wl_display *mDisplay; + struct wl_compositor *mCompositor; + struct wl_shm *mShm; + struct wl_shell *mShell; + QList<QPlatformScreen *> mScreens; + QList<QWaylandInputDevice *> mInputDevices; + + QSocketNotifier *mReadNotifier; + int mFd; + bool mScreensInitialized; + + uint32_t mSocketMask; + + struct wl_visual *argb_visual, *premultiplied_argb_visual, *rgb_visual; + + static const struct wl_output_listener outputListener; + static const struct wl_compositor_listener compositorListener; + static int sourceUpdate(uint32_t mask, void *data); + static void displayHandleGlobal(struct wl_display *display, + uint32_t id, + const char *interface, + uint32_t version, void *data); + static void outputHandleGeometry(void *data, + struct wl_output *output, + int32_t x, int32_t y, + int32_t width, int32_t height, + int subpixel, + const char *make, + const char *model); + static void mode(void *data, + struct wl_output *wl_output, + uint32_t flags, + int width, + int height, + int refresh); + + static void handleVisual(void *data, + struct wl_compositor *compositor, + uint32_t id, uint32_t token); + +#ifdef QT_WAYLAND_GL_SUPPORT + QWaylandGLIntegration *mEglIntegration; +#endif + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT + QWaylandWindowManagerIntegration *mWindowManagerIntegration; +#endif + + static void shellHandleConfigure(void *data, struct wl_shell *shell, + uint32_t time, uint32_t edges, + struct wl_surface *surface, + int32_t width, int32_t height); + + static const struct wl_shell_listener shellListener; +}; + +#endif // QWAYLANDDISPLAY_H diff --git a/src/plugins/platforms/wayland/qwaylanddnd.cpp b/src/plugins/platforms/wayland/qwaylanddnd.cpp new file mode 100644 index 0000000..5368daa --- /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 0000000..ebafd96 --- /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 new file mode 100644 index 0000000..c1e2325 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -0,0 +1,511 @@ +/**************************************************************************** +** +** 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 "qwaylandinputdevice.h" + +#include "qwaylandintegration.h" +#include "qwaylandwindow.h" +#include "qwaylandbuffer.h" + +#include <QtGui/private/qpixmap_raster_p.h> +#include <QtGui/QPlatformWindow> +#include <QDebug> + +#include <unistd.h> +#include <fcntl.h> + +#ifndef QT_NO_WAYLAND_XKB +#include <X11/extensions/XKBcommon.h> +#include <X11/keysym.h> +#endif + +//#define POINT_DEBUG + +QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, + uint32_t id) + : mQDisplay(display) + , mDisplay(display->wl_display()) + , mInputDevice(wl_input_device_create(mDisplay, id, 1)) + , mPointerFocus(NULL) + , mKeyboardFocus(NULL) + , mButtons(0) + , mTouchState(QEvent::TouchBegin) +{ + wl_input_device_add_listener(mInputDevice, + &inputDeviceListener, + this); + wl_input_device_set_user_data(mInputDevice, this); + +#ifndef QT_NO_WAYLAND_XKB + struct xkb_rule_names names; + names.rules = "evdev"; + names.model = "pc105"; + names.layout = "us"; + names.variant = ""; + names.options = ""; + + mXkb = xkb_compile_keymap_from_rules(&names); +#endif +} + +void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window) +{ + if (window == mPointerFocus) + mPointerFocus = 0; + if (window == mKeyboardFocus) + mKeyboardFocus = 0; +} + +void QWaylandInputDevice::inputHandleMotion(void *data, + struct wl_input_device *input_device, + uint32_t time, + int32_t x, int32_t y, + int32_t surface_x, int32_t surface_y) +{ + Q_UNUSED(input_device); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + QWaylandWindow *window = inputDevice->mPointerFocus; + + if (window == NULL) { + /* We destroyed the pointer focus surface, but the server + * didn't get the message yet. */ + return; + } + + inputDevice->mSurfacePos = QPoint(surface_x, surface_y); + inputDevice->mGlobalPos = QPoint(x, y); + inputDevice->mTime = time; + QWindowSystemInterface::handleMouseEvent(window->window(), + time, + inputDevice->mSurfacePos, + inputDevice->mGlobalPos, + inputDevice->mButtons); +} + +void QWaylandInputDevice::inputHandleButton(void *data, + struct wl_input_device *input_device, + uint32_t time, uint32_t button, uint32_t state) +{ + Q_UNUSED(input_device); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + QWaylandWindow *window = inputDevice->mPointerFocus; + Qt::MouseButton qt_button; + + if (window == NULL) { + /* We destroyed the pointer focus surface, but the server + * didn't get the message yet. */ + return; + } + + switch (button) { + case 272: + qt_button = Qt::LeftButton; + break; + case 273: + qt_button = Qt::RightButton; + break; + case 274: + qt_button = Qt::MiddleButton; + break; + default: + return; + } + + if (state) + inputDevice->mButtons |= qt_button; + else + inputDevice->mButtons &= ~qt_button; + + inputDevice->mTime = time; + QWindowSystemInterface::handleMouseEvent(window->window(), + time, + inputDevice->mSurfacePos, + inputDevice->mGlobalPos, + inputDevice->mButtons); +} + +#ifndef QT_NO_WAYLAND_XKB +static Qt::KeyboardModifiers translateModifiers(int s) +{ + const uchar qt_alt_mask = XKB_COMMON_MOD1_MASK; + const uchar qt_meta_mask = XKB_COMMON_MOD4_MASK; + + Qt::KeyboardModifiers ret = 0; + if (s & XKB_COMMON_SHIFT_MASK) + ret |= Qt::ShiftModifier; + if (s & XKB_COMMON_CONTROL_MASK) + ret |= Qt::ControlModifier; + if (s & qt_alt_mask) + ret |= Qt::AltModifier; + if (s & qt_meta_mask) + ret |= Qt::MetaModifier; + + return ret; +} + +static uint32_t translateKey(uint32_t sym, char *string, size_t size) +{ + Q_UNUSED(size); + string[0] = '\0'; + + switch (sym) { + case XK_Escape: return Qt::Key_Escape; + case XK_Tab: return Qt::Key_Tab; + case XK_ISO_Left_Tab: return Qt::Key_Backtab; + case XK_BackSpace: return Qt::Key_Backspace; + case XK_Return: return Qt::Key_Return; + case XK_Insert: return Qt::Key_Insert; + case XK_Delete: return Qt::Key_Delete; + case XK_Clear: return Qt::Key_Delete; + case XK_Pause: return Qt::Key_Pause; + case XK_Print: return Qt::Key_Print; + + case XK_Home: return Qt::Key_Home; + case XK_End: return Qt::Key_End; + case XK_Left: return Qt::Key_Left; + case XK_Up: return Qt::Key_Up; + case XK_Right: return Qt::Key_Right; + case XK_Down: return Qt::Key_Down; + case XK_Prior: return Qt::Key_PageUp; + case XK_Next: return Qt::Key_PageDown; + + case XK_Shift_L: return Qt::Key_Shift; + case XK_Shift_R: return Qt::Key_Shift; + case XK_Shift_Lock: return Qt::Key_Shift; + case XK_Control_L: return Qt::Key_Control; + case XK_Control_R: return Qt::Key_Control; + case XK_Meta_L: return Qt::Key_Meta; + case XK_Meta_R: return Qt::Key_Meta; + case XK_Alt_L: return Qt::Key_Alt; + case XK_Alt_R: return Qt::Key_Alt; + case XK_Caps_Lock: return Qt::Key_CapsLock; + case XK_Num_Lock: return Qt::Key_NumLock; + case XK_Scroll_Lock: return Qt::Key_ScrollLock; + case XK_Super_L: return Qt::Key_Super_L; + case XK_Super_R: return Qt::Key_Super_R; + case XK_Menu: return Qt::Key_Menu; + + default: + string[0] = sym; + string[1] = '\0'; + return toupper(sym); + } +} +#endif + +void QWaylandInputDevice::inputHandleKey(void *data, + struct wl_input_device *input_device, + uint32_t time, uint32_t key, uint32_t state) +{ +#ifndef QT_NO_WAYLAND_XKB + Q_UNUSED(input_device); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + QWaylandWindow *window = inputDevice->mKeyboardFocus; + uint32_t code, sym, level; + Qt::KeyboardModifiers modifiers; + QEvent::Type type; + char s[2]; + + if (window == NULL) { + /* We destroyed the keyboard focus surface, but the server + * didn't get the message yet. */ + return; + } + + code = key + inputDevice->mXkb->min_key_code; + + level = 0; + if (inputDevice->mModifiers & Qt::ShiftModifier && + XkbKeyGroupWidth(inputDevice->mXkb, code, 0) > 1) + level = 1; + + sym = XkbKeySymEntry(inputDevice->mXkb, code, level, 0); + + modifiers = translateModifiers(inputDevice->mXkb->map->modmap[code]); + + if (state) { + inputDevice->mModifiers |= modifiers; + type = QEvent::KeyPress; + } else { + inputDevice->mModifiers &= ~modifiers; + type = QEvent::KeyRelease; + } + + sym = translateKey(sym, s, sizeof s); + + if (window) { + QWindowSystemInterface::handleKeyEvent(window->window(), + time, type, sym, + inputDevice->mModifiers, + QString::fromLatin1(s)); + } +#endif +} + +void QWaylandInputDevice::inputHandlePointerFocus(void *data, + struct wl_input_device *input_device, + uint32_t time, struct wl_surface *surface, + int32_t x, int32_t y, int32_t sx, int32_t sy) +{ + Q_UNUSED(input_device); + Q_UNUSED(x); + Q_UNUSED(y); + Q_UNUSED(sx); + Q_UNUSED(sy); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + QWaylandWindow *window; + + if (inputDevice->mPointerFocus) { + window = inputDevice->mPointerFocus; + QWindowSystemInterface::handleLeaveEvent(window->window()); + inputDevice->mPointerFocus = NULL; + } + + if (surface) { + window = (QWaylandWindow *) wl_surface_get_user_data(surface); + QWindowSystemInterface::handleEnterEvent(window->window()); + inputDevice->mPointerFocus = window; + } + + inputDevice->mTime = time; +} + +void QWaylandInputDevice::inputHandleKeyboardFocus(void *data, + struct wl_input_device *input_device, + uint32_t time, + struct wl_surface *surface, + struct wl_array *keys) +{ +#ifndef QT_NO_WAYLAND_XKB + Q_UNUSED(input_device); + Q_UNUSED(time); + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + QWaylandWindow *window; + uint32_t *k, *end; + uint32_t code; + + end = (uint32_t *) ((char *) keys->data + keys->size); + inputDevice->mModifiers = 0; + for (k = (uint32_t *) keys->data; k < end; k++) { + code = *k + inputDevice->mXkb->min_key_code; + inputDevice->mModifiers |= + translateModifiers(inputDevice->mXkb->map->modmap[code]); + } + + if (surface) { + window = (QWaylandWindow *) wl_surface_get_user_data(surface); + inputDevice->mKeyboardFocus = window; + QWindowSystemInterface::handleWindowActivated(window->window()); + } else { + inputDevice->mKeyboardFocus = NULL; + QWindowSystemInterface::handleWindowActivated(0); + } +#endif +} + +void QWaylandInputDevice::inputHandleTouchDown(void *data, + struct wl_input_device *wl_input_device, + uint32_t time, + int id, + int x, + int y) +{ + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + inputDevice->handleTouchPoint(id, x, y, Qt::TouchPointPressed); +} + +void QWaylandInputDevice::inputHandleTouchUp(void *data, + struct wl_input_device *wl_input_device, + uint32_t time, + int id) +{ + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + inputDevice->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); +} + +void QWaylandInputDevice::inputHandleTouchMotion(void *data, + struct wl_input_device *wl_input_device, + uint32_t time, + int id, + int x, + int y) +{ + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + inputDevice->handleTouchPoint(id, x, y, Qt::TouchPointMoved); +} + +void QWaylandInputDevice::handleTouchPoint(int id, int x, int y, Qt::TouchPointState state) +{ + QWindowSystemInterface::TouchPoint tp; + + // Find out the coordinates for Released events. + bool coordsOk = false; + if (state == Qt::TouchPointReleased) + for (int i = 0; i < mPrevTouchPoints.count(); ++i) + if (mPrevTouchPoints.at(i).id == id) { + tp.area = mPrevTouchPoints.at(i).area; + coordsOk = true; + break; + } + + if (!coordsOk) { + // x and y are surface relative. + // We need a global (screen) position. + + QWaylandWindow *win = mPointerFocus; + if (!win) + win = mKeyboardFocus; +#ifdef POINT_DEBUG + qDebug() << "surface relative coords" << x << y << "using window" << win; +#endif + if (!win) + return; + + QRect winRect = win->geometry(); + + // Get a normalized position (0..1). + const qreal nx = x / qreal(winRect.width()); + const qreal ny = y / qreal(winRect.height()); + tp.normalPosition = QPointF(nx, ny); + + // Map to screen. + QPlatformScreen *screen = mQDisplay->screens().at(0); + QRect screenRect = screen->geometry(); + x = int(nx * screenRect.width()); + y = int(ny * screenRect.height()); + +#ifdef POINT_DEBUG + qDebug() << "normalized position" << nx << ny + << "win rect" << winRect << "screen rect" << screenRect; + qDebug() << "mapped to screen position" << x << y; +#endif + + tp.area = QRectF(x, y, 1, 1); + } + + tp.state = state; + tp.id = id; + tp.isPrimary = mTouchPoints.isEmpty(); + tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1; + mTouchPoints.append(tp); +} + +void QWaylandInputDevice::inputHandleTouchFrame(void *data, struct wl_input_device *wl_input_device) +{ + QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; + inputDevice->handleTouchFrame(); +} + +void QWaylandInputDevice::handleTouchFrame() +{ + // Copy all points, that are in the previous but not in the current list, as stationary. + for (int i = 0; i < mPrevTouchPoints.count(); ++i) { + const QWindowSystemInterface::TouchPoint &prevPoint(mPrevTouchPoints.at(i)); + if (prevPoint.state == Qt::TouchPointReleased) + continue; + bool found = false; + for (int j = 0; j < mTouchPoints.count(); ++j) + if (mTouchPoints.at(j).id == prevPoint.id) { + found = true; + break; + } + if (!found) { + QWindowSystemInterface::TouchPoint p = prevPoint; + p.state = Qt::TouchPointStationary; + mTouchPoints.append(p); + } + } + + if (mTouchPoints.isEmpty()) { + mPrevTouchPoints.clear(); + return; + } + +#ifdef POINT_DEBUG + qDebug() << mTouchPoints.count() << "touchpoints, event type" << mTouchState; + for (int i = 0; i < mTouchPoints.count(); ++i) + qDebug() << " " << mTouchPoints[i].id << mTouchPoints[i].state << mTouchPoints[i].area; +#endif + + QWindowSystemInterface::handleTouchEvent(0, mTouchState, QTouchEvent::TouchScreen, mTouchPoints); + + bool allReleased = true; + for (int i = 0; i < mTouchPoints.count(); ++i) + if (mTouchPoints.at(i).state != Qt::TouchPointReleased) { + allReleased = false; + break; + } + + mPrevTouchPoints = mTouchPoints; + mTouchPoints.clear(); + + if (allReleased) { +#ifdef POINT_DEBUG + qDebug() << mTouchPoints.count() << "touchpoints, event type" << QEvent::TouchEnd; +#endif + QWindowSystemInterface::handleTouchEvent(0, QEvent::TouchEnd, QTouchEvent::TouchScreen, mTouchPoints); + mTouchState = QEvent::TouchBegin; + mPrevTouchPoints.clear(); + } else if (mTouchState == QEvent::TouchBegin) + mTouchState = QEvent::TouchUpdate; +} + +void QWaylandInputDevice::inputHandleTouchCancel(void *data, struct wl_input_device *wl_input_device) +{ +} + +const struct wl_input_device_listener QWaylandInputDevice::inputDeviceListener = { + QWaylandInputDevice::inputHandleMotion, + QWaylandInputDevice::inputHandleButton, + QWaylandInputDevice::inputHandleKey, + QWaylandInputDevice::inputHandlePointerFocus, + QWaylandInputDevice::inputHandleKeyboardFocus, + QWaylandInputDevice::inputHandleTouchDown, + QWaylandInputDevice::inputHandleTouchUp, + QWaylandInputDevice::inputHandleTouchMotion, + QWaylandInputDevice::inputHandleTouchFrame, + QWaylandInputDevice::inputHandleTouchCancel +}; + +void QWaylandInputDevice::attach(QWaylandBuffer *buffer, int x, int y) +{ + wl_input_device_attach(mInputDevice, mTime, buffer->buffer(), x, y); +} diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h new file mode 100644 index 0000000..05ebe05 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** 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 QWAYLANDINPUTDEVICE_H +#define QWAYLANDINPUTDEVICE_H + +#include "qwaylandwindow.h" + +#include <QSocketNotifier> +#include <QObject> +#include <QtGui/QPlatformIntegration> +#include <QtGui/QPlatformScreen> +#include <QWindowSystemInterface> + +#include <wayland-client.h> + +QT_BEGIN_NAMESPACE + +class QWaylandWindow; +class QWaylandDisplay; + +class QWaylandInputDevice { +public: + QWaylandInputDevice(QWaylandDisplay *display, uint32_t id); + 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; + struct wl_display *mDisplay; + struct wl_input_device *mInputDevice; + QWaylandWindow *mPointerFocus; + QWaylandWindow *mKeyboardFocus; + static const struct wl_input_device_listener inputDeviceListener; + Qt::MouseButtons mButtons; + QPoint mSurfacePos; + QPoint mGlobalPos; + struct xkb_desc *mXkb; + Qt::KeyboardModifiers mModifiers; + uint32_t mTime; + + static void inputHandleMotion(void *data, + struct wl_input_device *input_device, + uint32_t time, + int32_t x, int32_t y, + int32_t sx, int32_t sy); + static void inputHandleButton(void *data, + struct wl_input_device *input_device, + uint32_t time, uint32_t button, uint32_t state); + static void inputHandleKey(void *data, + struct wl_input_device *input_device, + uint32_t time, uint32_t key, uint32_t state); + static void inputHandlePointerFocus(void *data, + struct wl_input_device *input_device, + uint32_t time, struct wl_surface *surface, + int32_t x, int32_t y, int32_t sx, int32_t sy); + static void inputHandleKeyboardFocus(void *data, + struct wl_input_device *input_device, + uint32_t time, + struct wl_surface *surface, + struct wl_array *keys); + static void inputHandleTouchDown(void *data, + struct wl_input_device *wl_input_device, + uint32_t time, + int id, + int x, + int y); + static void inputHandleTouchUp(void *data, + struct wl_input_device *wl_input_device, + uint32_t time, + int id); + static void inputHandleTouchMotion(void *data, + struct wl_input_device *wl_input_device, + uint32_t time, + int id, + int x, + int y); + static void inputHandleTouchFrame(void *data, + struct wl_input_device *wl_input_device); + static void inputHandleTouchCancel(void *data, + struct wl_input_device *wl_input_device); + + void handleTouchPoint(int id, int x, int y, Qt::TouchPointState state); + void handleTouchFrame(); + QList<QWindowSystemInterface::TouchPoint> mTouchPoints; + QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; + QEvent::Type mTouchState; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp new file mode 100644 index 0000000..e17c2f8 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -0,0 +1,141 @@ +/**************************************************************************** +** +** 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 config.tests 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 "qwaylandintegration.h" + +#include "qwaylanddisplay.h" +#include "qwaylandshmbackingstore.h" +#include "qwaylandshmwindow.h" +#include "qwaylandnativeinterface.h" +#include "qwaylandclipboard.h" +#include "qwaylanddnd.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/QSurfaceFormat> +#include <QtGui/QOpenGLContext> + +#ifdef QT_WAYLAND_GL_SUPPORT +#include "gl_integration/qwaylandglintegration.h" +#endif + +QWaylandIntegration::QWaylandIntegration() + : mFontDb(new QGenericUnixFontDatabase()) + , mEventDispatcher(createUnixEventDispatcher()) + , mNativeInterface(new QWaylandNativeInterface) +{ + QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher); + mDisplay = new QWaylandDisplay(); + + foreach (QPlatformScreen *screen, mDisplay->screens()) + screenAdded(screen); +} + +QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const +{ + return mNativeInterface; +} + +bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) const +{ + switch (cap) { + case ThreadedPixmaps: return true; + case OpenGL: +#ifdef QT_WAYLAND_GL_SUPPORT + return true; +#else + return false; +#endif + case ThreadedOpenGL: + return hasCapability(OpenGL); + default: return QPlatformIntegration::hasCapability(cap); + } +} + +QPlatformWindow *QWaylandIntegration::createPlatformWindow(QWindow *window) const +{ +#ifdef QT_WAYLAND_GL_SUPPORT + if (window->surfaceType() == QWindow::OpenGLSurface) + return mDisplay->eglIntegration()->createEglWindow(window); +#endif + return new QWaylandShmWindow(window); +} + +QPlatformOpenGLContext *QWaylandIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const +{ +#ifdef QT_WAYLAND_GL_SUPPORT + return mDisplay->eglIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle()); +#else + Q_UNUSED(glFormat); + Q_UNUSED(share); + return 0; +#endif +} + +QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const +{ + return new QWaylandShmBackingStore(window); +} + +QAbstractEventDispatcher *QWaylandIntegration::guiThreadEventDispatcher() const +{ + return mEventDispatcher; +} + +QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const +{ + 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 new file mode 100644 index 0000000..61e8559 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -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$ +** +****************************************************************************/ + +#ifndef QPLATFORMINTEGRATION_WAYLAND_H +#define QPLATFORMINTEGRATION_WAYLAND_H + +#include <QtGui/QPlatformIntegration> + +QT_BEGIN_NAMESPACE + +class QWaylandBuffer; +class QWaylandDisplay; +class QAbstractEventDispatcher; + +class QWaylandIntegration : public QPlatformIntegration +{ +public: + QWaylandIntegration(); + + bool hasCapability(QPlatformIntegration::Capability cap) const; + QPlatformWindow *createPlatformWindow(QWindow *window) const; + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; + QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; + + QAbstractEventDispatcher *guiThreadEventDispatcher() const; + + QPlatformFontDatabase *fontDatabase() const; + + QPlatformNativeInterface *nativeInterface() const; + + QPlatformClipboard *clipboard() const; + + QPlatformDrag *drag() const; + +private: + QPlatformFontDatabase *mFontDb; + QAbstractEventDispatcher *mEventDispatcher; + QWaylandDisplay *mDisplay; + QPlatformNativeInterface *mNativeInterface; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/wayland/qwaylandmime.cpp b/src/plugins/platforms/wayland/qwaylandmime.cpp new file mode 100644 index 0000000..c218d7d --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandmime.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** 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 "qwaylandmime.h" +#include <QImage> +#include <QColor> +#include <QUrl> +#include <QBuffer> +#include <QImageWriter> + +QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &mimeType) +{ + QByteArray content; + if (mimeType == QLatin1String("text/plain")) { + content = mimeData->text().toUtf8(); + } else if (mimeData->hasImage() + && (mimeType == QLatin1String("application/x-qt-image") + || mimeType.startsWith("image/"))) { + QImage image = qvariant_cast<QImage>(mimeData->imageData()); + if (!image.isNull()) { + QBuffer buf; + buf.open(QIODevice::ReadWrite); + QByteArray fmt = "BMP"; + if (mimeType.startsWith("image/")) { + QByteArray imgFmt = mimeType.mid(6).toUpper().toAscii(); + if (QImageWriter::supportedImageFormats().contains(imgFmt)) + fmt = imgFmt; + } + QImageWriter wr(&buf, fmt); + wr.write(image); + content = buf.buffer(); + } + } else if (mimeType == QLatin1String("application/x-color")) { + content = qvariant_cast<QColor>(mimeData->colorData()).name().toAscii(); + } else if (mimeType == QLatin1String("text/uri-list")) { + QList<QUrl> urls = mimeData->urls(); + for (int i = 0; i < urls.count(); ++i) { + content.append(urls.at(i).toEncoded()); + content.append('\n'); + } + } else { + content = mimeData->data(mimeType); + } + return content; +} diff --git a/src/plugins/platforms/wayland/qwaylandmime.h b/src/plugins/platforms/wayland/qwaylandmime.h new file mode 100644 index 0000000..5f6ed95 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandmime.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** 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 QWAYLANDMIME_H +#define QWAYLANDMIME_H + +#include <QString> +#include <QByteArray> +#include <QMimeData> + +class QWaylandMimeHelper +{ +public: + static QByteArray getByteArray(QMimeData *mimeData, const QString &mimeType); +}; + +#endif diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp new file mode 100644 index 0000000..d81fa35 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** 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 "qwaylandnativeinterface.h" +#include "qwaylanddisplay.h" +#include "qwaylandwindow.h" +#include <QtGui/private/qguiapplication_p.h> +#include <QtGui/QScreen> + +#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" + +void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) +{ + QByteArray lowerCaseResource = resourceString.toLower(); + + if (lowerCaseResource == "display") + return qPlatformScreenForWindow(window)->display()->wl_display(); + if (lowerCaseResource == "surface") { + return ((QWaylandWindow *) window->handle())->wl_surface(); + } + + return NULL; +} + + +QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWindow(QWindow *window) +{ + QWaylandScreen *screen; + + if (window) { + screen = static_cast<QWaylandScreen *>(window->screen()->handle()); + } else { + screen = static_cast<QWaylandScreen *>(QGuiApplication::primaryScreen()->handle()); + } + return screen; +} + +QVariantMap QWaylandNativeInterface::windowProperties(QPlatformWindow *window) const +{ + return m_windowProperties.value(window); +} + +QVariant QWaylandNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const +{ + const QVariantMap properties = m_windowProperties.value(window); + return properties.value(name); +} + +QVariant QWaylandNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const +{ + const QVariantMap properties = m_windowProperties.value(window); + return properties.value(name, defaultValue); +} + +void QWaylandNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) +{ + QVariantMap props = m_windowProperties.value(window); + props.insert(name, value); + m_windowProperties.insert(window, props); + + QWaylandWindow *wlWindow = static_cast<QWaylandWindow*>(window); + QWaylandWindowManagerIntegration::instance()->setWindowProperty(wlWindow, name, value); + + emit windowPropertyChanged(window, name); +} diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.h b/src/plugins/platforms/wayland/qwaylandnativeinterface.h new file mode 100644 index 0000000..9db442a --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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 QWAYLANDNATIVEINTERFACE_H +#define QWAYLANDNATIVEINTERFACE_H + +#include "qwaylandscreen.h" +#include <QVariantMap> +#include <QtGui/QPlatformNativeInterface> + +class QWaylandNativeInterface : public QPlatformNativeInterface +{ +public: + void *nativeResourceForWindow(const QByteArray &resourceString, + QWindow *window); + + QVariantMap windowProperties(QPlatformWindow *window) const; + QVariant windowProperty(QPlatformWindow *window, const QString &name) const; + QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const; + void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value); + +private: + static QWaylandScreen *qPlatformScreenForWindow(QWindow *window); + +private: + QHash<QPlatformWindow*, QVariantMap> m_windowProperties; +}; + + +#endif // QWAYLANDNATIVEINTERFACE_H diff --git a/src/plugins/platforms/wayland/qwaylandscreen.cpp b/src/plugins/platforms/wayland/qwaylandscreen.cpp new file mode 100644 index 0000000..7b064ba --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandscreen.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 "qwaylandscreen.h" + +#include "qwaylanddisplay.h" +#include "qwaylandcursor.h" + +QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output *output, QRect geometry) + : QPlatformScreen() + , mWaylandDisplay(waylandDisplay) + , mOutput(output) + , mGeometry(geometry) + , mDepth(32) + , mFormat(QImage::Format_ARGB32_Premultiplied) + , mWaylandCursor(new QWaylandCursor(this)) +{ +} + +QWaylandScreen::~QWaylandScreen() +{ + delete mWaylandCursor; +} + +QWaylandDisplay * QWaylandScreen::display() const +{ + return mWaylandDisplay; +} + +QRect QWaylandScreen::geometry() const +{ + return mGeometry; +} + +int QWaylandScreen::depth() const +{ + return mDepth; +} + +QImage::Format QWaylandScreen::format() const +{ + return mFormat; +} + +QWaylandScreen * QWaylandScreen::waylandScreenFromWindow(QWindow *window) +{ + QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(window); + return static_cast<QWaylandScreen *>(platformScreen); +} + +wl_visual * QWaylandScreen::visual() const +{ + struct wl_visual *visual; + + switch (format()) { + case QImage::Format_ARGB32: + visual = mWaylandDisplay->argbVisual(); + break; + case QImage::Format_ARGB32_Premultiplied: + visual = mWaylandDisplay->argbPremultipliedVisual(); + break; + default: + qDebug("unsupported buffer format %d requested\n", format()); + visual = mWaylandDisplay->argbVisual(); + break; + } + return visual; +} diff --git a/src/plugins/platforms/wayland/qwaylandscreen.h b/src/plugins/platforms/wayland/qwaylandscreen.h new file mode 100644 index 0000000..9bf4f65 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandscreen.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** 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 QWAYLANDSCREEN_H +#define QWAYLANDSCREEN_H + +#include <QtGui/QPlatformScreen> + +class QWaylandDisplay; +class QWaylandCursor; +struct wl_visual; + +class QWaylandScreen : public QPlatformScreen +{ +public: + QWaylandScreen(QWaylandDisplay *waylandDisplay, struct wl_output *output, QRect geometry); + ~QWaylandScreen(); + + QWaylandDisplay *display() const; + + QRect geometry() const; + int depth() const; + QImage::Format format() const; + + wl_visual *visual() const; + + static QWaylandScreen *waylandScreenFromWindow(QWindow *window); + +private: + QWaylandDisplay *mWaylandDisplay; + struct wl_output *mOutput; + QRect mGeometry; + int mDepth; + QImage::Format mFormat; + QSize mPhysicalSize; + QWaylandCursor *mWaylandCursor; +}; + +#endif // QWAYLANDSCREEN_H diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp new file mode 100644 index 0000000..25a1b46 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** 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 "qwaylandshmbackingstore.h" + +#include <QtCore/qdebug.h> + +#include "qwaylanddisplay.h" +#include "qwaylandshmwindow.h" +#include "qwaylandscreen.h" + +#include <wayland-client.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/mman.h> + +QT_BEGIN_NAMESPACE + +QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, + const QSize &size, QImage::Format format) +{ + int stride = size.width() * 4; + int alloc = stride * size.height(); + char filename[] = "/tmp/wayland-shm-XXXXXX"; + int fd = mkstemp(filename); + if (fd < 0) + qWarning("open %s failed: %s", filename, strerror(errno)); + if (ftruncate(fd, alloc) < 0) { + qWarning("ftruncate failed: %s", strerror(errno)); + close(fd); + return; + } + uchar *data = (uchar *) + mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + unlink(filename); + + if (data == (uchar *) MAP_FAILED) { + qWarning("mmap /dev/zero failed: %s", strerror(errno)); + close(fd); + return; + } + + mImage = QImage(data, size.width(), size.height(), stride, format); + mBuffer = display->createShmBuffer(fd, size.width(), size.height(), + stride, display->argbVisual()); + close(fd); +} + +QWaylandShmBuffer::~QWaylandShmBuffer(void) +{ + munmap((void *) mImage.constBits(), mImage.byteCount()); + wl_buffer_destroy(mBuffer); +} + +QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window) + : QPlatformBackingStore(window) + , mBuffer(0) + , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) +{ +} + +QWaylandShmBackingStore::~QWaylandShmBackingStore() +{ +} + +QPaintDevice *QWaylandShmBackingStore::paintDevice() +{ + return mBuffer->image(); +} + +void QWaylandShmBackingStore::beginPaint(const QRegion &) +{ + QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); + Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); + waylandWindow->waitForFrameSync(); +} + +void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(window); + Q_UNUSED(offset); + 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++) { + const QRect rect = rects.at(i); + wl_buffer_damage(mBuffer->buffer(),rect.x(),rect.y(),rect.width(),rect.height()); + waylandWindow->damage(rect); + } +} + +void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) +{ + QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); + Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); + + QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format(); + + if (mBuffer != NULL && mBuffer->size() == size) + return; + + if (mBuffer != NULL) + delete mBuffer; + + mBuffer = new QWaylandShmBuffer(mDisplay, size, format); + + waylandWindow->attach(mBuffer); +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.h b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h new file mode 100644 index 0000000..5e6959d --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** 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 QWAYLANDSHMBACKINGSTORE_H +#define QWAYLANDSHMBACKINGSTORE_H + +#include "qwaylandbuffer.h" +#include <QtGui/QPlatformBackingStore> +#include <QtGui/QImage> +#include <QtGui/QPlatformWindow> + +QT_BEGIN_NAMESPACE + +class QWaylandDisplay; + +class QWaylandShmBuffer : public QWaylandBuffer { +public: + QWaylandShmBuffer(QWaylandDisplay *display, + const QSize &size, QImage::Format format); + ~QWaylandShmBuffer(); + QSize size() const { return mImage.size(); } + QImage *image() { return &mImage; } +private: + QImage mImage; +}; + +class QWaylandShmBackingStore : public QPlatformBackingStore +{ +public: + QWaylandShmBackingStore(QWindow *window); + ~QWaylandShmBackingStore(); + + QPaintDevice *paintDevice(); + void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); + void resize(const QSize &size, const QRegion &staticContents); + void beginPaint(const QRegion &); + +private: + QWaylandShmBuffer *mBuffer; + QWaylandDisplay *mDisplay; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.cpp b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp new file mode 100644 index 0000000..ba5e46c --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandshmwindow.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** 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 config.tests 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 "qwaylandshmwindow.h" + +#include "qwaylandbuffer.h" + +#include <QtCore/QVector> + +#include <QtCore/QDebug> + +QWaylandShmWindow::QWaylandShmWindow(QWindow *window) + : QWaylandWindow(window) +{ + newSurfaceCreated(); +} + +QWaylandShmWindow::~QWaylandShmWindow() +{ + +} + +QWaylandWindow::WindowType QWaylandShmWindow::windowType() const +{ + return QWaylandWindow::Shm; +} + diff --git a/src/plugins/platforms/wayland/qwaylandshmwindow.h b/src/plugins/platforms/wayland/qwaylandshmwindow.h new file mode 100644 index 0000000..36f9f22 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandshmwindow.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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 config.tests 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 QWAYLANDSHMWINDOW_H +#define QWAYLANDSHMWINDOW_H + +#include "qwaylandwindow.h" +#include <QtGui/QRegion> + +class QWaylandShmWindow : public QWaylandWindow +{ +public: + QWaylandShmWindow(QWindow *window); + ~QWaylandShmWindow(); + + WindowType windowType() 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 new file mode 100644 index 0000000..6011621 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** 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 config.tests 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 "qwaylandwindow.h" + +#include "qwaylandbuffer.h" +#include "qwaylanddisplay.h" +#include "qwaylandinputdevice.h" +#include "qwaylandscreen.h" + +#include <QtGui/QWindow> + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT +#include "windowmanager_integration/qwaylandwindowmanagerintegration.h" +#endif + +#include <QCoreApplication> +#include <QtGui/QWindowSystemInterface> + +#include <QDebug> + +QWaylandWindow::QWaylandWindow(QWindow *window) + : QPlatformWindow(window) + , mSurface(0) + , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) + , mBuffer(0) + , mWaitingForFrameSync(false) +{ + static WId id = 1; + mWindowId = id++; + +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT + mDisplay->windowManagerIntegration()->mapClientToProcess(qApp->applicationPid()); + mDisplay->windowManagerIntegration()->authenticateWithToken(); +#endif +} + +QWaylandWindow::~QWaylandWindow() +{ + if (mSurface) + wl_surface_destroy(mSurface); + + QList<QWaylandInputDevice *> inputDevices = mDisplay->inputDevices(); + for (int i = 0; i < inputDevices.size(); ++i) + inputDevices.at(i)->handleWindowDestroyed(this); +} + +WId QWaylandWindow::winId() const +{ + return mWindowId; +} + +void QWaylandWindow::setParent(const QPlatformWindow *parent) +{ + Q_UNUSED(parent); + qWarning("Sub window is not supported"); +} + +void QWaylandWindow::setVisible(bool visible) +{ + if (!mSurface && visible) { + mSurface = mDisplay->createSurface(this); + newSurfaceCreated(); + } + + if (!visible) { + wl_surface_destroy(mSurface); + mSurface = NULL; + } +} + +void QWaylandWindow::configure(uint32_t time, uint32_t edges, + int32_t x, int32_t y, + int32_t width, int32_t height) +{ + Q_UNUSED(time); + Q_UNUSED(edges); + + QRect geometry = QRect(x, y, width, height); + setGeometry(geometry); + + QWindowSystemInterface::handleGeometryChange(window(), geometry); +} + +void QWaylandWindow::attach(QWaylandBuffer *buffer) +{ + mBuffer = buffer; + if (mSurface) { + wl_surface_attach(mSurface, buffer->buffer(),0,0); + QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size())); + } +} + +void QWaylandWindow::damage(const QRect &rect) +{ + //We have to do sync stuff before calling damage, or we might + //get a frame callback before we get the timestamp + if (!mWaitingForFrameSync) { + mDisplay->frameCallback(QWaylandWindow::frameCallback, mSurface, this); + mWaitingForFrameSync = true; + } + + wl_surface_damage(mSurface, + rect.x(), rect.y(), rect.width(), rect.height()); +} + +void QWaylandWindow::newSurfaceCreated() +{ + if (mBuffer) { + wl_surface_attach(mSurface,mBuffer->buffer(),0,0); + // do not damage the surface here, as this leads to graphical corruptions in the compositor until + // the first frame has been rendered + } +#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT + QWaylandWindowManagerIntegration::instance()->flushPropertyChanges(this); +#endif +} + +void QWaylandWindow::frameCallback(struct wl_surface *surface, void *data, uint32_t time) +{ + Q_UNUSED(time); + Q_UNUSED(surface); + QWaylandWindow *self = static_cast<QWaylandWindow*>(data); + self->mWaitingForFrameSync = false; +} + +void QWaylandWindow::waitForFrameSync() +{ + mDisplay->flushRequests(); + while (mWaitingForFrameSync) + mDisplay->blockingReadEvents(); +} diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h new file mode 100644 index 0000000..4f1e2c8 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** 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 config.tests 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 QWAYLANDWINDOW_H +#define QWAYLANDWINDOW_H + +#include <QtGui/QPlatformWindow> +#include <QtCore/QWaitCondition> + +#include "qwaylanddisplay.h" + +class QWaylandDisplay; +class QWaylandBuffer; +struct wl_egl_window; + +class QWaylandWindow : public QPlatformWindow +{ +public: + enum WindowType { + Shm, + Egl + }; + + QWaylandWindow(QWindow *window); + ~QWaylandWindow(); + + virtual WindowType windowType() const = 0; + WId winId() const; + void setVisible(bool visible); + void setParent(const QPlatformWindow *parent); + + void configure(uint32_t time, uint32_t edges, + int32_t x, int32_t y, int32_t width, int32_t height); + + void attach(QWaylandBuffer *buffer); + void damage(const QRect &rect); + + void waitForFrameSync(); + + struct wl_surface *wl_surface() const { return mSurface; } + +protected: + struct wl_surface *mSurface; + virtual void newSurfaceCreated(); + QWaylandDisplay *mDisplay; + QWaylandBuffer *mBuffer; + WId mWindowId; + bool mWaitingForFrameSync; + QWaitCondition mFrameSyncWait; + +private: + static void frameCallback(struct wl_surface *surface, void *data, uint32_t time); + + +}; + + +#endif // QWAYLANDWINDOW_H diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro new file mode 100644 index 0000000..fd6ffc0 --- /dev/null +++ b/src/plugins/platforms/wayland/wayland.pro @@ -0,0 +1,56 @@ +TARGET = qwayland +load(qt_plugin) + +CONFIG += qpa/genericunixfontdatabase + +DESTDIR = $$QT.gui.plugins/platforms + +DEFINES += Q_PLATFORM_WAYLAND +DEFINES += $$QMAKE_DEFINES_WAYLAND + +mac { + DEFINES += QT_NO_WAYLAND_XKB +} + +QT += core-private gui-private opengl-private platformsupport-private + +SOURCES = main.cpp \ + qwaylandintegration.cpp \ + qwaylandnativeinterface.cpp \ + qwaylandshmbackingstore.cpp \ + qwaylandinputdevice.cpp \ + qwaylandcursor.cpp \ + qwaylanddisplay.cpp \ + qwaylandwindow.cpp \ + qwaylandscreen.cpp \ + qwaylandshmwindow.cpp \ + qwaylandclipboard.cpp \ + qwaylanddnd.cpp \ + qwaylandmime.cpp + +HEADERS = qwaylandintegration.h \ + qwaylandnativeinterface.h \ + qwaylandcursor.h \ + qwaylanddisplay.h \ + qwaylandwindow.h \ + qwaylandscreen.h \ + qwaylandshmbackingstore.h \ + qwaylandbuffer.h \ + qwaylandshmwindow.h \ + qwaylandclipboard.h \ + qwaylanddnd.h \ + qwaylandmime.h + +INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND +LIBS += $$QMAKE_LIBS_WAYLAND +mac { + LIBS += -lwayland-client +} + +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND + +target.path += $$[QT_INSTALL_PLUGINS]/platforms +INSTALLS += target + +include ($$PWD/gl_integration/gl_integration.pri) +include ($$PWD/windowmanager_integration/windowmanager_integration.pri) diff --git a/src/plugins/platforms/wayland/wayland_sha1.txt b/src/plugins/platforms/wayland/wayland_sha1.txt new file mode 100644 index 0000000..9596f7b --- /dev/null +++ b/src/plugins/platforms/wayland/wayland_sha1.txt @@ -0,0 +1,3 @@ +This version of the Qt Wayland plugin is checked against the following sha1 +from the Wayland repository: +aa7bbb210b7121b9314993228960240358e9b123 diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp new file mode 100644 index 0000000..7d68571 --- /dev/null +++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp @@ -0,0 +1,263 @@ +/**************************************************************************** +** +** 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 "qwaylandwindowmanagerintegration.h" +#include "wayland-windowmanager-client-protocol.h" +#include "qwaylandwindow.h" + +#include <stdint.h> +#include <QtCore/QEvent> +#include <QtCore/QHash> +#include <QtGui/QPlatformNativeInterface> +#include <QtGui/QPlatformWindow> +#include <QtGui/QtEvents> +#include <QtGui/QGuiApplication> + +#include <QDebug> + +class QWaylandWindowManagerIntegrationPrivate { +public: + QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay); + bool m_blockPropertyUpdates; + QWaylandDisplay *m_waylandDisplay; + struct wl_windowmanager *m_waylandWindowManager; + QHash<QWaylandWindow*,QVariantMap> m_queuedProperties; + +}; + +QWaylandWindowManagerIntegrationPrivate::QWaylandWindowManagerIntegrationPrivate(QWaylandDisplay *waylandDisplay) + : m_blockPropertyUpdates(false) + , m_waylandDisplay(waylandDisplay) + , m_waylandWindowManager(0) +{ + +} + +QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::m_instance = 0; + +const struct wl_windowmanager_listener QWaylandWindowManagerIntegration::m_windowManagerListener = { + QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange, + QWaylandWindowManagerIntegration::wlHandleScreenOrientationChange, + QWaylandWindowManagerIntegration::wlHandleWindowPropertyChange +}; + +QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::createIntegration(QWaylandDisplay *waylandDisplay) +{ + return new QWaylandWindowManagerIntegration(waylandDisplay); +} + +QWaylandWindowManagerIntegration::QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay) + : d_ptr(new QWaylandWindowManagerIntegrationPrivate(waylandDisplay)) +{ + m_instance = this; + + wl_display_add_global_listener(d_ptr->m_waylandDisplay->wl_display(), + QWaylandWindowManagerIntegration::wlHandleListenerGlobal, + this); +} + +QWaylandWindowManagerIntegration::~QWaylandWindowManagerIntegration() +{ + +} + +QWaylandWindowManagerIntegration *QWaylandWindowManagerIntegration::instance() +{ + return m_instance; +} + +struct wl_windowmanager *QWaylandWindowManagerIntegration::windowManager() const +{ + Q_D(const QWaylandWindowManagerIntegration); + return d->m_waylandWindowManager; +} + +void QWaylandWindowManagerIntegration::wlHandleListenerGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data) +{ + Q_UNUSED(version); + if (strcmp(interface, "wl_windowmanager") == 0) { + QWaylandWindowManagerIntegration *integration = static_cast<QWaylandWindowManagerIntegration *>(data); + integration->d_ptr->m_waylandWindowManager = wl_windowmanager_create(display, id, 1); + wl_windowmanager *windowManager = integration->d_ptr->m_waylandWindowManager; + wl_windowmanager_add_listener(windowManager, &m_windowManagerListener, integration); + } +} + +void QWaylandWindowManagerIntegration::mapClientToProcess(long long processId) +{ + Q_D(QWaylandWindowManagerIntegration); + if (d->m_waylandWindowManager) + wl_windowmanager_map_client_to_process(d->m_waylandWindowManager, (uint32_t) processId); +} + +void QWaylandWindowManagerIntegration::authenticateWithToken(const QByteArray &token) +{ + Q_D(QWaylandWindowManagerIntegration); + QByteArray authToken = token; + if (authToken.isEmpty()) + authToken = qgetenv("WL_AUTHENTICATION_TOKEN"); + + if (d->m_waylandWindowManager && !authToken.isEmpty()) { + wl_windowmanager_authenticate_with_token(d->m_waylandWindowManager, authToken.constData()); + } +} + +static wl_array writePropertyValue(const QVariant &value) +{ + QByteArray byteValue; + QDataStream ds(&byteValue, QIODevice::WriteOnly); + ds << value; + + wl_array data; + data.size = byteValue.size(); + data.data = (void*)byteValue.constData(); + data.alloc = 0; + + return data; +} + +void QWaylandWindowManagerIntegration::setWindowProperty(QWaylandWindow *window, const QString &propertyName, const QVariant &propertyValue) +{ + Q_D(QWaylandWindowManagerIntegration); + if (d->m_blockPropertyUpdates) + return; + + if (window->wl_surface()) { + wl_array data = writePropertyValue(propertyValue); + wl_windowmanager_update_generic_property(d->m_waylandWindowManager, window->wl_surface(), + propertyName.toLatin1().constData(), + &data); + } else { + QVariantMap props = d->m_queuedProperties.value(window); + props.insert(propertyName, propertyValue); + d->m_queuedProperties.insert(window, props); + // ### TODO we'll need to add listening to destroyed() of QWindow that owns QWaylandWindow + // once refactor changes are in, and connect to removeQueuedPropertiesForWindow(). + } +} + +void QWaylandWindowManagerIntegration::flushPropertyChanges(QWaylandWindow *windowToFlush) +{ + // write all changes we got while we did not have a surface. + // this can happen during startup, for example, or while the window is hidden. + Q_D(QWaylandWindowManagerIntegration); + + if (!windowToFlush) + return; + + QVariantMap properties = d->m_queuedProperties.value(windowToFlush); + wl_surface *surface = windowToFlush->wl_surface(); + + QMapIterator<QString, QVariant> pIt(properties); + while (pIt.hasNext()) { + pIt.next(); + wl_array data = writePropertyValue(pIt.value()); + wl_windowmanager_update_generic_property(d->m_waylandWindowManager, surface, pIt.key().toLatin1().constData(), &data); + } + + d->m_queuedProperties.clear(); +} + +void QWaylandWindowManagerIntegration::removeQueuedPropertiesForWindow() +{ + // TODO enable this later once refactor changes are in. +// Q_D(QWaylandWindowManagerIntegration); +// QWaylandWindow *window = 0; +// d->m_queuedProperties.remove(window); +} + +void QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible) +{ + Q_UNUSED(data); + Q_UNUSED(wl_windowmanager); + QEvent evt(visible != 0 ? QEvent::ApplicationActivate : QEvent::ApplicationDeactivate); + QCoreApplication::sendEvent(QCoreApplication::instance(), &evt); +} + +void QWaylandWindowManagerIntegration::wlHandleScreenOrientationChange(void *data, struct wl_windowmanager *wl_windowmanager, int screenOrientation) +{ + Q_UNUSED(data); + Q_UNUSED(wl_windowmanager); + QScreenOrientationChangeEvent event(screenOrientation); + QCoreApplication::sendEvent(QCoreApplication::instance(), &event); +} + +void QWaylandWindowManagerIntegration::wlHandleWindowPropertyChange(void *data, struct wl_windowmanager *wl_windowmanager, + struct wl_surface *surface, + const char *propertyName, struct wl_array *propertyValue) +{ + // window manager changes a window property + Q_UNUSED(data); + Q_UNUSED(wl_windowmanager); + + QVariant variantValue; + QByteArray baValue = QByteArray((const char*)propertyValue->data, propertyValue->size); + QDataStream ds(&baValue, QIODevice::ReadOnly); + ds >> variantValue; + + QPlatformNativeInterface *nativeInterface = qApp->platformNativeInterface(); + QWaylandWindowManagerIntegration *inst = QWaylandWindowManagerIntegration::instance(); + + QList<QWindow *> windows = qApp->topLevelWindows(); + foreach (QWindow *window, windows) { + QPlatformWindow *platformWindowForWindow = window->handle(); + if (!platformWindowForWindow) + continue; + QWaylandWindow *waylandWindow = static_cast<QWaylandWindow*>(platformWindowForWindow); + wl_surface *windowSurface = (wl_surface*)nativeInterface->nativeResourceForWindow(QByteArray("surface"), window); + if (windowSurface == surface) { + inst->handleWindowPropertyChange(waylandWindow, QString(propertyName), variantValue); + break; + } + } +} + +void QWaylandWindowManagerIntegration::handleWindowPropertyChange(QWaylandWindow *window, + const QString &propertyName, const QVariant &propertyValue) +{ + Q_D(QWaylandWindowManagerIntegration); + d->m_blockPropertyUpdates = true; + + QPlatformNativeInterface *nativeInterface = qApp->platformNativeInterface(); + nativeInterface->setWindowProperty(window, propertyName, propertyValue); + + d->m_blockPropertyUpdates = false; +} diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.h b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.h new file mode 100644 index 0000000..1372fb8 --- /dev/null +++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** 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 QWAYLANDWINDOWMANAGERINTEGRATION_H +#define QWAYLANDWINDOWMANAGERINTEGRATION_H + +#include <QtCore/QObject> +#include <QtCore/QScopedPointer> + +#include "wayland-client.h" +#include "qwaylanddisplay.h" + +class QWaylandWindow; + +class QWaylandWindowManagerIntegrationPrivate; + +class QWaylandWindowManagerIntegration : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandWindowManagerIntegration) +public: + explicit QWaylandWindowManagerIntegration(QWaylandDisplay *waylandDisplay); + virtual ~QWaylandWindowManagerIntegration(); + static QWaylandWindowManagerIntegration *createIntegration(QWaylandDisplay *waylandDisplay); + struct wl_windowmanager *windowManager() const; + + static QWaylandWindowManagerIntegration *instance(); + + void mapSurfaceToProcess(struct wl_surface *surface, long long processId); + void mapClientToProcess(long long processId); + void authenticateWithToken(const QByteArray &token = QByteArray()); + void setWindowProperty(QWaylandWindow *window, const QString &propertyName, const QVariant &propertyValue); + + void flushPropertyChanges(QWaylandWindow *windowToFlush); + +private slots: + void removeQueuedPropertiesForWindow(); + +private: + static void wlHandleListenerGlobal(wl_display *display, uint32_t id, + const char *interface, uint32_t version, void *data); + + static void wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible); + static void wlHandleScreenOrientationChange(void *data, struct wl_windowmanager *wl_windowmanager, int screenOrientation); + static void wlHandleWindowPropertyChange(void *data, struct wl_windowmanager *wl_windowmanager, + struct wl_surface *surface, + const char *propertyName, struct wl_array *propertyValue); + + void handleWindowPropertyChange(QWaylandWindow *window, const QString &propertyName, const QVariant &propertyValue); + +private: + QScopedPointer<QWaylandWindowManagerIntegrationPrivate> d_ptr; + static QWaylandWindowManagerIntegration *m_instance; + + static const struct wl_windowmanager_listener m_windowManagerListener; +}; + +#endif // QWAYLANDWINDOWMANAGERINTEGRATION_H diff --git a/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-client-protocol.h b/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-client-protocol.h new file mode 100644 index 0000000..034c08f --- /dev/null +++ b/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-client-protocol.h @@ -0,0 +1,96 @@ +#ifndef WAYLAND_WINDOWMANAGER_CLIENT_PROTOCOL_H +#define WAYLAND_WINDOWMANAGER_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <stddef.h> +#include "wayland-util.h" + +struct wl_client; + +struct wl_windowmanager; + +extern const struct wl_interface wl_windowmanager_interface; + +struct wl_windowmanager_listener { + void (*client_onscreen_visibility)(void *data, + struct wl_windowmanager *wl_windowmanager, + int32_t visible); + void (*set_screen_rotation)(void *data, + struct wl_windowmanager *wl_windowmanager, + int32_t rotation); + void (*set_generic_property)(void *data, + struct wl_windowmanager *wl_windowmanager, + struct wl_surface *surface, + const char *name, + struct wl_array *value); +}; + +static inline int +wl_windowmanager_add_listener(struct wl_windowmanager *wl_windowmanager, + const struct wl_windowmanager_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *) wl_windowmanager, + (void (**)(void)) listener, data); +} + +#define WL_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS 0 +#define WL_WINDOWMANAGER_AUTHENTICATE_WITH_TOKEN 1 +#define WL_WINDOWMANAGER_UPDATE_GENERIC_PROPERTY 2 + +static inline struct wl_windowmanager * +wl_windowmanager_create(struct wl_display *display, uint32_t id, uint32_t version) +{ + wl_display_bind(display, id, "wl_windowmanager", version); + + return (struct wl_windowmanager *) + wl_proxy_create_for_id(display, &wl_windowmanager_interface, id); +} + +static inline void +wl_windowmanager_set_user_data(struct wl_windowmanager *wl_windowmanager, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *) wl_windowmanager, user_data); +} + +static inline void * +wl_windowmanager_get_user_data(struct wl_windowmanager *wl_windowmanager) +{ + return wl_proxy_get_user_data((struct wl_proxy *) wl_windowmanager); +} + +static inline void +wl_windowmanager_destroy(struct wl_windowmanager *wl_windowmanager) +{ + wl_proxy_destroy((struct wl_proxy *) wl_windowmanager); +} + +static inline void +wl_windowmanager_map_client_to_process(struct wl_windowmanager *wl_windowmanager, uint32_t processid) +{ + wl_proxy_marshal((struct wl_proxy *) wl_windowmanager, + WL_WINDOWMANAGER_MAP_CLIENT_TO_PROCESS, processid); +} + +static inline void +wl_windowmanager_authenticate_with_token(struct wl_windowmanager *wl_windowmanager, const char *processid) +{ + wl_proxy_marshal((struct wl_proxy *) wl_windowmanager, + WL_WINDOWMANAGER_AUTHENTICATE_WITH_TOKEN, processid); +} + +static inline void +wl_windowmanager_update_generic_property(struct wl_windowmanager *wl_windowmanager, struct wl_surface *surface, const char *name, struct wl_array *value) +{ + wl_proxy_marshal((struct wl_proxy *) wl_windowmanager, + WL_WINDOWMANAGER_UPDATE_GENERIC_PROPERTY, surface, name, value); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-protocol.c b/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-protocol.c new file mode 100644 index 0000000..1d231f5 --- /dev/null +++ b/src/plugins/platforms/wayland/windowmanager_integration/wayland-windowmanager-protocol.c @@ -0,0 +1,34 @@ +#include <stdlib.h> +#include <stdint.h> +#include "wayland-util.h" + +extern const struct wl_interface wl_surface_interface; + +static const struct wl_interface *types[] = { + NULL, + &wl_surface_interface, + NULL, + NULL, + &wl_surface_interface, + NULL, + NULL, +}; + +static const struct wl_message wl_windowmanager_requests[] = { + { "map_client_to_process", "u", types + 0 }, + { "authenticate_with_token", "s", types + 0 }, + { "update_generic_property", "osa", types + 1 }, +}; + +static const struct wl_message wl_windowmanager_events[] = { + { "client_onscreen_visibility", "i", types + 0 }, + { "set_screen_rotation", "i", types + 0 }, + { "set_generic_property", "osa", types + 4 }, +}; + +WL_EXPORT const struct wl_interface wl_windowmanager_interface = { + "wl_windowmanager", 1, + ARRAY_LENGTH(wl_windowmanager_requests), wl_windowmanager_requests, + ARRAY_LENGTH(wl_windowmanager_events), wl_windowmanager_events, +}; + diff --git a/src/plugins/platforms/wayland/windowmanager_integration/windowmanager_integration.pri b/src/plugins/platforms/wayland/windowmanager_integration/windowmanager_integration.pri new file mode 100644 index 0000000..45118b5 --- /dev/null +++ b/src/plugins/platforms/wayland/windowmanager_integration/windowmanager_integration.pri @@ -0,0 +1,16 @@ +DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT + +contains(DEFINES, QT_WAYLAND_WINDOWMANAGER_SUPPORT) { + + HEADERS += \ + $$PWD/wayland-windowmanager-client-protocol.h \ + $$PWD/qwaylandwindowmanagerintegration.h + + SOURCES += \ + $$PWD/qwaylandwindowmanagerintegration.cpp \ + $$PWD/wayland-windowmanager-protocol.c + +} + + + |