diff options
Diffstat (limited to 'src/compositor')
178 files changed, 16111 insertions, 11583 deletions
diff --git a/src/compositor/compositor.pro b/src/compositor/compositor.pro index 710fa2dcd..fe58df7ec 100644 --- a/src/compositor/compositor.pro +++ b/src/compositor/compositor.pro @@ -1,12 +1,17 @@ -TARGET = QtCompositor +TARGET = QtWaylandCompositor +MODULE = waylandcompositor + QT = core gui-private +qtHaveModule(quick): QT += quick + contains(QT_CONFIG, opengl):MODULE_DEFINES = QT_COMPOSITOR_WAYLAND_GL CONFIG -= precompile_header CONFIG += link_pkgconfig DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT +QMAKE_DOCS = $$PWD/doc/qtwaylandcompositor.qdocconf !contains(QT_CONFIG, no-pkg-config) { PKGCONFIG_PRIVATE += wayland-server @@ -15,14 +20,21 @@ DEFINES += QT_WAYLAND_WINDOWMANAGER_SUPPORT } INCLUDEPATH += ../shared -HEADERS += ../shared/qwaylandmimehelper.h -SOURCES += ../shared/qwaylandmimehelper.cpp + +HEADERS += ../shared/qwaylandmimehelper_p.h \ + ../shared/qwaylandinputmethodeventbuilder_p.h \ + ../shared/qwaylandshmformathelper_p.h + +SOURCES += ../shared/qwaylandmimehelper.cpp \ + ../shared/qwaylandinputmethodeventbuilder.cpp + +RESOURCES += compositor.qrc include ($$PWD/global/global.pri) include ($$PWD/wayland_wrapper/wayland_wrapper.pri) include ($$PWD/hardware_integration/hardware_integration.pri) include ($$PWD/compositor_api/compositor_api.pri) -include ($$PWD/windowmanagerprotocol/windowmanagerprotocol.pri) +include ($$PWD/extensions/extensions.pri) MODULE_PLUGIN_TYPES = \ wayland-graphics-integration-server diff --git a/src/compositor/compositor.qrc b/src/compositor/compositor.qrc new file mode 100644 index 000000000..5dc7a70a5 --- /dev/null +++ b/src/compositor/compositor.qrc @@ -0,0 +1,11 @@ +<RCC> + <qresource prefix="/qt-project.org/wayland/compositor"> + <file>shaders/surface.vert</file> + <file>shaders/surface_oes_external.frag</file> + <file>shaders/surface_rgba.frag</file> + <file>shaders/surface_rgbx.frag</file> + <file>shaders/surface_y_u_v.frag</file> + <file>shaders/surface_y_uv.frag</file> + <file>shaders/surface_y_xuxv.frag</file> + </qresource> +</RCC> diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index ac356b8fa..1724ec965 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -2,30 +2,46 @@ INCLUDEPATH += compositor_api HEADERS += \ compositor_api/qwaylandcompositor.h \ + compositor_api/qwaylandcompositor_p.h \ compositor_api/qwaylandclient.h \ compositor_api/qwaylandsurface.h \ compositor_api/qwaylandsurface_p.h \ compositor_api/qwaylandinput.h \ - compositor_api/qwaylandinputpanel.h \ + compositor_api/qwaylandinput_p.h \ + compositor_api/qwaylandkeyboard.h \ + compositor_api/qwaylandkeyboard_p.h \ + compositor_api/qwaylandpointer.h \ + compositor_api/qwaylandpointer_p.h \ + compositor_api/qwaylandtouch.h \ + compositor_api/qwaylandtouch_p.h \ compositor_api/qwaylandoutput.h \ compositor_api/qwaylanddrag.h \ compositor_api/qwaylandbufferref.h \ - compositor_api/qwaylandsurfaceview.h \ - compositor_api/qwaylandglobalinterface.h \ - compositor_api/qwaylandsurfaceinterface.h + compositor_api/qwaylanddestroylistener.h \ + compositor_api/qwaylanddestroylistener_p.h \ + compositor_api/qwaylandview.h \ + compositor_api/qwaylandview_p.h \ + compositor_api/qwaylandresource.h \ + compositor_api/qwaylandsurfacegrabber.h \ + compositor_api/qwaylandinputmethodcontrol.h \ + compositor_api/qwaylandinputmethodcontrol_p.h SOURCES += \ compositor_api/qwaylandcompositor.cpp \ compositor_api/qwaylandclient.cpp \ compositor_api/qwaylandsurface.cpp \ compositor_api/qwaylandinput.cpp \ - compositor_api/qwaylandinputpanel.cpp \ + compositor_api/qwaylandkeyboard.cpp \ + compositor_api/qwaylandpointer.cpp \ + compositor_api/qwaylandtouch.cpp \ compositor_api/qwaylandoutput.cpp \ compositor_api/qwaylanddrag.cpp \ compositor_api/qwaylandbufferref.cpp \ - compositor_api/qwaylandsurfaceview.cpp \ - compositor_api/qwaylandglobalinterface.cpp \ - compositor_api/qwaylandsurfaceinterface.cpp + compositor_api/qwaylanddestroylistener.cpp \ + compositor_api/qwaylandview.cpp \ + compositor_api/qwaylandresource.cpp \ + compositor_api/qwaylandsurfacegrabber.cpp \ + compositor_api/qwaylandinputmethodcontrol.cpp QT += core-private @@ -34,13 +50,14 @@ qtHaveModule(quick) { compositor_api/qwaylandquickcompositor.cpp \ compositor_api/qwaylandquicksurface.cpp \ compositor_api/qwaylandquickoutput.cpp \ - compositor_api/qwaylandsurfaceitem.cpp + compositor_api/qwaylandquickitem.cpp HEADERS += \ compositor_api/qwaylandquickcompositor.h \ compositor_api/qwaylandquicksurface.h \ compositor_api/qwaylandquickoutput.h \ - compositor_api/qwaylandsurfaceitem.h + compositor_api/qwaylandquickitem.h \ + compositor_api/qwaylandquickitem_p.h - QT += qml quick + QT += qml qml-private quick quick-private } diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp index 894f50a1c..e9fbcfbdb 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.cpp +++ b/src/compositor/compositor_api/qwaylandbufferref.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -43,14 +46,34 @@ class QWaylandBufferRefPrivate { public: QtWayland::SurfaceBuffer *buffer; + + bool nullOrDestroyed() { + return !buffer || buffer->isDestroyed(); + } }; +/*! + * \class QWaylandBufferRef + * \inmodule QtWaylandCompositor + * \preliminary + * \brief A class which holds a reference to a surface buffer + * + * This class can be used to reference a surface buffer. As long as a reference + * to the buffer exists, it is owned by the compositor and the client cannot modify it. + */ + +/*! + * Constructs a null buffer ref. + */ QWaylandBufferRef::QWaylandBufferRef() : d(new QWaylandBufferRefPrivate) { d->buffer = 0; } +/*! + * Constructs a reference to \a buffer. + */ QWaylandBufferRef::QWaylandBufferRef(QtWayland::SurfaceBuffer *buffer) : d(new QWaylandBufferRefPrivate) { @@ -59,13 +82,20 @@ QWaylandBufferRef::QWaylandBufferRef(QtWayland::SurfaceBuffer *buffer) buffer->ref(); } +/*! + * Creates a new reference to the buffer referenced by \a ref. + */ QWaylandBufferRef::QWaylandBufferRef(const QWaylandBufferRef &ref) : d(new QWaylandBufferRefPrivate) { - d->buffer = 0; - *this = ref; + d->buffer = ref.d->buffer; + if (d->buffer) + d->buffer->ref(); } +/*! + * Dereferences the buffer. + */ QWaylandBufferRef::~QWaylandBufferRef() { if (d->buffer) @@ -73,6 +103,10 @@ QWaylandBufferRef::~QWaylandBufferRef() delete d; } +/*! + * Assigns \a ref to this buffer. The previously referenced buffer is + * dereferenced and the new one gets a new reference. + */ QWaylandBufferRef &QWaylandBufferRef::operator=(const QWaylandBufferRef &ref) { if (d->buffer) @@ -85,56 +119,158 @@ QWaylandBufferRef &QWaylandBufferRef::operator=(const QWaylandBufferRef &ref) return *this; } -QWaylandBufferRef::operator bool() const +/*! + * Returns true if this QWaylandBufferRef references the same buffer as \a ref. + * Otherwise returns false. + */ +bool QWaylandBufferRef::operator==(const QWaylandBufferRef &ref) { - return d->buffer && d->buffer->waylandBufferHandle(); + return d->buffer == ref.d->buffer; } -bool QWaylandBufferRef::isShm() const +/*! + * Returns false if this QWaylandBufferRef references the same buffer as \a ref. + * Otherwise returns true. + */ +bool QWaylandBufferRef::operator!=(const QWaylandBufferRef &ref) { - return d->buffer->isShmBuffer(); + return d->buffer != ref.d->buffer; } -QImage QWaylandBufferRef::image() const +/*! + * Returns true if this QWaylandBufferRef does not reference a buffer. + * Otherwise returns false. + * + * \sa hasBuffer() + */ +bool QWaylandBufferRef::isNull() const { - if (d->buffer->isShmBuffer()) - return d->buffer->image(); - return QImage(); + return !d->buffer; } -#ifdef QT_COMPOSITOR_WAYLAND_GL +/*! + * Returns true if this QWaylandBufferRef references a buffer. Otherwise returns false. + * + * \sa isNull() + */ +bool QWaylandBufferRef::hasBuffer() const +{ + return d->buffer; +} -GLenum QWaylandBufferRef::textureTarget() const +/*! + * Returns true if this QWaylandBufferRef references a buffer that + * has been destroyed. Otherwise returns false. + */ +bool QWaylandBufferRef::isDestroyed() const { - Q_ASSERT(d->buffer->textureCreated()); - return d->buffer->textureTarget(); + return d->buffer && d->buffer->isDestroyed(); } -GLuint QWaylandBufferRef::createTexture() +/*! + * Returns the Wayland resource for the buffer. + */ +struct ::wl_resource *QWaylandBufferRef::wl_buffer() const { - if (!d->buffer->isShmBuffer() && !d->buffer->textureCreated()) { - d->buffer->createTexture(); - } - return d->buffer->texture(); + return d->buffer ? d->buffer->waylandBufferHandle() : Q_NULLPTR; } -void QWaylandBufferRef::updateTexture() +/*! + * Returns the size of the buffer. + * If the buffer referenced is null, an invalid QSize() is returned. + */ +QSize QWaylandBufferRef::size() const { - if (!d->buffer->isShmBuffer() && d->buffer->textureCreated()) - d->buffer->updateTexture(); + if (d->nullOrDestroyed()) + return QSize(); + + return d->buffer->size(); } -void QWaylandBufferRef::destroyTexture() +/*! + * Returns the origin of the buffer. + * If the buffer referenced is null, QWaylandSurface::OriginBottomLeft + * is returned. + */ +QWaylandSurface::Origin QWaylandBufferRef::origin() const { - if (!d->buffer->isShmBuffer() && d->buffer->textureCreated()) { - d->buffer->destroyTexture(); - } + if (d->buffer) + return d->buffer->origin(); + + return QWaylandSurface::OriginBottomLeft; +} + +QWaylandBufferRef::BufferType QWaylandBufferRef::bufferType() const +{ + if (d->nullOrDestroyed()) + return BufferType_Null; + + if (isShm()) + return BufferType_Shm; + + return BufferType_Egl; } -void *QWaylandBufferRef::nativeBuffer() const +QWaylandBufferRef::BufferFormatEgl QWaylandBufferRef::bufferFormatEgl() const { - return d->buffer->handle(); + if (d->nullOrDestroyed()) + return BufferFormatEgl_Null; + + return d->buffer->bufferFormatEgl(); +} + +/*! + * Returns true if the buffer is a shared memory buffer. Otherwise returns false. + */ +bool QWaylandBufferRef::isShm() const +{ + if (d->nullOrDestroyed()) + return false; + + return d->buffer->isShm(); +} + +/*! + * Returns an image with the contents of the buffer. + */ +QImage QWaylandBufferRef::image() const +{ + if (d->nullOrDestroyed()) + return QImage(); + + return d->buffer->image(); +} + +#ifdef QT_COMPOSITOR_WAYLAND_GL +GLuint QWaylandBufferRef::textureForPlane(int plane) const +{ + if (d->nullOrDestroyed()) + return 0; + + return d->buffer->textureForPlane(plane); } #endif +/*! + * Binds the buffer to the current OpenGL texture. This may + * perform a copy of the buffer data, depending on the platform + * and the type of the buffer. + */ +void QWaylandBufferRef::bindToTexture() const +{ + if (d->nullOrDestroyed()) + return; + + return d->buffer->bindToTexture(); + +} + +void QWaylandBufferRef::updateTexture() const +{ + if (d->nullOrDestroyed() || d->buffer->isShm()) + return; + + d->buffer->updateTexture(); +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h index 0a5f6cd85..50c85b965 100644 --- a/src/compositor/compositor_api/qwaylandbufferref.h +++ b/src/compositor/compositor_api/qwaylandbufferref.h @@ -3,9 +3,9 @@ ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -40,7 +43,10 @@ #include <QtGui/qopengl.h> #endif -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/QWaylandSurface> +#include <QtWaylandCompositor/qwaylandexport.h> + +struct wl_resource; QT_BEGIN_NAMESPACE @@ -49,7 +55,7 @@ namespace QtWayland class SurfaceBuffer; } -class Q_COMPOSITOR_EXPORT QWaylandBufferRef +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandBufferRef { public: QWaylandBufferRef(); @@ -58,23 +64,45 @@ public: ~QWaylandBufferRef(); QWaylandBufferRef &operator=(const QWaylandBufferRef &ref); - operator bool() const; - bool isShm() const; + bool isNull() const; + bool hasBuffer() const; + bool isDestroyed() const; + bool operator==(const QWaylandBufferRef &ref); + bool operator!=(const QWaylandBufferRef &ref); + + struct wl_resource *wl_buffer() const; + + QSize size() const; + QWaylandSurface::Origin origin() const; + + enum BufferType { + BufferType_Null, + BufferType_Shm, + BufferType_Egl + }; + enum BufferFormatEgl { + BufferFormatEgl_Null, + BufferFormatEgl_RGB, + BufferFormatEgl_RGBA, + BufferFormatEgl_EXTERNAL_OES, + BufferFormatEgl_Y_U_V, + BufferFormatEgl_Y_UV, + BufferFormatEgl_Y_XUXV + }; + + BufferType bufferType() const; + BufferFormatEgl bufferFormatEgl() const; + + bool isShm() const; QImage image() const; #ifdef QT_COMPOSITOR_WAYLAND_GL - /** - * There must be a GL context bound when calling this function. - * The texture will be automatically destroyed when the last QWaylandBufferRef - * referring to the same underlying buffer will be destroyed or reset. - */ - GLuint createTexture(); - GLenum textureTarget() const; - void updateTexture(); - void destroyTexture(); - void *nativeBuffer() const; + GLuint textureForPlane(int plane) const; #endif + void bindToTexture() const; + void updateTexture() const; + private: class QWaylandBufferRefPrivate *const d; friend class QWaylandBufferRefPrivate; diff --git a/src/compositor/compositor_api/qwaylandclient.cpp b/src/compositor/compositor_api/qwaylandclient.cpp index 216abc4f8..d2da470a4 100644 --- a/src/compositor/compositor_api/qwaylandclient.cpp +++ b/src/compositor/compositor_api/qwaylandclient.cpp @@ -3,46 +3,43 @@ ** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <private/qobject_p.h> - -#include "wayland_wrapper/qwlcompositor_p.h" -#include "qwaylandcompositor.h" #include "qwaylandclient.h" +#include <QtCore/private/qobject_p.h> + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/private/qwaylandcompositor_p.h> + #include <wayland-server.h> #include <wayland-util.h> @@ -52,8 +49,9 @@ QT_BEGIN_NAMESPACE class QWaylandClientPrivate : public QObjectPrivate { public: - QWaylandClientPrivate(wl_client *_client) - : client(_client) + QWaylandClientPrivate(QWaylandCompositor *compositor, wl_client *_client) + : compositor(compositor) + , client(_client) { // Save client credentials wl_client_get_credentials(client, &pid, &uid, &gid); @@ -69,10 +67,10 @@ public: QWaylandClient *client = reinterpret_cast<Listener *>(listener)->parent; Q_ASSERT(client != 0); - QtWayland::Compositor::instance()->m_clients.removeOne(client); delete client; } + QWaylandCompositor *compositor; wl_client *client; uid_t uid; @@ -86,8 +84,31 @@ public: Listener listener; }; -QWaylandClient::QWaylandClient(wl_client *client) - : QObject(*new QWaylandClientPrivate(client)) +/*! + * \qmltype WaylandClient + * \inqmlmodule QtWayland.Compositor + * \preliminary + * \brief A client connecting to the WaylandCompositor. + * + * This type represents a client connecting to the compositor using the Wayland protocol. + * It corresponds to the Wayland interface wl_client. + */ + +/*! + * \class QWaylandClient + * \inmodule QtWaylandCompositor + * \preliminary + * \brief A client connecting to the QWaylandCompositor. + * + * This class corresponds to a client connecting to the compositor using the Wayland protocol. + * It corresponds to the Wayland interface wl_client. + */ + +/*! + * Constructs a QWaylandClient for the \a compositor and the Wayland \a client. + */ +QWaylandClient::QWaylandClient(QWaylandCompositor *compositor, wl_client *client) + : QObject(*new QWaylandClientPrivate(compositor, client)) { Q_D(QWaylandClient); @@ -95,17 +116,29 @@ QWaylandClient::QWaylandClient(wl_client *client) d->listener.parent = this; d->listener.listener.notify = QWaylandClientPrivate::client_destroy_callback; wl_client_add_destroy_listener(client, &d->listener.listener); + + QWaylandCompositorPrivate::get(compositor)->addClient(this); } +/*! + * Destroys the QWaylandClient. + */ QWaylandClient::~QWaylandClient() { Q_D(QWaylandClient); // Remove listener from signal wl_list_remove(&d->listener.listener.link); + + QWaylandCompositorPrivate::get(d->compositor)->removeClient(this); } -QWaylandClient *QWaylandClient::fromWlClient(wl_client *wlClient) +/*! + * Returns the QWaylandClient corresponding to the Wayland client \a wl_client and \a compositor. + * If a QWaylandClient has not already been created for \a client, it is + * created and returned. + */ +QWaylandClient *QWaylandClient::fromWlClient(QWaylandCompositor *compositor, wl_client *wlClient) { if (!wlClient) return 0; @@ -124,13 +157,15 @@ QWaylandClient *QWaylandClient::fromWlClient(wl_client *wlClient) // bind several times resulting in multiple QWaylandClient // instances for the same wl_client therefore we create it from // here on demand - client = new QWaylandClient(wlClient); - QtWayland::Compositor::instance()->m_clients.append(client); + client = new QWaylandClient(compositor, wlClient); } return client; } +/*! + * Returns the Wayland client of this QWaylandClient. + */ wl_client *QWaylandClient::client() const { Q_D(const QWaylandClient); @@ -138,6 +173,17 @@ wl_client *QWaylandClient::client() const return d->client; } +/*! + * \qmlproperty int QtWaylandCompositor::WaylandClient::userId + * + * This property holds the user id of this WaylandClient. + */ + +/*! + * \property QWaylandClient::userId + * + * This property holds the user id of this QWaylandClient. + */ qint64 QWaylandClient::userId() const { Q_D(const QWaylandClient); @@ -145,6 +191,17 @@ qint64 QWaylandClient::userId() const return d->uid; } +/*! + * \qmlproperty int QtWaylandCompositor::WaylandClient::groupId + * + * This property holds the group id of this WaylandClient. + */ + +/*! + * \property int QWaylandClient::groupId + * + * This property holds the group id of this QWaylandClient. + */ qint64 QWaylandClient::groupId() const { Q_D(const QWaylandClient); @@ -152,6 +209,17 @@ qint64 QWaylandClient::groupId() const return d->gid; } +/*! + * \qmlproperty int QtWaylandCompositor::WaylandClient::processId + * + * This property holds the process id of this WaylandClient. + */ + +/*! + * \property QWaylandClient::processId + * + * This property holds the process id of this QWaylandClient. + */ qint64 QWaylandClient::processId() const { Q_D(const QWaylandClient); @@ -159,16 +227,35 @@ qint64 QWaylandClient::processId() const return d->pid; } -void QWaylandClient::kill(int sig) +/*! + * \qmlmethod void QtWaylandCompositor::WaylandClient::kill(signal) + * + * Kills the client with the specified \a signal. + */ + +/*! + * Kills the client with the specified \a signal. + */ +void QWaylandClient::kill(int signal) { Q_D(QWaylandClient); - ::kill(d->pid, sig); + ::kill(d->pid, signal); } +/*! + * \qmlmethod void QtWaylandCompositor::WaylandClient::close() + * + * Closes the client + */ + +/*! + * Closes the client. + */ void QWaylandClient::close() { - QtWayland::Compositor::instance()->waylandCompositor()->destroyClient(this); + Q_D(QWaylandClient); + d->compositor->destroyClient(this); } QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandclient.h b/src/compositor/compositor_api/qwaylandclient.h index 9199406b3..26e7b95e5 100644 --- a/src/compositor/compositor_api/qwaylandclient.h +++ b/src/compositor/compositor_api/qwaylandclient.h @@ -3,36 +3,32 @@ ** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -41,7 +37,7 @@ #ifndef QWAYLANDCLIENT_H #define QWAYLANDCLIENT_H -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> #include <QObject> @@ -52,8 +48,9 @@ struct wl_client; QT_BEGIN_NAMESPACE class QWaylandClientPrivate; +class QWaylandCompositor; -class Q_COMPOSITOR_EXPORT QWaylandClient : public QObject +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandClient : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandClient) @@ -64,7 +61,7 @@ class Q_COMPOSITOR_EXPORT QWaylandClient : public QObject public: ~QWaylandClient(); - static QWaylandClient *fromWlClient(wl_client *wlClient); + static QWaylandClient *fromWlClient(QWaylandCompositor *compositor, wl_client *wlClient); wl_client *client() const; @@ -73,13 +70,13 @@ public: qint64 processId() const; - Q_INVOKABLE void kill(int sig = SIGTERM); + Q_INVOKABLE void kill(int signal = SIGTERM); public Q_SLOTS: void close(); private: - explicit QWaylandClient(wl_client *client); + explicit QWaylandClient(QWaylandCompositor *compositor, wl_client *client); }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 04d1c4aed..6e463e384 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -4,367 +4,875 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qwaylandcompositor.h" +#include "qwaylandcompositor_p.h" + +#include <QtWaylandCompositor/qwaylandclient.h> +#include <QtWaylandCompositor/qwaylandinput.h> +#include <QtWaylandCompositor/qwaylandoutput.h> +#include <QtWaylandCompositor/qwaylandview.h> +#include <QtWaylandCompositor/qwaylandclient.h> +#include <QtWaylandCompositor/qwaylandkeyboard.h> +#include <QtWaylandCompositor/qwaylandpointer.h> +#include <QtWaylandCompositor/qwaylandtouch.h> +#include <QtWaylandCompositor/qwaylandsurfacegrabber.h> -#include "qwaylandclient.h" -#include "qwaylandinput.h" -#include "qwaylandoutput.h" -#include "qwaylandglobalinterface.h" -#include "qwaylandsurfaceview.h" +#include <QtWaylandCompositor/private/qwaylandkeyboard_p.h> +#include <QtWaylandCompositor/private/qwaylandsurface_p.h> -#include "wayland_wrapper/qwlcompositor_p.h" #include "wayland_wrapper/qwldatadevice_p.h" -#include "wayland_wrapper/qwlsurface_p.h" -#include "wayland_wrapper/qwlinputdevice_p.h" -#include "wayland_wrapper/qwlinputpanel_p.h" -#include "wayland_wrapper/qwlshellsurface_p.h" +#include "wayland_wrapper/qwldatadevicemanager_p.h" + +#include "hardware_integration/qwlclientbufferintegration_p.h" +#include "hardware_integration/qwlclientbufferintegrationfactory_p.h" +#include "hardware_integration/qwlserverbufferintegration_p.h" +#include "hardware_integration/qwlserverbufferintegrationfactory_p.h" +#include "hardware_integration/qwlhwintegration_p.h" + +#include "extensions/qwaylandwindowmanagerextension.h" + +#include "qwaylandxkb_p.h" +#include "qwaylandshmformathelper_p.h" #include <QtCore/QCoreApplication> #include <QtCore/QStringList> +#include <QtCore/QSocketNotifier> #include <QtGui/QDesktopServices> #include <QtGui/QScreen> -#include <QDebug> +#include <QtGui/qpa/qwindowsysteminterface_p.h> +#include <QtGui/qpa/qplatformnativeinterface.h> +#include <QtGui/private/qguiapplication_p.h> + +#ifdef QT_COMPOSITOR_WAYLAND_GL +# include <QtGui/private/qopengltextureblitter_p.h> +# include <QOpenGLContext> +# include <QOpenGLFramebufferObject> +# include <QMatrix4x4> +#endif QT_BEGIN_NAMESPACE -QWaylandCompositor::QWaylandCompositor(const char *socketName, ExtensionFlags extensions) - : m_compositor(new QtWayland::Compositor(this, extensions)) +Q_LOGGING_CATEGORY(qLcCompositorInputMethods, "qt.compositor.input.methods") + +namespace QtWayland { + +class WindowSystemEventHandler : public QWindowSystemEventHandler { - m_compositor->m_socket_name = socketName; - m_compositor->init(); +public: + WindowSystemEventHandler(QWaylandCompositor *c) : compositor(c) {} + bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) Q_DECL_OVERRIDE + { + if (e->type == QWindowSystemInterfacePrivate::Key) { + QWindowSystemInterfacePrivate::KeyEvent *ke = static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e); + QWaylandKeyboardPrivate *keyb = QWaylandKeyboardPrivate::get(compositor->defaultInputDevice()->keyboard()); + + uint32_t code = ke->nativeScanCode; + bool isDown = ke->keyType == QEvent::KeyPress; + +#ifndef QT_NO_WAYLAND_XKB + QString text; + Qt::KeyboardModifiers modifiers = QWaylandXkb::modifiers(keyb->xkbState()); + + const xkb_keysym_t sym = xkb_state_key_get_one_sym(keyb->xkbState(), code); + int qtkey; + std::tie(qtkey, text) = QWaylandXkb::keysymToQtKey(sym, modifiers); + + ke->key = qtkey; + ke->modifiers = modifiers; + ke->nativeVirtualKey = sym; + ke->nativeModifiers = keyb->xkbModsMask(); + ke->unicode = text; +#endif + if (!ke->repeat) + keyb->keyEvent(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED); + + QWindowSystemEventHandler::sendEvent(e); + + if (!ke->repeat) { + keyb->updateKeymap(); + keyb->updateModifierState(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED); + } + } else { + QWindowSystemEventHandler::sendEvent(e); + } + return true; + } + + QWaylandCompositor *compositor; +}; + +} // namespace + +QWaylandCompositorPrivate::QWaylandCompositorPrivate(QWaylandCompositor *compositor) + : display(0) +#if defined (QT_COMPOSITOR_WAYLAND_GL) + , use_hw_integration_extension(true) + , client_buffer_integration(0) + , server_buffer_integration(0) +#endif + , retainSelection(false) + , initialized(false) +{ + if (QGuiApplication::platformNativeInterface()) + display = static_cast<wl_display*>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("server_wl_display")); + if (!display) + display = wl_display_create(); + eventHandler.reset(new QtWayland::WindowSystemEventHandler(compositor)); + timer.start(); + + QWindowSystemInterfacePrivate::installWindowSystemEventHandler(eventHandler.data()); } -QWaylandCompositor::QWaylandCompositor(const char *socketName, QtWayland::Compositor *dptr) - : m_compositor(dptr) +void QWaylandCompositorPrivate::init() { - m_compositor->m_socket_name = socketName; - m_compositor->init(); + Q_Q(QWaylandCompositor); + QStringList arguments = QCoreApplication::instance()->arguments(); + + if (socket_name.isEmpty()) { + const int socketArg = arguments.indexOf(QLatin1String("--wayland-socket-name")); + if (socketArg != -1 && socketArg + 1 < arguments.size()) + socket_name = arguments.at(socketArg + 1).toLocal8Bit(); + } + wl_compositor::init(display, 3); + wl_subcompositor::init(display, 1); + + data_device_manager = new QtWayland::DataDeviceManager(q); + + wl_display_init_shm(display); + QVector<wl_shm_format> formats = QWaylandShmFormatHelper::supportedWaylandFormats(); + foreach (wl_shm_format format, formats) + wl_display_add_shm_format(display, format); + + if (!socket_name.isEmpty()) { + if (wl_display_add_socket(display, socket_name.constData())) + qFatal("Fatal: Failed to open server socket\n"); + } else { + const char *autoSocketName = wl_display_add_socket_auto(display); + if (!autoSocketName) + qFatal("Fatal: Failed to open server socket\n"); + socket_name = autoSocketName; + } + + loop = wl_display_get_event_loop(display); + + int fd = wl_event_loop_get_fd(loop); + + QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, q); + QObject::connect(sockNot, SIGNAL(activated(int)), q, SLOT(processWaylandEvents())); + + QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; + QObject::connect(dispatcher, SIGNAL(aboutToBlock()), q, SLOT(processWaylandEvents())); + + initializeHardwareIntegration(); + initializeDefaultInputDevice(); + + initialized = true; + + Q_FOREACH (QPointer<QObject> object, polish_objects) { + if (object) { + QEvent polishEvent(QEvent::Polish); + QCoreApplication::sendEvent(object.data(), &polishEvent); + } + } } -QWaylandCompositor::~QWaylandCompositor() +QWaylandCompositorPrivate::~QWaylandCompositorPrivate() { - qDeleteAll(m_compositor->m_globals); - delete m_compositor; + qDeleteAll(clients); + + qDeleteAll(outputs); + + delete data_device_manager; + + wl_display_destroy(display); } -void QWaylandCompositor::addGlobalInterface(QWaylandGlobalInterface *interface) +void QWaylandCompositorPrivate::destroySurface(QWaylandSurface *surface) { - wl_global_create(m_compositor->wl_display(), interface->interface(), interface->version(), interface, QtWayland::Compositor::bindGlobal); - m_compositor->m_globals << interface; + Q_Q(QWaylandCompositor); + q->surfaceAboutToBeDestroyed(surface); + + delete surface; } -void QWaylandCompositor::addDefaultShell() +void QWaylandCompositorPrivate::unregisterSurface(QWaylandSurface *surface) { - addGlobalInterface(new QtWayland::Shell); + if (!all_surfaces.removeOne(surface)) + qWarning("%s Unexpected state. Cant find registered surface\n", Q_FUNC_INFO); } -struct wl_display *QWaylandCompositor::waylandDisplay() const +void QWaylandCompositorPrivate::feedRetainedSelectionData(QMimeData *data) { - return m_compositor->wl_display(); + Q_Q(QWaylandCompositor); + if (retainSelection) + q->retainedSelectionReceived(data); } -void QWaylandCompositor::sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces) +void QWaylandCompositorPrivate::addPolishObject(QObject *object) { - m_compositor->sendFrameCallbacks(visibleSurfaces); + if (initialized) { + QCoreApplication::postEvent(object, new QEvent(QEvent::Polish)); + } else { + polish_objects.append(object); + } } -void QWaylandCompositor::frameStarted() +/*! + \qmlsignal void QtWaylandCompositor::WaylandCompositor::createSurface(object client, int id, int version) + + This signal is emitted when a client has created a surface. + The slot connecting to this signal may create and initialize + a WaylandSurface instance in the scope of the slot. + Otherwise a default surface is created. +*/ + +/*! + \fn void QWaylandCompositor::createSurface(QWaylandClient *client, uint id, int version) + + This signal is emitted when a client has created a surface. + The slot connecting to this signal may create and initialize + a QWaylandSurface instance in the scope of the slot. + Otherwise a default surface is created. + + Connections to this signal must be of Qt::DirectConnection connection type. +*/ + +/* + \qmlsignal void surfaceCreated(QWaylandSurface *surface) + + This signal is emitted when a new WaylandSurface instance has been created. +*/ + +/* + \fn void surfaceCreated(QWaylandSurface *surface) + + This signal is emitted when a new QWaylandSurface instance has been created. +*/ + + +void QWaylandCompositorPrivate::compositor_create_surface(wl_compositor::Resource *resource, uint32_t id) { - foreach (QtWayland::Surface *surf, m_compositor->surfaces()) - surf->frameStarted(); + Q_Q(QWaylandCompositor); + QWaylandClient *client = QWaylandClient::fromWlClient(q, resource->client()); + emit q->createSurface(client, id, resource->version()); +#ifndef QT_NO_DEBUG + Q_ASSERT_X(!QWaylandSurfacePrivate::hasUninitializedSurface(), "QWaylandCompositor", QStringLiteral("Found uninitialized QWaylandSurface after emitting QWaylandCompositor::createSurface for id %1. All surfaces has to be initialized immediately after creation. See QWaylandSurface::initialize.").arg(id).toLocal8Bit().constData()); +#endif + struct wl_resource *surfResource = wl_client_get_object(client->client(), id); + + QWaylandSurface *surface; + if (surfResource) { + surface = QWaylandSurface::fromResource(surfResource); + } else { + surface = createDefaultSurface(); + surface->initialize(q, client, id, resource->version()); + } + Q_ASSERT(surface); + all_surfaces.append(surface); + emit q->surfaceCreated(surface); } -void QWaylandCompositor::destroyClientForSurface(QWaylandSurface *surface) +void QWaylandCompositorPrivate::compositor_create_region(wl_compositor::Resource *resource, uint32_t id) { - destroyClient(surface->client()); + new QtWayland::Region(resource->client(), id); } -void QWaylandCompositor::destroyClient(QWaylandClient *client) +void QWaylandCompositorPrivate::subcompositor_get_subsurface(wl_subcompositor::Resource *resource, uint32_t id, wl_resource *surface, wl_resource *parent) { - m_compositor->destroyClient(client); + Q_Q(QWaylandCompositor); + QWaylandSurface *childSurface = QWaylandSurface::fromResource(surface); + QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent); + QWaylandSurfacePrivate::get(childSurface)->initSubsurface(parentSurface, resource->client(), id, 1); + emit q->subsurfaceChanged(childSurface, parentSurface); } -QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(QWaylandClient* client) const +/*! + \internal + Used to create a fallback QWaylandSurface when no surface was + created by emitting the QWaylandCompositor::createSurface signal. +*/ +QWaylandSurface *QWaylandCompositorPrivate::createDefaultSurface() { - QList<QtWayland::Surface *> surfaces = m_compositor->surfaces(); + return new QWaylandSurface(); +} - QList<QWaylandSurface *> result; - for (int i = 0; i < surfaces.count(); ++i) { - if (surfaces.at(i)->waylandSurface()->client() == client) { - result.append(surfaces.at(i)->waylandSurface()); - } - } +void QWaylandCompositorPrivate::initializeHardwareIntegration() +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + Q_Q(QWaylandCompositor); + if (use_hw_integration_extension) + hw_integration.reset(new QtWayland::HardwareIntegration(q)); + + loadClientBufferIntegration(); + loadServerBufferIntegration(); - return result; + if (client_buffer_integration) + client_buffer_integration->initializeHardware(display); + if (server_buffer_integration) + server_buffer_integration->initializeHardware(q); +#endif } -QList<QWaylandSurface *> QWaylandCompositor::surfaces() const +void QWaylandCompositorPrivate::initializeDefaultInputDevice() { - QList<QtWayland::Surface *> surfaces = m_compositor->surfaces(); - QList<QWaylandSurface *> surfs; - surfs.reserve(surfaces.count()); - foreach (QtWayland::Surface *s, surfaces) - surfs << s->waylandSurface(); - return surfs; + Q_Q(QWaylandCompositor); + QWaylandInputDevice *device = q->createInputDevice(); + inputDevices.append(device); + q->defaultInputDeviceChanged(device, nullptr); } -QList<QWaylandOutput *> QWaylandCompositor::outputs() const +void QWaylandCompositorPrivate::loadClientBufferIntegration() { - return m_compositor->outputs(); +#ifdef QT_COMPOSITOR_WAYLAND_GL + Q_Q(QWaylandCompositor); + QStringList keys = QtWayland::ClientBufferIntegrationFactory::keys(); + QString targetKey; + QByteArray clientBufferIntegration = qgetenv("QT_WAYLAND_HARDWARE_INTEGRATION"); + if (clientBufferIntegration.isEmpty()) + clientBufferIntegration = qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"); + if (keys.contains(QString::fromLocal8Bit(clientBufferIntegration.constData()))) { + targetKey = QString::fromLocal8Bit(clientBufferIntegration.constData()); + } else if (keys.contains(QString::fromLatin1("wayland-egl"))) { + targetKey = QString::fromLatin1("wayland-egl"); + } else if (!keys.isEmpty()) { + targetKey = keys.first(); + } + + if (!targetKey.isEmpty()) { + client_buffer_integration.reset(QtWayland::ClientBufferIntegrationFactory::create(targetKey, QStringList())); + if (client_buffer_integration) { + client_buffer_integration->setCompositor(q); + if (hw_integration) + hw_integration->setClientBufferIntegration(targetKey); + } + } + //BUG: if there is no client buffer integration, bad things will happen when opengl is used +#endif } -QWaylandOutput *QWaylandCompositor::output(QWindow *window) +void QWaylandCompositorPrivate::loadServerBufferIntegration() { - return m_compositor->output(window); +#ifdef QT_COMPOSITOR_WAYLAND_GL + QStringList keys = QtWayland::ServerBufferIntegrationFactory::keys(); + QString targetKey; + QByteArray serverBufferIntegration = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"); + if (keys.contains(QString::fromLocal8Bit(serverBufferIntegration.constData()))) { + targetKey = QString::fromLocal8Bit(serverBufferIntegration.constData()); + } + if (!targetKey.isEmpty()) { + server_buffer_integration.reset(QtWayland::ServerBufferIntegrationFactory::create(targetKey, QStringList())); + if (hw_integration) + hw_integration->setServerBufferIntegration(targetKey); + } +#endif } -QWaylandOutput *QWaylandCompositor::primaryOutput() const +/*! + \qmltype WaylandCompositor + \inqmlmodule QtWayland.Compositor + \preliminary + \brief Type managing the Wayland display server. + + The WaylandCompositor manages the connections to the clients, as well as the different + \l{WaylandOutput}{outputs} and \l{QWaylandInputDevice}{input devices}. + + Normally, a compositor application will have a single WaylandCompositor + instance, which can have several outputs as children. When a client + requests the compositor to create a surface, the request is handled by + the onCreateSurface handler. + + Extensions that are supported by the compositor should be instantiated and added to the + extensions property. +*/ + + +/*! + \class QWaylandCompositor + \inmodule QtWaylandCompositor + \preliminary + \brief Class managing the Wayland display server. + + The QWaylandCompositor manages the connections to the clients, as well as the different \l{QWaylandOutput}{outputs} + and \l{QWaylandInputDevice}{input devices}. + + Normally, a compositor application will have a single WaylandCompositor + instance, which can have several outputs as children. +*/ + +/*! + * Constructs a QWaylandCompositor with the given \a parent. + */ +QWaylandCompositor::QWaylandCompositor(QObject *parent) + : QWaylandObject(*new QWaylandCompositorPrivate(this), parent) { - return m_compositor->primaryOutput(); } -void QWaylandCompositor::setPrimaryOutput(QWaylandOutput *output) +/*! + * \internal + * Constructs a QWaylandCompositor with the private object \a dptr and \a parent. + */ +QWaylandCompositor::QWaylandCompositor(QWaylandCompositorPrivate &dptr, QObject *parent) + : QWaylandObject(dptr, parent) { - m_compositor->setPrimaryOutput(output); } -void QWaylandCompositor::cleanupGraphicsResources() +/*! + * Destroys the QWaylandCompositor + */ +QWaylandCompositor::~QWaylandCompositor() { - m_compositor->cleanupGraphicsResources(); } -void QWaylandCompositor::surfaceAboutToBeDestroyed(QWaylandSurface *surface) +/*! + * Initializes the QWaylandCompositor. + * If you override this function in your subclass, be sure to call the base class implementation. + */ +void QWaylandCompositor::create() { - Q_UNUSED(surface); + Q_D(QWaylandCompositor); + d->init(); } -QWaylandSurfaceView *QWaylandCompositor::pickView(const QPointF &globalPosition) const +/*! + * Returns true if the QWaylandCompositor has been initialized. Otherwise returns false. + */ +bool QWaylandCompositor::isCreated() const { - Q_FOREACH (QWaylandOutput *output, outputs()) { - // Skip coordinates not in output - if (!QRectF(output->geometry()).contains(globalPosition)) - continue; + Q_D(const QWaylandCompositor); + return d->initialized; +} - Q_FOREACH (QWaylandSurface *surface, output->surfaces()) { - Q_FOREACH (QWaylandSurfaceView *view, surface->views()) { - if (QRectF(view->pos(), surface->size()).contains(globalPosition)) - return view; - } - } - } +/*! + * \qmlproperty string QtWaylandCompositor::WaylandCompositor::socketName + * + * This property holds the socket name used by WaylandCompositor to communicate with + * clients. It must be set before the component is completed. + * + * If the socketName is empty (the default), the contents of the start argument + * --wayland-socket-name is used instead. If this is not set, then the compositor + * will try to find a socket name automatically, which in the default case will + * be "wayland-0". + */ - return Q_NULLPTR; +/*! + * \property QWaylandCompositor::socketName + * + * This property holds the socket name used by QWaylandCompositor to communicate with + * clients. This must be set before the QWaylandCompositor is \l{create()}{created}. + * + * If the socketName is empty (the default), the contents of the start argument + * --wayland-socket-name is used instead. If this is not set, then the compositor + * will try to find a socket name automatically, which in the default case will + * be "wayland-0". + */ +void QWaylandCompositor::setSocketName(const QByteArray &name) +{ + Q_D(QWaylandCompositor); + if (d->initialized) { + qWarning("%s: Changing socket name after initializing the compositor is not supported.\n", Q_FUNC_INFO); + return; + } + d->socket_name = name; } -QPointF QWaylandCompositor::mapToView(QWaylandSurfaceView *surface, const QPointF &globalPosition) const +QByteArray QWaylandCompositor::socketName() const { - return globalPosition - surface->pos(); + Q_D(const QWaylandCompositor); + return d->socket_name; } /*! - Override this to handle QDesktopServices::openUrl() requests from the clients. - - The default implementation simply forwards the request to QDesktopServices::openUrl(). -*/ -bool QWaylandCompositor::openUrl(QWaylandClient *client, const QUrl &url) + * \internal + */ +struct wl_display *QWaylandCompositor::display() const { - Q_UNUSED(client); - return QDesktopServices::openUrl(url); + Q_D(const QWaylandCompositor); + return d->display; } -QtWayland::Compositor * QWaylandCompositor::handle() const +/*! + * \internal + */ +uint32_t QWaylandCompositor::nextSerial() { - return m_compositor; + Q_D(QWaylandCompositor); + return wl_display_next_serial(d->display); } -void QWaylandCompositor::setRetainedSelectionEnabled(bool enabled) +/*! + * \internal + */ +QList<QWaylandClient *>QWaylandCompositor::clients() const { - m_compositor->setRetainedSelectionEnabled(enabled); + Q_D(const QWaylandCompositor); + return d->clients; } -bool QWaylandCompositor::retainedSelectionEnabled() const +/*! + * \qmlmethod QtWaylandCompositor::WaylandCompositor::destroyClientForSurface(surface) + * + * Destroys the client for the WaylandSurface \a surface. + */ + +/*! + * Destroys the client for the \a surface. + */ +void QWaylandCompositor::destroyClientForSurface(QWaylandSurface *surface) { - return m_compositor->retainedSelectionEnabled(); + destroyClient(surface->client()); } -void QWaylandCompositor::retainedSelectionReceived(QMimeData *) +/*! + * \qmlmethod QtWaylandCompositor::WaylandCompositor::destroyClient(client) + * + * Destroys the given WaylandClient \a client. + */ + +/*! + * Destroys the \a client. + */ +void QWaylandCompositor::destroyClient(QWaylandClient *client) { + if (!client) + return; + + QWaylandWindowManagerExtension *wmExtension = QWaylandWindowManagerExtension::findIn(this); + if (wmExtension) + wmExtension->sendQuitMessage(client->client()); + + wl_client_destroy(client->client()); } -void QWaylandCompositor::overrideSelection(const QMimeData *data) +/*! + * \internal + */ +QList<QWaylandSurface *> QWaylandCompositor::surfacesForClient(QWaylandClient* client) const { - m_compositor->overrideSelection(data); + Q_D(const QWaylandCompositor); + QList<QWaylandSurface *> surfs; + foreach (QWaylandSurface *surface, d->all_surfaces) { + if (surface->client() == client) + surfs.append(surface); + } + return surfs; } -void QWaylandCompositor::setClientFullScreenHint(bool value) +/*! + * \internal + */ +QList<QWaylandSurface *> QWaylandCompositor::surfaces() const { - m_compositor->setClientFullScreenHint(value); + Q_D(const QWaylandCompositor); + return d->all_surfaces; } -const char *QWaylandCompositor::socketName() const -{ - if (m_compositor->m_socket_name.isEmpty()) - return 0; - return m_compositor->m_socket_name.constData(); +/*! + * Returns the QWaylandOutput that is connected to the given \a window. + */ +QWaylandOutput *QWaylandCompositor::outputFor(QWindow *window) const +{ + Q_D(const QWaylandCompositor); + foreach (QWaylandOutput *output, d->outputs) { + if (output->window() == window) + return output; + } + + return Q_NULLPTR; } -#if QT_DEPRECATED_SINCE(5, 5) /*! - Set the screen orientation based on accelerometer data or similar. -*/ -void QWaylandCompositor::setScreenOrientation(Qt::ScreenOrientation orientation) + * \qmlproperty object QtWaylandCompositor::WaylandCompositor::defaultOutput + * + * This property contains the first in the list of outputs added to the + * WaylandCompositor, or null if no outputs have been added. + * + * Setting a new default output prepends it to the output list, making + * it the new default, but the previous default is not removed from + * the list. + */ +/*! + * \property QWaylandCompositor::defaultOutput + * + * This property contains the first in the list of outputs added to the + * QWaylandCompositor, or null if no outputs have been added. + * + * Setting a new default output prepends it to the output list, making + * it the new default, but the previous default is not removed from + * the list. If the new default output was already in the list of outputs, + * it is moved to the beginning of the list. + */ +QWaylandOutput *QWaylandCompositor::defaultOutput() const { - QWaylandOutput *output = primaryOutput(); - if (output) { - bool isPortrait = output->window()->screen()->primaryOrientation() == Qt::PortraitOrientation; - - switch (orientation) { - case Qt::PrimaryOrientation: - output->setTransform(QWaylandOutput::TransformNormal); - break; - case Qt::LandscapeOrientation: - output->setTransform(isPortrait ? QWaylandOutput::Transform270 : QWaylandOutput::TransformNormal); - break; - case Qt::PortraitOrientation: - output->setTransform(isPortrait ? QWaylandOutput::TransformNormal : QWaylandOutput::Transform90); - break; - case Qt::InvertedLandscapeOrientation: - output->setTransform(isPortrait ? QWaylandOutput::Transform90 : QWaylandOutput::Transform180); - break; - case Qt::InvertedPortraitOrientation: - output->setTransform(isPortrait ? QWaylandOutput::Transform180 : QWaylandOutput::Transform270); - break; - } - } + Q_D(const QWaylandCompositor); + return d->defaultOutput(); } -void QWaylandCompositor::setOutputGeometry(const QRect &geometry) +void QWaylandCompositor::setDefaultOutput(QWaylandOutput *output) { - QWaylandOutput *output = primaryOutput(); - if (output) - output->setGeometry(geometry); + Q_D(QWaylandCompositor); + if (d->outputs.size() && d->outputs.first() == output) + return; + d->outputs.removeOne(output); + d->outputs.prepend(output); + defaultOutputChanged(); } -QRect QWaylandCompositor::outputGeometry() const +/*! + * \internal + */ +QList<QWaylandOutput *> QWaylandCompositor::outputs() const { - QWaylandOutput *output = primaryOutput(); - if (output) - return output->geometry(); - return QRect(); + Q_D(const QWaylandCompositor); + return d->outputs; } -void QWaylandCompositor::setOutputRefreshRate(int rate) +/*! + * \internal + */ +uint QWaylandCompositor::currentTimeMsecs() const { - QWaylandOutput *output = primaryOutput(); - if (output) - output->setMode({output->mode().size, rate}); + Q_D(const QWaylandCompositor); + return d->timer.elapsed(); } -int QWaylandCompositor::outputRefreshRate() const +/*! + * \internal + */ +void QWaylandCompositor::processWaylandEvents() { - QWaylandOutput *output = primaryOutput(); - if (output) - return output->mode().refreshRate; - return 0; + Q_D(QWaylandCompositor); + int ret = wl_event_loop_dispatch(d->loop, 0); + if (ret) + fprintf(stderr, "wl_event_loop_dispatch error: %d\n", ret); + wl_display_flush_clients(d->display); } -#endif -QWaylandInputDevice *QWaylandCompositor::defaultInputDevice() const +/*! + * \internal + */ +QWaylandInputDevice *QWaylandCompositor::createInputDevice() { - return m_compositor->defaultInputDevice()->handle(); + return new QWaylandInputDevice(this); } -QWaylandInputPanel *QWaylandCompositor::inputPanel() const +/*! + * \internal + */ +QWaylandPointer *QWaylandCompositor::createPointerDevice(QWaylandInputDevice *inputDevice) { - return m_compositor->inputPanel()->handle(); + return new QWaylandPointer(inputDevice); } -QWaylandDrag *QWaylandCompositor::drag() const +/*! + * \internal + */ +QWaylandKeyboard *QWaylandCompositor::createKeyboardDevice(QWaylandInputDevice *inputDevice) { - return m_compositor->defaultInputDevice()->dragHandle(); + return new QWaylandKeyboard(inputDevice); } -bool QWaylandCompositor::isDragging() const +/*! + * \internal + */ +QWaylandTouch *QWaylandCompositor::createTouchDevice(QWaylandInputDevice *inputDevice) { - return m_compositor->isDragging(); + return new QWaylandTouch(inputDevice); } -void QWaylandCompositor::sendDragMoveEvent(const QPoint &global, const QPoint &local, - QWaylandSurface *surface) +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandCompositor::retainedSelection + * + * This property holds whether retained selection is enabled. + */ + +/*! + * \property QWaylandCompositor::retainedSelection + * + * This property holds whether retained selection is enabled. + */ +void QWaylandCompositor::setRetainedSelectionEnabled(bool enabled) { - m_compositor->sendDragMoveEvent(global, local, surface ? surface->handle() : 0); + Q_D(QWaylandCompositor); + d->retainSelection = enabled; } -void QWaylandCompositor::sendDragEndEvent() +bool QWaylandCompositor::retainedSelectionEnabled() const { - m_compositor->sendDragEndEvent(); + Q_D(const QWaylandCompositor); + return d->retainSelection; } -void QWaylandCompositor::setCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY) +/*! + * \internal + */ +void QWaylandCompositor::retainedSelectionReceived(QMimeData *) { - Q_UNUSED(surface); - Q_UNUSED(hotspotX); - Q_UNUSED(hotspotY); } -void QWaylandCompositor::configureTouchExtension(TouchExtensionFlags flags) +/*! + * \internal + */ +void QWaylandCompositor::overrideSelection(const QMimeData *data) { - m_compositor->configureTouchExtension(flags); + Q_D(QWaylandCompositor); + d->data_device_manager->overrideSelection(*data); } -QWaylandSurfaceView *QWaylandCompositor::createView(QWaylandSurface *surface) +/*! + * \qmlproperty object QtWaylandCompositor::WaylandCompositor::defaultInputDevice + * + * This property contains the default input device for this + * WaylandCompositor. + */ + +/*! + * \property QWaylandCompositor::defaultInputDevice + * + * This property contains the default input device for this + * QWaylandCompositor. + */ +QWaylandInputDevice *QWaylandCompositor::defaultInputDevice() const { - return new QWaylandSurfaceView(surface); + Q_D(const QWaylandCompositor); + if (d->inputDevices.size()) + return d->inputDevices.first(); + return Q_NULLPTR; } +/*! + * \internal + * + * Currently, Qt only supports a single input device, so this exists for + * future proofing the APIs. + */ QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent) { - return m_compositor->inputDeviceFor(inputEvent); + Q_D(QWaylandCompositor); + QWaylandInputDevice *dev = NULL; + for (int i = 0; i < d->inputDevices.size(); i++) { + QWaylandInputDevice *candidate = d->inputDevices.at(i); + if (candidate->isOwner(inputEvent)) { + dev = candidate; + break; + } + } + return dev; +} + +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandCompositor::useHardwareIntegrationExtension + * + * This property holds whether the hardware integration extension should be enabled for + * this WaylandCompositor. + * + * This property must be set before the compositor component is completed. + */ + +/*! + * \property QWaylandCompositor::useHardwareIntegrationExtension + * + * This property holds whether the hardware integration extension should be enabled for + * this QWaylandCompositor. + * + * This property must be set before the compositor is \l{create()}{created}. + */ +bool QWaylandCompositor::useHardwareIntegrationExtension() const +{ + Q_D(const QWaylandCompositor); + return d->use_hw_integration_extension; } -QWaylandOutput *QWaylandCompositor::createOutput(QWindow *window, - const QString &manufacturer, - const QString &model) +void QWaylandCompositor::setUseHardwareIntegrationExtension(bool use) { - return new QWaylandOutput(this, window, manufacturer, model); + Q_D(QWaylandCompositor); + if (use == d->use_hw_integration_extension) + return; + + if (d->initialized) + qWarning("Setting QWaylandCompositor::useHardwareIntegrationExtension after initialization has no effect"); + + d->use_hw_integration_extension = use; + useHardwareIntegrationExtensionChanged(); +} + +/*! + * Grab the surface content from the given \a buffer. + * The default implementation requires a OpenGL context to be bound to the current thread + * to work. If this is not possible reimplement this function in your compositor subclass + * to implement custom logic. + * The default implementation only grabs SHM and OpenGL buffers, reimplement this in your + * compositor subclass to handle more buffer types. + * You should not call this manually, but rather use \a QWaylandSurfaceGrabber. + */ +void QWaylandCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer) +{ + if (buffer.isShm()) { + emit grabber->success(buffer.image()); + } else { +#ifdef QT_COMPOSITOR_WAYLAND_GL + if (QOpenGLContext::currentContext()) { + QOpenGLFramebufferObject fbo(buffer.size()); + fbo.bind(); + QOpenGLTextureBlitter blitter; + blitter.create(); + blitter.bind(); + + glViewport(0, 0, buffer.size().width(), buffer.size().height()); + + QOpenGLTextureBlitter::Origin surfaceOrigin = + buffer.origin() == QWaylandSurface::OriginTopLeft + ? QOpenGLTextureBlitter::OriginTopLeft + : QOpenGLTextureBlitter::OriginBottomLeft; + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + buffer.bindToTexture(); + blitter.blit(texture, QMatrix4x4(), surfaceOrigin); + + blitter.release(); + glDeleteTextures(1, &texture); + + emit grabber->success(fbo.toImage()); + } else +#endif + emit grabber->failed(QWaylandSurfaceGrabber::UnknownBufferType); + } } QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index 7097a19f4..f97484d86 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -41,11 +37,14 @@ #ifndef QWAYLANDCOMPOSITOR_H #define QWAYLANDCOMPOSITOR_H -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandcompositorextension.h> +#include <QtWaylandCompositor/QWaylandOutput> #include <QObject> #include <QImage> #include <QRect> +#include <QLoggingCategory> struct wl_display; @@ -56,124 +55,96 @@ class QInputEvent; class QMimeData; class QUrl; class QOpenGLContext; +class QWaylandCompositorPrivate; class QWaylandClient; class QWaylandSurface; class QWaylandInputDevice; -class QWaylandInputPanel; -class QWaylandDrag; class QWaylandGlobalInterface; -class QWaylandSurfaceView; -class QWaylandOutput; +class QWaylandView; +class QWaylandPointer; +class QWaylandKeyboard; +class QWaylandTouch; +class QWaylandSurfaceGrabber; +class QWaylandBufferRef; -namespace QtWayland -{ - class Compositor; -} +Q_DECLARE_LOGGING_CATEGORY(qLcCompositorInputMethods) -class Q_COMPOSITOR_EXPORT QWaylandCompositor +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositor : public QWaylandObject { + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandCompositor) + Q_PROPERTY(QByteArray socketName READ socketName WRITE setSocketName) + Q_PROPERTY(bool retainedSelection READ retainedSelectionEnabled WRITE setRetainedSelectionEnabled) + Q_PROPERTY(QWaylandOutput *defaultOutput READ defaultOutput WRITE setDefaultOutput NOTIFY defaultOutputChanged) + Q_PROPERTY(bool useHardwareIntegrationExtension READ useHardwareIntegrationExtension WRITE setUseHardwareIntegrationExtension NOTIFY useHardwareIntegrationExtensionChanged) + Q_PROPERTY(QWaylandInputDevice *defaultInputDevice READ defaultInputDevice NOTIFY defaultInputDeviceChanged) + public: - enum ExtensionFlag { - WindowManagerExtension = 0x01, - SurfaceExtension = 0x02, - QtKeyExtension = 0x04, - TouchExtension = 0x08, - SubSurfaceExtension = 0x10, - TextInputExtension = 0x20, - HardwareIntegrationExtension = 0x40, - - DefaultExtensions = WindowManagerExtension | SurfaceExtension | QtKeyExtension | TouchExtension | HardwareIntegrationExtension - }; - Q_DECLARE_FLAGS(ExtensionFlags, ExtensionFlag) - - QWaylandCompositor(const char *socketName = Q_NULLPTR, ExtensionFlags extensions = DefaultExtensions); + QWaylandCompositor(QObject *parent = nullptr); virtual ~QWaylandCompositor(); - void addGlobalInterface(QWaylandGlobalInterface *interface); - void addDefaultShell(); - ::wl_display *waylandDisplay() const; - - void frameStarted(); - void sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces); - - void destroyClientForSurface(QWaylandSurface *surface); - void destroyClient(QWaylandClient *client); + virtual void create(); + bool isCreated() const; - QList<QWaylandSurface *> surfacesForClient(QWaylandClient* client) const; - QList<QWaylandSurface *> surfaces() const; + void setSocketName(const QByteArray &name); + QByteArray socketName() const; - QList<QWaylandOutput *> outputs() const; - QWaylandOutput *output(QWindow *window); + ::wl_display *display() const; + uint32_t nextSerial(); - QWaylandOutput *primaryOutput() const; - void setPrimaryOutput(QWaylandOutput *output); + QList<QWaylandClient *>clients() const; + Q_INVOKABLE void destroyClientForSurface(QWaylandSurface *surface); + Q_INVOKABLE void destroyClient(QWaylandClient *client); - virtual void surfaceCreated(QWaylandSurface *surface) = 0; - virtual void surfaceAboutToBeDestroyed(QWaylandSurface *surface); + QList<QWaylandSurface *> surfaces() const; + QList<QWaylandSurface *> surfacesForClient(QWaylandClient* client) const; - virtual QWaylandSurfaceView *pickView(const QPointF &globalPosition) const; - virtual QPointF mapToView(QWaylandSurfaceView *view, const QPointF &surfacePosition) const; + Q_INVOKABLE QWaylandOutput *outputFor(QWindow *window) const; - virtual bool openUrl(QWaylandClient *client, const QUrl &url); + QWaylandOutput *defaultOutput() const; + void setDefaultOutput(QWaylandOutput *output); + QList<QWaylandOutput *> outputs() const; - QtWayland::Compositor *handle() const; + uint currentTimeMsecs() const; void setRetainedSelectionEnabled(bool enabled); bool retainedSelectionEnabled() const; void overrideSelection(const QMimeData *data); - void setClientFullScreenHint(bool value); - - const char *socketName() const; - -#if QT_DEPRECATED_SINCE(5, 5) - void setScreenOrientation(Qt::ScreenOrientation orientation); - - void setOutputGeometry(const QRect &outputGeometry); - QRect outputGeometry() const; - - void setOutputRefreshRate(int refreshRate); - int outputRefreshRate() const; -#endif - QWaylandInputDevice *defaultInputDevice() const; - QWaylandInputPanel *inputPanel() const; - QWaylandDrag *drag() const; + QWaylandView *createSurfaceView(QWaylandSurface *surface); - bool isDragging() const; - void sendDragMoveEvent(const QPoint &global, const QPoint &local, QWaylandSurface *surface); - void sendDragEndEvent(); + QWaylandInputDevice *inputDeviceFor(QInputEvent *inputEvent); - virtual void setCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY); + bool useHardwareIntegrationExtension() const; + void setUseHardwareIntegrationExtension(bool use); - void cleanupGraphicsResources(); + virtual void grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer); - enum TouchExtensionFlag { - TouchExtMouseFromTouch = 0x01 - }; - Q_DECLARE_FLAGS(TouchExtensionFlags, TouchExtensionFlag) - void configureTouchExtension(TouchExtensionFlags flags); +public Q_SLOTS: + void processWaylandEvents(); - virtual QWaylandSurfaceView *createView(QWaylandSurface *surface); +Q_SIGNALS: + void createSurface(QWaylandClient *client, uint id, int version); + void surfaceCreated(QWaylandSurface *surface); + void surfaceAboutToBeDestroyed(QWaylandSurface *surface); + void subsurfaceChanged(QWaylandSurface *child, QWaylandSurface *parent); - QWaylandInputDevice *inputDeviceFor(QInputEvent *inputEvent); + void defaultOutputChanged(); + void defaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice); + void useHardwareIntegrationExtensionChanged(); protected: - QWaylandCompositor(const char *socketName, QtWayland::Compositor *dptr); virtual void retainedSelectionReceived(QMimeData *mimeData); + virtual QWaylandInputDevice *createInputDevice(); + virtual QWaylandPointer *createPointerDevice(QWaylandInputDevice *inputDevice); + virtual QWaylandKeyboard *createKeyboardDevice(QWaylandInputDevice *inputDevice); + virtual QWaylandTouch *createTouchDevice(QWaylandInputDevice *inputDevice); - virtual QWaylandOutput *createOutput(QWindow *window, - const QString &manufacturer, - const QString &model); - - friend class QtWayland::Compositor; - QtWayland::Compositor *m_compositor; + QWaylandCompositor(QWaylandCompositorPrivate &dptr, QObject *parent = nullptr); }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandCompositor::ExtensionFlags) -Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandCompositor::TouchExtensionFlags) - QT_END_NAMESPACE #endif // QWAYLANDCOMPOSITOR_H diff --git a/src/compositor/compositor_api/qwaylandcompositor_p.h b/src/compositor/compositor_api/qwaylandcompositor_p.h new file mode 100644 index 000000000..8966acb38 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandcompositor_p.h @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2014-2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDCOMPOSITOR_P_H +#define QWAYLANDCOMPOSITOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtCore/private/qobject_p.h> +#include <QtCore/QSet> +#include <QtCore/QElapsedTimer> + +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + class HardwareIntegration; + class ClientBufferIntegration; + class ServerBufferIntegration; + class DataDeviceManager; +} + +class QWindowSystemEventHandler; +class QWaylandSurface; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositorPrivate : public QObjectPrivate, public QtWaylandServer::wl_compositor, public QtWaylandServer::wl_subcompositor +{ +public: + static QWaylandCompositorPrivate *get(QWaylandCompositor *compositor) { return compositor->d_func(); } + + QWaylandCompositorPrivate(QWaylandCompositor *compositor); + ~QWaylandCompositorPrivate(); + + void init(); + + void destroySurface(QWaylandSurface *surface); + void unregisterSurface(QWaylandSurface *surface); + + QWaylandOutput *defaultOutput() const { return outputs.size() ? outputs.first() : Q_NULLPTR; } + + inline QtWayland::ClientBufferIntegration *clientBufferIntegration() const; + inline QtWayland::ServerBufferIntegration *serverBufferIntegration() const; + + QtWayland::DataDeviceManager *dataDeviceManager() const { return data_device_manager; } + void feedRetainedSelectionData(QMimeData *data); + + QWaylandPointer *callCreatePointerDevice(QWaylandInputDevice *inputDevice) + { return q_func()->createPointerDevice(inputDevice); } + QWaylandKeyboard *callCreateKeyboardDevice(QWaylandInputDevice *inputDevice) + { return q_func()->createKeyboardDevice(inputDevice); } + QWaylandTouch *callCreateTouchDevice(QWaylandInputDevice *inputDevice) + { return q_func()->createTouchDevice(inputDevice); } + + inline void addClient(QWaylandClient *client); + inline void removeClient(QWaylandClient *client); + + void addPolishObject(QObject *object); + + inline void addOutput(QWaylandOutput *output); + inline void removeOutput(QWaylandOutput *output); +protected: + void compositor_create_surface(wl_compositor::Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + void compositor_create_region(wl_compositor::Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + + void subcompositor_get_subsurface(wl_subcompositor::Resource *resource, uint32_t id, struct ::wl_resource *surface, struct ::wl_resource *parent) Q_DECL_OVERRIDE; + + virtual QWaylandSurface *createDefaultSurface(); +protected: + void initializeHardwareIntegration(); + void initializeExtensions(); + void initializeDefaultInputDevice(); + + void loadClientBufferIntegration(); + void loadServerBufferIntegration(); + + QByteArray socket_name; + struct wl_display *display; + + QList<QWaylandInputDevice *> inputDevices; + QList<QWaylandOutput *> outputs; + + QList<QWaylandSurface *> all_surfaces; + + QtWayland::DataDeviceManager *data_device_manager; + + QElapsedTimer timer; + + wl_event_loop *loop; + + QList<QWaylandClient *> clients; + +#ifdef QT_COMPOSITOR_WAYLAND_GL + bool use_hw_integration_extension; + QScopedPointer<QtWayland::HardwareIntegration> hw_integration; + QScopedPointer<QtWayland::ClientBufferIntegration> client_buffer_integration; + QScopedPointer<QtWayland::ServerBufferIntegration> server_buffer_integration; +#endif + + QScopedPointer<QWindowSystemEventHandler> eventHandler; + + bool retainSelection; + bool initialized; + QList<QPointer<QObject> > polish_objects; + + Q_DECLARE_PUBLIC(QWaylandCompositor) + Q_DISABLE_COPY(QWaylandCompositorPrivate) +}; + +QtWayland::ClientBufferIntegration * QWaylandCompositorPrivate::clientBufferIntegration() const +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + return client_buffer_integration.data(); +#else + return 0; +#endif +} + +QtWayland::ServerBufferIntegration * QWaylandCompositorPrivate::serverBufferIntegration() const +{ +#ifdef QT_COMPOSITOR_WAYLAND_GL + return server_buffer_integration.data(); +#else + return 0; +#endif +} + +void QWaylandCompositorPrivate::addClient(QWaylandClient *client) +{ + Q_ASSERT(!clients.contains(client)); + clients.append(client); +} + +void QWaylandCompositorPrivate::removeClient(QWaylandClient *client) +{ + Q_ASSERT(clients.contains(client)); + clients.removeOne(client); +} + +void QWaylandCompositorPrivate::addOutput(QWaylandOutput *output) +{ + Q_ASSERT(output); + if (outputs.contains(output)) + return; + outputs.append(output); +} + +void QWaylandCompositorPrivate::removeOutput(QWaylandOutput *output) +{ + Q_ASSERT(output); + Q_ASSERT(outputs.count(output) == 1); + outputs.removeOne(output); +} + +QT_END_NAMESPACE + +#endif //QWAYLANDCOMPOSITOR_P_H diff --git a/src/compositor/compositor_api/qwaylanddestroylistener.cpp b/src/compositor/compositor_api/qwaylanddestroylistener.cpp new file mode 100644 index 000000000..13ec63849 --- /dev/null +++ b/src/compositor/compositor_api/qwaylanddestroylistener.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylanddestroylistener.h" +#include "qwaylanddestroylistener_p.h" + +QT_BEGIN_NAMESPACE + +QWaylandDestroyListenerPrivate::QWaylandDestroyListenerPrivate() +{ + listener.parent = this; + listener.listener.notify = handler; + wl_list_init(&listener.listener.link); +} + +QWaylandDestroyListener::QWaylandDestroyListener(QObject *parent) + : QObject(* new QWaylandDestroyListenerPrivate(), parent) +{ +} +void QWaylandDestroyListener::listenForDestruction(::wl_resource *resource) +{ + Q_D(QWaylandDestroyListener); + wl_resource_add_destroy_listener(resource, &d->listener.listener); +} + +void QWaylandDestroyListener::reset() +{ + Q_D(QWaylandDestroyListener); + wl_list_remove(&d->listener.listener.link); + wl_list_init(&d->listener.listener.link); +} + +void QWaylandDestroyListenerPrivate::handler(wl_listener *listener, void *data) +{ + QWaylandDestroyListenerPrivate *that = reinterpret_cast<Listener *>(listener)->parent; + emit that->q_func()->fired(data); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylanddestroylistener.h b/src/compositor/compositor_api/qwaylanddestroylistener.h new file mode 100644 index 000000000..580a5c46a --- /dev/null +++ b/src/compositor/compositor_api/qwaylanddestroylistener.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDDESTROYLISTENER_H +#define QWAYLANDDESTROYLISTENER_H + +#include <QtCore/QObject> +#include <QtWaylandCompositor/qwaylandexport.h> + +struct wl_resource; + +QT_BEGIN_NAMESPACE + +class QWaylandDestroyListenerPrivate; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandDestroyListener : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandDestroyListener) +public: + QWaylandDestroyListener(QObject *parent = nullptr); + void listenForDestruction(struct wl_resource *resource); + void reset(); + +Q_SIGNALS: + void fired(void *data); + +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDDESTROYLISTENER_H*/ diff --git a/src/compositor/wayland_wrapper/qwllistener_p.h b/src/compositor/compositor_api/qwaylanddestroylistener_p.h index 296a081ab..63b2d3ce9 100644 --- a/src/compositor/wayland_wrapper/qwllistener_p.h +++ b/src/compositor/compositor_api/qwaylanddestroylistener_p.h @@ -3,9 +3,9 @@ ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -45,32 +48,28 @@ // We mean it. // -#include <QObject> +#include "qwaylanddestroylistener.h" + +#include <QtCore/private/qobject_p.h> #include <wayland-server.h> QT_BEGIN_NAMESPACE -class WlListener : public QObject +class QWaylandDestroyListenerPrivate : public QObjectPrivate { - Q_OBJECT public: - WlListener(); - - void listenForDestruction(::wl_resource *resource); - void reset(); + Q_DECLARE_PUBLIC(QWaylandDestroyListener) -signals: - void fired(void *data); + QWaylandDestroyListenerPrivate(); -private: static void handler(wl_listener *listener, void *data); struct Listener { wl_listener listener; - WlListener *parent; + QWaylandDestroyListenerPrivate *parent; }; - Listener m_listener; + Listener listener; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylanddrag.cpp b/src/compositor/compositor_api/qwaylanddrag.cpp index b31df31b8..cc45c1279 100644 --- a/src/compositor/compositor_api/qwaylanddrag.cpp +++ b/src/compositor/compositor_api/qwaylanddrag.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -42,51 +38,85 @@ #include <private/qobject_p.h> -#include "qwlcompositor_p.h" -#include "qwlinputdevice_p.h" #include "qwldatadevice_p.h" -#include "qwlsurface_p.h" -#include "qwaylandsurfaceview.h" +#include "qwaylandview.h" +#include <QtWaylandCompositor/private/qwaylandinput_p.h> QT_BEGIN_NAMESPACE class QWaylandDragPrivate : public QObjectPrivate { public: - QWaylandDragPrivate(QtWayland::InputDevice *id) + QWaylandDragPrivate(QWaylandInputDevice *id) : inputDevice(id) { } - QtWayland::InputDevice *inputDevice; -}; + QtWayland::DataDevice *dataDevice() + { + return QWaylandInputDevicePrivate::get(inputDevice)->dataDevice(); + } + + const QtWayland::DataDevice *dataDevice() const + { + return QWaylandInputDevicePrivate::get(inputDevice)->dataDevice(); + } + QWaylandInputDevice *inputDevice; +}; -QWaylandDrag::QWaylandDrag(QtWayland::InputDevice *inputDevice) +QWaylandDrag::QWaylandDrag(QWaylandInputDevice *inputDevice) : QObject(* new QWaylandDragPrivate(inputDevice)) { } -QWaylandSurfaceView *QWaylandDrag::icon() const +QWaylandSurface *QWaylandDrag::icon() const { Q_D(const QWaylandDrag); - const QtWayland::DataDevice *dataDevice = d->inputDevice->dataDevice(); + const QtWayland::DataDevice *dataDevice = d->dataDevice(); if (!dataDevice) return 0; return dataDevice->dragIcon(); } + bool QWaylandDrag::visible() const { Q_D(const QWaylandDrag); - const QtWayland::DataDevice *dataDevice = d->inputDevice->dataDevice(); + const QtWayland::DataDevice *dataDevice = d->dataDevice(); if (!dataDevice) return false; return dataDevice->dragIcon() != 0; } +void QWaylandDrag::dragMove(QWaylandSurface *target, const QPointF &pos) +{ + Q_D(QWaylandDrag); + QtWayland::DataDevice *dataDevice = d->dataDevice(); + if (!dataDevice) + return; + dataDevice->dragMove(target, pos); +} +void QWaylandDrag::drop() +{ + Q_D(QWaylandDrag); + QtWayland::DataDevice *dataDevice = d->dataDevice(); + if (!dataDevice) + return; + dataDevice->drop(); +} + +void QWaylandDrag::cancelDrag() +{ + Q_D(QWaylandDrag); + QtWayland::DataDevice *dataDevice = d->dataDevice(); + if (!dataDevice) + return; + dataDevice->cancelDrag(); +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylanddrag.h b/src/compositor/compositor_api/qwaylanddrag.h index c0b0aca36..00a2bee8e 100644 --- a/src/compositor/compositor_api/qwaylanddrag.h +++ b/src/compositor/compositor_api/qwaylanddrag.h @@ -3,36 +3,32 @@ ** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -41,35 +37,48 @@ #ifndef QWAYLANDDRAG_H #define QWAYLANDDRAG_H -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> -#include <QObject> +#include <QtCore/QObject> +#include <QtCore/QPointF> QT_BEGIN_NAMESPACE class QWaylandDragPrivate; class QWaylandSurface; -class QWaylandSurfaceView; +class QWaylandView; +class QWaylandInputDevice; namespace QtWayland { -class InputDevice; + class DataDevice; } -class Q_COMPOSITOR_EXPORT QWaylandDrag : public QObject + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandDrag : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandDrag) - Q_PROPERTY(QWaylandSurfaceView* icon READ icon NOTIFY iconChanged) + Q_PROPERTY(QWaylandSurface *icon READ icon NOTIFY iconChanged) Q_PROPERTY(bool visible READ visible NOTIFY iconChanged) public: - explicit QWaylandDrag(QtWayland::InputDevice *inputDevice); + explicit QWaylandDrag(QWaylandInputDevice *inputDevice); - QWaylandSurfaceView *icon() const; + QWaylandSurface *icon() const; + // QPointF position() const; bool visible() const; +public Q_SLOTS: + void dragMove(QWaylandSurface *target, const QPointF &pos); + void drop(); + void cancelDrag(); + Q_SIGNALS: void iconChanged(); + void dragStarted(); // QWaylandSurface *icon???? + +private: + //friend class QtWayland::DataDevice; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandglobalinterface.cpp b/src/compositor/compositor_api/qwaylandglobalinterface.cpp deleted file mode 100644 index 791964863..000000000 --- a/src/compositor/compositor_api/qwaylandglobalinterface.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandglobalinterface.h" - -#include <wayland-server.h> - -QT_BEGIN_NAMESPACE - -QWaylandGlobalInterface::QWaylandGlobalInterface() -{ - -} - -QWaylandGlobalInterface::~QWaylandGlobalInterface() -{ - -} - -quint32 QWaylandGlobalInterface::version() const -{ - return interface()->version; -} - -QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandglobalinterface.h b/src/compositor/compositor_api/qwaylandglobalinterface.h deleted file mode 100644 index 6be3236fa..000000000 --- a/src/compositor/compositor_api/qwaylandglobalinterface.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDGLOBALINTERFACE_H -#define QWAYLANDGLOBALINTERFACE_H - -#include <QtCompositor/qwaylandexport.h> - -struct wl_interface; -struct wl_client; - -QT_BEGIN_NAMESPACE - -namespace QtWayland { -class Compositor; -} - -class Q_COMPOSITOR_EXPORT QWaylandGlobalInterface -{ -public: - QWaylandGlobalInterface(); - virtual ~QWaylandGlobalInterface(); - - virtual const wl_interface *interface() const = 0; - virtual quint32 version() const; - -protected: - virtual void bind(wl_client *client, quint32 version, quint32 id) = 0; - - friend class QtWayland::Compositor; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandinput.cpp index 4e106f5fe..09c02bc48 100644 --- a/src/compositor/compositor_api/qwaylandinput.cpp +++ b/src/compositor/compositor_api/qwaylandinput.cpp @@ -3,52 +3,141 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qwaylandinput.h" +#include "qwaylandinput_p.h" -#include "qwlinputdevice_p.h" -#include "qwlkeyboard_p.h" #include "qwaylandcompositor.h" -#include "qwlsurface_p.h" -#include "qwlcompositor_p.h" -#include "qwaylandsurfaceview.h" +#include "qwaylandinputmethodcontrol.h" +#include "qwaylandview.h" +#include <QtWaylandCompositor/QWaylandDrag> +#include <QtWaylandCompositor/QWaylandTouch> +#include <QtWaylandCompositor/QWaylandPointer> +#include <QtWaylandCompositor/QWaylandWlShellSurface> +#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandcompositor_p.h> +#include <QtWaylandCompositor/private/qwldatadevice_p.h> + +#include "extensions/qwlqtkey_p.h" +#include "extensions/qwaylandtextinput.h" QT_BEGIN_NAMESPACE +QWaylandInputDevicePrivate::QWaylandInputDevicePrivate(QWaylandInputDevice *inputdevice, QWaylandCompositor *compositor) + : QObjectPrivate() + , QtWaylandServer::wl_seat(compositor->display(), 4) + , compositor(compositor) + , mouseFocus(Q_NULLPTR) + , keyboardFocus(nullptr) + , capabilities() + , data_device() + , drag_handle(new QWaylandDrag(inputdevice)) +{ +} + +QWaylandInputDevicePrivate::~QWaylandInputDevicePrivate() +{ +} + +void QWaylandInputDevicePrivate::setCapabilities(QWaylandInputDevice::CapabilityFlags caps) +{ + Q_Q(QWaylandInputDevice); + if (capabilities != caps) { + QWaylandInputDevice::CapabilityFlags changed = caps ^ capabilities; + + if (changed & QWaylandInputDevice::Pointer) { + pointer.reset(pointer.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreatePointerDevice(q) : 0); + } + + if (changed & QWaylandInputDevice::Keyboard) { + keyboard.reset(keyboard.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateKeyboardDevice(q) : 0); + } + + if (changed & QWaylandInputDevice::Touch) { + touch.reset(touch.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateTouchDevice(q) : 0); + } + + capabilities = caps; + QList<Resource *> resources = resourceMap().values(); + for (int i = 0; i < resources.size(); i++) { + wl_seat::send_capabilities(resources.at(i)->handle, (uint32_t)capabilities); + } + + if ((changed & caps & QWaylandInputDevice::Keyboard) && keyboardFocus != nullptr) + keyboard->setFocus(keyboardFocus); + } +} + +void QWaylandInputDevicePrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *, struct wl_client *client, uint32_t id) +{ + Q_Q(QWaylandInputDevice); + if (!data_device) + data_device.reset(new QtWayland::DataDevice(q)); + data_device->add(client, id, 1); +} + +void QWaylandInputDevicePrivate::seat_destroy_resource(wl_seat::Resource *) +{ +// cleanupDataDeviceForClient(resource->client(), true); +} + +void QWaylandInputDevicePrivate::seat_bind_resource(wl_seat::Resource *resource) +{ + // The order of capabilities matches the order defined in the wayland protocol + wl_seat::send_capabilities(resource->handle, (uint32_t)capabilities); +} + +void QWaylandInputDevicePrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id) +{ + if (!pointer.isNull()) { + pointer->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version()); + } +} + +void QWaylandInputDevicePrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id) +{ + if (!keyboard.isNull()) { + keyboard->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version()); + } +} + +void QWaylandInputDevicePrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id) +{ + if (!touch.isNull()) { + touch->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version()); + } +} + QWaylandKeymap::QWaylandKeymap(const QString &layout, const QString &variant, const QString &options, const QString &model, const QString &rules) : m_layout(layout) , m_variant(variant) @@ -59,134 +148,328 @@ QWaylandKeymap::QWaylandKeymap(const QString &layout, const QString &variant, co } +/*! + * \class QWaylandInputDevice + * \inmodule QtWaylandCompositor + * \preliminary + * \brief The QWaylandInputDevice class provides access to keyboard, mouse and touch input. + * + * The QWaylandInputDevice provides access to different types of user input and maintains + * a keyboard focus and a mouse pointer. It corresponds to the wl_seat interface in the Wayland protocol. + */ -QWaylandInputDevice::QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags caps) - : d(new QtWayland::InputDevice(this,compositor->handle(), caps)) -{ -} +/*! + * \enum QWaylandInputDevice::CapabilityFlag + * + * This enum type describes the capabilities of a QWaylandInputDevice. + * + * \value Pointer The QWaylandInputDevice supports pointer input. + * \value Keyboard The QWaylandInputDevice supports keyboard input. + * \value Touch The QWaylandInputDevice supports touch input. + */ -QWaylandInputDevice::~QWaylandInputDevice() +/*! + * Constructs a QWaylandInputDevice for the given \a compositor and with the given \a capabilityFlags. + */ +QWaylandInputDevice::QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags) + : QWaylandObject(*new QWaylandInputDevicePrivate(this,compositor)) { - delete d; + d_func()->setCapabilities(capabilityFlags); } -void QWaylandInputDevice::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) +/*! + * Destroys the QWaylandInputDevice + */ +QWaylandInputDevice::~QWaylandInputDevice() { - d->sendMousePressEvent(button,localPos,globalPos); } -void QWaylandInputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) +/*! + * Sends a mouse press event for \a button to the QWaylandInputDevice's pointer device. + */ +void QWaylandInputDevice::sendMousePressEvent(Qt::MouseButton button) { - d->sendMouseReleaseEvent(button,localPos,globalPos); + Q_D(QWaylandInputDevice); + d->pointer->sendMousePressEvent(button); } -void QWaylandInputDevice::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos) +/*! + * Sends a mouse release event for \a button to the QWaylandInputDevice's pointer device. + */ +void QWaylandInputDevice::sendMouseReleaseEvent(Qt::MouseButton button) { - d->sendMouseMoveEvent(localPos,globalPos); + Q_D(QWaylandInputDevice); + d->pointer->sendMouseReleaseEvent(button); } -/** Convenience function that will set the mouse focus to the surface, then send the mouse move event. - * If the mouse focus is the same surface as the surface passed in, then only the move event is sent +/*! + * Sets the mouse focus to \a view and sends a mouse move event to the pointer device with the + * local position \a localPos and output space position \a outputSpacePos. **/ -void QWaylandInputDevice::sendMouseMoveEvent(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos) +void QWaylandInputDevice::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos) { - d->sendMouseMoveEvent(surface,localPos,globalPos); + Q_D(QWaylandInputDevice); + d->pointer->sendMouseMoveEvent(view, localPos, outputSpacePos); } +/*! + * Sends a mouse wheel event to the QWaylandInputDevice's pointer device with the given \a orientation and \a delta. + */ void QWaylandInputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta) { - d->sendMouseWheelEvent(orientation, delta); + Q_D(QWaylandInputDevice); + d->pointer->sendMouseWheelEvent(orientation, delta); } +/*! + * Sends a key press event with the key \a code to the keyboard device. + */ void QWaylandInputDevice::sendKeyPressEvent(uint code) { - d->keyboardDevice()->sendKeyPressEvent(code); + Q_D(QWaylandInputDevice); + d->keyboard->sendKeyPressEvent(code); } +/*! + * Sends a key release event with the key \a code to the keyboard device. + */ void QWaylandInputDevice::sendKeyReleaseEvent(uint code) { - d->keyboardDevice()->sendKeyReleaseEvent(code); + Q_D(QWaylandInputDevice); + d->keyboard->sendKeyReleaseEvent(code); } -void QWaylandInputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state) +/*! + * Sends a touch point event with the given \a id and \a state to the touch device. The position + * of the touch point is given by \a point. + */ +void QWaylandInputDevice::sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state) { - d->sendTouchPointEvent(id,x,y,state); + Q_D(QWaylandInputDevice); + if (d->touch.isNull()) { + return; + } + d->touch->sendTouchPointEvent(id, point,state); } +/*! + * Sends a frame event to the touch device. + */ void QWaylandInputDevice::sendTouchFrameEvent() { - d->sendTouchFrameEvent(); + Q_D(QWaylandInputDevice); + if (!d->touch.isNull()) { + d->touch->sendFrameEvent(); + } } +/*! + * Sends a cancel event to the touch device. + */ void QWaylandInputDevice::sendTouchCancelEvent() { - d->sendTouchCancelEvent(); + Q_D(QWaylandInputDevice); + if (!d->touch.isNull()) { + d->touch->sendCancelEvent(); + } } +/*! + * Sends the \a event to the touch device. + */ void QWaylandInputDevice::sendFullTouchEvent(QTouchEvent *event) { - d->sendFullTouchEvent(event); + Q_D(QWaylandInputDevice); + if (!mouseFocus()) { + qWarning("Cannot send touch event, no pointer focus, fix the compositor"); + return; + } + + if (!d->touch) + return; + + d->touch->sendFullTouchEvent(event); } +/*! + * Sends the \a event to the keyboard device. + */ void QWaylandInputDevice::sendFullKeyEvent(QKeyEvent *event) { - d->sendFullKeyEvent(event); + Q_D(QWaylandInputDevice); + + if (!keyboardFocus()) { + qWarning("Cannot send key event, no keyboard focus, fix the compositor"); + return; + } + + if (keyboardFocus()->inputMethodControl()->enabled() + && event->nativeScanCode() == 0) { + QWaylandTextInput *textInput = QWaylandTextInput::findIn(this); + if (textInput) { + textInput->sendKeyEvent(event); + return; + } + } + + QtWayland::QtKeyExtensionGlobal *ext = QtWayland::QtKeyExtensionGlobal::findIn(d->compositor); + if (ext && ext->postQtKeyEvent(event, keyboardFocus())) + return; + + if (!d->keyboard.isNull() && !event->isAutoRepeat()) { + if (event->type() == QEvent::KeyPress) + d->keyboard->sendKeyPressEvent(event->nativeScanCode()); + else if (event->type() == QEvent::KeyRelease) + d->keyboard->sendKeyReleaseEvent(event->nativeScanCode()); + } } -void QWaylandInputDevice::sendFullKeyEvent(QWaylandSurface *surface, QKeyEvent *event) +/*! + * Returns the keyboard for this input device. + */ +QWaylandKeyboard *QWaylandInputDevice::keyboard() const { - d->sendFullKeyEvent(surface->handle(), event); + Q_D(const QWaylandInputDevice); + return d->keyboard.data(); } +/*! + * Returns the current focused surface for keyboard input. + */ QWaylandSurface *QWaylandInputDevice::keyboardFocus() const { - QtWayland::Surface *wlsurface = d->keyboardFocus(); - if (wlsurface) - return wlsurface->waylandSurface(); - return 0; + Q_D(const QWaylandInputDevice); + if (d->keyboard.isNull() || !d->keyboard->focus()) + return Q_NULLPTR; + + return d->keyboard->focus(); } +/*! + * Sets the current keyboard focus to \a surface. + */ bool QWaylandInputDevice::setKeyboardFocus(QWaylandSurface *surface) { - QtWayland::Surface *wlsurface = surface?surface->handle():0; - return d->setKeyboardFocus(wlsurface); + Q_D(QWaylandInputDevice); + if (surface && surface->isDestroyed()) + return false; + + QWaylandSurface *oldSurface = keyboardFocus(); + if (surface == oldSurface) + return true; + + QWaylandWlShellSurface *wlShellsurface = QWaylandWlShellSurface::findIn(surface); + if (wlShellsurface && wlShellsurface->focusPolicy() == QWaylandWlShellSurface::NoKeyboardFocus) + return false; + + d->keyboardFocus = surface; + if (!d->keyboard.isNull()) + d->keyboard->setFocus(surface); + if (d->data_device) + d->data_device->setFocus(surface->client()); + emit keyboardFocusChanged(surface, oldSurface); + return true; } +/*! + * Sets the key map of this QWaylandInputDevice to \a keymap. + */ void QWaylandInputDevice::setKeymap(const QWaylandKeymap &keymap) { - if (handle()->keyboardDevice()) - handle()->keyboardDevice()->setKeymap(keymap); + if (keyboard()) + keyboard()->setKeymap(keymap); } -QWaylandSurfaceView *QWaylandInputDevice::mouseFocus() const +/*! + * Returns the pointer device for this QWaylandInputDevice. + */ +QWaylandPointer *QWaylandInputDevice::pointer() const { - return d->mouseFocus(); + Q_D(const QWaylandInputDevice); + return d->pointer.data(); } -void QWaylandInputDevice::setMouseFocus(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos) +/*! + * Returns the touch device for this QWaylandInputDevice. + */ +QWaylandTouch *QWaylandInputDevice::touch() const { - d->setMouseFocus(surface,localPos,globalPos); + Q_D(const QWaylandInputDevice); + return d->touch.data(); } +/*! + * Returns the view that currently has mouse focus. + */ +QWaylandView *QWaylandInputDevice::mouseFocus() const +{ + Q_D(const QWaylandInputDevice); + return d->mouseFocus; +} + +/*! + * Sets the current mouse focus to \a view. + */ +void QWaylandInputDevice::setMouseFocus(QWaylandView *view) +{ + Q_D(QWaylandInputDevice); + if (view == d->mouseFocus) + return; + + QWaylandView *oldFocus = d->mouseFocus; + d->mouseFocus = view; + emit mouseFocusChanged(d->mouseFocus, oldFocus); +} + +/*! + * Returns the compositor for this QWaylandInputDevice. + */ QWaylandCompositor *QWaylandInputDevice::compositor() const { - return d->compositor()->waylandCompositor(); + Q_D(const QWaylandInputDevice); + return d->compositor; } -QtWayland::InputDevice *QWaylandInputDevice::handle() const +/*! + * Returns the drag object for this QWaylandInputDevice. + */ +QWaylandDrag *QWaylandInputDevice::drag() const { - return d; + Q_D(const QWaylandInputDevice); + return d->drag_handle.data(); } -QWaylandInputDevice::CapabilityFlags QWaylandInputDevice::capabilities() +/*! + * Returns the capability flags for this QWaylandInputDevice. + */ +QWaylandInputDevice::CapabilityFlags QWaylandInputDevice::capabilities() const { - return d->capabilities(); + Q_D(const QWaylandInputDevice); + return d->capabilities; } -bool QWaylandInputDevice::isOwner(QInputEvent *inputEvent) +/*! + * \internal + */ +bool QWaylandInputDevice::isOwner(QInputEvent *inputEvent) const { Q_UNUSED(inputEvent); return true; } +/*! + * Returns the QWaylandInputDevice corresponding to the \a resource. The \a resource is expected + * to have the type wl_seat. + */ +QWaylandInputDevice *QWaylandInputDevice::fromSeatResource(struct ::wl_resource *resource) +{ + return static_cast<QWaylandInputDevicePrivate *>(QWaylandInputDevicePrivate::Resource::fromResource(resource)->seat_object)->q_func(); +} + +/*! + * \fn void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus) + * + * This signal is emitted when the mouse focus has changed from \a oldFocus to \a newFocus. + */ + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandinput.h b/src/compositor/compositor_api/qwaylandinput.h index 7842fa38b..d1cb922b7 100644 --- a/src/compositor/compositor_api/qwaylandinput.h +++ b/src/compositor/compositor_api/qwaylandinput.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -45,7 +41,9 @@ #include <QtCore/QPoint> #include <QtCore/QString> -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandcompositorextension.h> +#include <QtWaylandCompositor/qwaylandkeyboard.h> QT_BEGIN_NAMESPACE @@ -53,35 +51,22 @@ class QWaylandCompositor; class QWaylandSurface; class QKeyEvent; class QTouchEvent; -class QWaylandSurfaceView; +class QWaylandView; class QInputEvent; +class QWaylandInputDevicePrivate; +class QWaylandDrag; +class QWaylandKeyboard; +class QWaylandPointer; +class QWaylandTouch; namespace QtWayland { class InputDevice; } -class Q_COMPOSITOR_EXPORT QWaylandKeymap -{ -public: - QWaylandKeymap(const QString &layout = QString(), const QString &variant = QString(), const QString &options = QString(), - const QString &model = QString(), const QString &rules = QString()); - - inline QString layout() const { return m_layout; } - inline QString variant() const { return m_variant; } - inline QString options() const { return m_options; } - inline QString rules() const { return m_rules; } - inline QString model() const { return m_model; } - -private: - QString m_layout; - QString m_variant; - QString m_options; - QString m_rules; - QString m_model; -}; - -class Q_COMPOSITOR_EXPORT QWaylandInputDevice +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandInputDevice : public QWaylandObject { + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandInputDevice) public: enum CapabilityFlag { // The order should match the enum WL_SEAT_CAPABILITY_* @@ -92,14 +77,14 @@ public: DefaultCapabilities = Pointer | Keyboard | Touch }; Q_DECLARE_FLAGS(CapabilityFlags, CapabilityFlag) + Q_ENUM(CapabilityFlags) - QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags caps = DefaultCapabilities); + QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags = DefaultCapabilities); virtual ~QWaylandInputDevice(); - void sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos = QPointF()); - void sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos = QPointF()); - void sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos = QPointF()); - void sendMouseMoveEvent(QWaylandSurfaceView *surface , const QPointF &localPos, const QPointF &globalPos = QPointF()); + void sendMousePressEvent(Qt::MouseButton button); + void sendMouseReleaseEvent(Qt::MouseButton button); + void sendMouseMoveEvent(QWaylandView *surface , const QPointF &localPos, const QPointF &outputSpacePos = QPointF()); void sendMouseWheelEvent(Qt::Orientation orientation, int delta); void sendKeyPressEvent(uint code); @@ -108,29 +93,39 @@ public: void sendFullKeyEvent(QKeyEvent *event); void sendFullKeyEvent(QWaylandSurface *surface, QKeyEvent *event); - void sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state); + void sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state); void sendTouchFrameEvent(); void sendTouchCancelEvent(); void sendFullTouchEvent(QTouchEvent *event); + QWaylandPointer *pointer() const; + //Normally set by the mouse device, + //But can be set manually for use with touch or can reset unset the current mouse focus; + QWaylandView *mouseFocus() const; + void setMouseFocus(QWaylandView *view); + + QWaylandKeyboard *keyboard() const; QWaylandSurface *keyboardFocus() const; bool setKeyboardFocus(QWaylandSurface *surface); void setKeymap(const QWaylandKeymap &keymap); - QWaylandSurfaceView *mouseFocus() const; - void setMouseFocus(QWaylandSurfaceView *surface, const QPointF &local_pos, const QPointF &global_pos = QPointF()); + QWaylandTouch *touch() const; QWaylandCompositor *compositor() const; - QtWayland::InputDevice *handle() const; - QWaylandInputDevice::CapabilityFlags capabilities(); + QWaylandDrag *drag() const; + + QWaylandInputDevice::CapabilityFlags capabilities() const; + + virtual bool isOwner(QInputEvent *inputEvent) const; - virtual bool isOwner(QInputEvent *inputEvent); + static QWaylandInputDevice *fromSeatResource(struct ::wl_resource *resource); -private: - QtWayland::InputDevice *d; - Q_DISABLE_COPY(QWaylandInputDevice) +Q_SIGNALS: + void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus); + void keyboardFocusChanged(QWaylandSurface *newFocus, QWaylandSurface *oldFocus); + void cursorSurfaceRequest(QWaylandSurface *surface, int hotspotX, int hotspotY); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandInputDevice::CapabilityFlags) diff --git a/src/compositor/compositor_api/qwaylandinput_p.h b/src/compositor/compositor_api/qwaylandinput_p.h new file mode 100644 index 000000000..5e57c43cc --- /dev/null +++ b/src/compositor/compositor_api/qwaylandinput_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDINPUT_P_H +#define QWAYLANDINPUT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <stdint.h> + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandinput.h> + +#include <QtCore/QList> +#include <QtCore/QPoint> +#include <QtCore/QScopedPointer> +#include <QtCore/private/qobject_p.h> + +#ifndef QT_NO_WAYLAND_XKB +#include <xkbcommon/xkbcommon.h> +#endif + +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> + +QT_BEGIN_NAMESPACE + +class QKeyEvent; +class QTouchEvent; +class QWaylandInputDevice; +class QWaylandDrag; +class QWaylandView; + +namespace QtWayland { + +class Compositor; +class DataDevice; +class Surface; +class DataDeviceManager; +class Pointer; +class Keyboard; +class Touch; +class InputMethod; + +} + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandInputDevicePrivate : public QObjectPrivate, public QtWaylandServer::wl_seat +{ +public: + Q_DECLARE_PUBLIC(QWaylandInputDevice) + + QWaylandInputDevicePrivate(QWaylandInputDevice *device, QWaylandCompositor *compositor); + ~QWaylandInputDevicePrivate(); + + void clientRequestedDataDevice(QtWayland::DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id); + void setCapabilities(QWaylandInputDevice::CapabilityFlags caps); + + static QWaylandInputDevicePrivate *get(QWaylandInputDevice *device) { return device->d_func(); } + + QtWayland::DataDevice *dataDevice() const { return data_device.data(); } + +protected: + void seat_bind_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE; + + void seat_get_pointer(wl_seat::Resource *resource, + uint32_t id) Q_DECL_OVERRIDE; + void seat_get_keyboard(wl_seat::Resource *resource, + uint32_t id) Q_DECL_OVERRIDE; + void seat_get_touch(wl_seat::Resource *resource, + uint32_t id) Q_DECL_OVERRIDE; + + void seat_destroy_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE; + +private: + QWaylandCompositor *compositor; + QWaylandView *mouseFocus; + QWaylandSurface *keyboardFocus; + QWaylandInputDevice::CapabilityFlags capabilities; + + QScopedPointer<QWaylandPointer> pointer; + QScopedPointer<QWaylandKeyboard> keyboard; + QScopedPointer<QWaylandTouch> touch; + QScopedPointer<QtWayland::DataDevice> data_device; + QScopedPointer<QWaylandDrag> drag_handle; + +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDINPUT_P_H diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp b/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp new file mode 100644 index 000000000..122c589da --- /dev/null +++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandinputmethodcontrol.h" +#include "qwaylandinputmethodcontrol_p.h" + +#include "qwaylandcompositor.h" +#include "qwaylandinput.h" +#include "qwaylandsurface.h" +#include "qwaylandview.h" +#include "qwaylandtextinput.h" + +#include <QtGui/QInputMethodEvent> + +QWaylandInputMethodControl::QWaylandInputMethodControl(QWaylandSurface *surface) + : QObject(*new QWaylandInputMethodControlPrivate(surface), surface) +{ + connect(d_func()->compositor, &QWaylandCompositor::defaultInputDeviceChanged, + this, &QWaylandInputMethodControl::defaultInputDeviceChanged); + QWaylandTextInput *textInput = d_func()->textInput(); + if (textInput) { + connect(textInput, &QWaylandTextInput::surfaceEnabled, this, &QWaylandInputMethodControl::surfaceEnabled); + connect(textInput, &QWaylandTextInput::surfaceDisabled, this, &QWaylandInputMethodControl::surfaceDisabled); +#ifndef QT_NO_IM + connect(textInput, &QWaylandTextInput::updateInputMethod, this, &QWaylandInputMethodControl::updateInputMethod); +#endif + } +} + +QVariant QWaylandInputMethodControl::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const +{ + Q_D(const QWaylandInputMethodControl); + + QWaylandTextInput *textInput = d->textInput(); + + if (textInput && textInput->focus() == d->surface) { + return textInput->inputMethodQuery(query, argument); + } + + return QVariant(); +} + +void QWaylandInputMethodControl::inputMethodEvent(QInputMethodEvent *event) +{ + Q_D(QWaylandInputMethodControl); + + QWaylandTextInput *textInput = d->textInput(); + if (textInput) { + textInput->sendInputMethodEvent(event); + } else { + event->ignore(); + } +} + +bool QWaylandInputMethodControl::enabled() const +{ + Q_D(const QWaylandInputMethodControl); + + return d->enabled; +} + +void QWaylandInputMethodControl::setEnabled(bool enabled) +{ + Q_D(QWaylandInputMethodControl); + + if (d->enabled == enabled) + return; + + d->enabled = enabled; + emit enabledChanged(enabled); +#ifndef QT_NO_IM + emit updateInputMethod(Qt::ImQueryInput); +#endif +} + +void QWaylandInputMethodControl::surfaceEnabled(QWaylandSurface *surface) +{ + Q_D(QWaylandInputMethodControl); + + if (surface == d->surface) + setEnabled(true); +} + +void QWaylandInputMethodControl::surfaceDisabled(QWaylandSurface *surface) +{ + Q_D(QWaylandInputMethodControl); + + if (surface == d->surface) + setEnabled(false); +} + +void QWaylandInputMethodControl::setSurface(QWaylandSurface *surface) +{ + Q_D(QWaylandInputMethodControl); + + if (d->surface == surface) + return; + + d->surface = surface; + + QWaylandTextInput *textInput = d->textInput(); + setEnabled(textInput && textInput->isSurfaceEnabled(d->surface)); +} + +void QWaylandInputMethodControl::defaultInputDeviceChanged() +{ + Q_D(QWaylandInputMethodControl); + + disconnect(d->textInput(), 0, this, 0); + + d->inputDevice = d->compositor->defaultInputDevice(); + QWaylandTextInput *textInput = d->textInput(); + + connect(textInput, &QWaylandTextInput::surfaceEnabled, this, &QWaylandInputMethodControl::surfaceEnabled); + connect(textInput, &QWaylandTextInput::surfaceDisabled, this, &QWaylandInputMethodControl::surfaceDisabled); + + setEnabled(textInput && textInput->isSurfaceEnabled(d->surface)); +} + +QWaylandInputMethodControlPrivate::QWaylandInputMethodControlPrivate(QWaylandSurface *surface) + : QObjectPrivate() + , compositor(surface->compositor()) + , inputDevice(compositor->defaultInputDevice()) + , surface(surface) + , enabled(false) +{ +} + +QWaylandTextInput *QWaylandInputMethodControlPrivate::textInput() const +{ + return QWaylandTextInput::findIn(inputDevice); +} diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol.h b/src/compositor/compositor_api/qwaylandinputmethodcontrol.h new file mode 100644 index 000000000..f71650294 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDINPUTMETHODCONTROL_H +#define QWAYLANDINPUTMETHODCONTROL_H + +#include <QObject> + +QT_BEGIN_NAMESPACE + +class QWaylandCompositor; +class QWaylandInputMethodControlPrivate; +class QWaylandSurface; +class QInputMethodEvent; + +class QWaylandInputMethodControl : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandInputMethodControl) + Q_DISABLE_COPY(QWaylandInputMethodControl) + + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) +public: + explicit QWaylandInputMethodControl(QWaylandSurface *surface); + +#ifndef QT_NO_IM + QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const; +#endif + + void inputMethodEvent(QInputMethodEvent *event); + + bool enabled() const; + void setEnabled(bool enabled); + + void setSurface(QWaylandSurface *surface); + +Q_SIGNALS: + void enabledChanged(bool enabled); +#ifndef QT_NO_IM + void updateInputMethod(Qt::InputMethodQueries queries); +#endif + +private: + void defaultInputDeviceChanged(); + void surfaceEnabled(QWaylandSurface *surface); + void surfaceDisabled(QWaylandSurface *surface); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDINPUTMETHODCONTROL_H diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h b/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h new file mode 100644 index 000000000..a687e5299 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDINPUTMETHODCONTROL_P_H +#define QWAYLANDINPUTMETHODCONTROL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandinputmethodcontrol.h> + +#include <QtCore/private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +class QWaylandCompositor; +class QWaylandInputDevice; +class QWaylandSurface; +class QWaylandTextInput; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandInputMethodControlPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QWaylandInputMethodControl) + +public: + explicit QWaylandInputMethodControlPrivate(QWaylandSurface *surface); + + QWaylandTextInput *textInput() const; + + QWaylandCompositor *compositor; + QWaylandInputDevice *inputDevice; + QWaylandSurface *surface; + bool enabled; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDINPUTMETHODCONTROL_P_H diff --git a/src/compositor/compositor_api/qwaylandinputpanel.cpp b/src/compositor/compositor_api/qwaylandinputpanel.cpp deleted file mode 100644 index db4cd3296..000000000 --- a/src/compositor/compositor_api/qwaylandinputpanel.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandinputpanel.h" - -#include <private/qobject_p.h> - -#include "qwlinputpanel_p.h" -#include "qwlsurface_p.h" - -QT_BEGIN_NAMESPACE - -class QWaylandInputPanelPrivate : public QObjectPrivate -{ -public: - QWaylandInputPanelPrivate(QtWayland::InputPanel *panel) - : inputPanel(panel) - { - } - - QtWayland::InputPanel *inputPanel; -}; - - -QWaylandInputPanel::QWaylandInputPanel(QtWayland::InputPanel *inputPanel) - : QObject(*new QWaylandInputPanelPrivate(inputPanel)) -{ -} - -QtWayland::InputPanel *QWaylandInputPanel::handle() const -{ - Q_D(const QWaylandInputPanel); - - return d->inputPanel; -} - -QWaylandSurface *QWaylandInputPanel::focus() const -{ - Q_D(const QWaylandInputPanel); - - QtWayland::Surface *surface = d->inputPanel->focus(); - if (surface) - return surface->waylandSurface(); - return 0; -} - -bool QWaylandInputPanel::visible() const -{ - Q_D(const QWaylandInputPanel); - - return d->inputPanel->inputPanelVisible(); -} - -QRect QWaylandInputPanel::cursorRectangle() const -{ - Q_D(const QWaylandInputPanel); - - return d->inputPanel->cursorRectangle(); -} - -QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandinputpanel.h b/src/compositor/compositor_api/qwaylandinputpanel.h deleted file mode 100644 index 22dc8b9f4..000000000 --- a/src/compositor/compositor_api/qwaylandinputpanel.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDINPUTPANEL_H -#define QWAYLANDINPUTPANEL_H - -#include <QtCompositor/qwaylandexport.h> - -#include <QObject> -#include <QRect> - -QT_BEGIN_NAMESPACE - -class QWaylandCompositor; -class QWaylandInputPanelPrivate; -class QWaylandSurface; - -namespace QtWayland { -class InputPanel; -} - -class Q_COMPOSITOR_EXPORT QWaylandInputPanel : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QWaylandInputPanel) - - Q_PROPERTY(QWaylandSurface* focus READ focus NOTIFY focusChanged) - Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged) - Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) - -public: - explicit QWaylandInputPanel(QtWayland::InputPanel *inputPanel); - - QtWayland::InputPanel *handle() const; - - QWaylandSurface *focus() const; - bool visible() const; - QRect cursorRectangle() const; - -Q_SIGNALS: - void focusChanged(); - void visibleChanged(); - void cursorRectangleChanged(); -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDINPUTPANEL_H diff --git a/src/compositor/compositor_api/qwaylandkeyboard.cpp b/src/compositor/compositor_api/qwaylandkeyboard.cpp new file mode 100644 index 000000000..e6ba64ed5 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp @@ -0,0 +1,566 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandkeyboard.h" +#include "qwaylandkeyboard_p.h" +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandClient> + +#include <QtCore/QFile> +#include <QtCore/QStandardPaths> + +#include <fcntl.h> +#include <unistd.h> +#ifndef QT_NO_WAYLAND_XKB +#include <sys/mman.h> +#include <sys/types.h> +#endif + +QT_BEGIN_NAMESPACE + +QWaylandKeyboardPrivate::QWaylandKeyboardPrivate(QWaylandInputDevice *seat) + : QtWaylandServer::wl_keyboard() + , seat(seat) + , focus() + , focusResource() + , keys() + , modsDepressed() + , modsLatched() + , modsLocked() + , group() + , pendingKeymap(false) +#ifndef QT_NO_WAYLAND_XKB + , keymap_fd(-1) + , xkb_state(0) +#endif + , repeatRate(40) + , repeatDelay(400) +{ +#ifndef QT_NO_WAYLAND_XKB + initXKB(); +#endif +} + +QWaylandKeyboardPrivate::~QWaylandKeyboardPrivate() +{ +#ifndef QT_NO_WAYLAND_XKB + if (xkb_context) { + if (keymap_area) + munmap(keymap_area, keymap_size); + close(keymap_fd); + xkb_context_unref(xkb_context); + xkb_state_unref(xkb_state); + } +#endif +} + +QWaylandKeyboardPrivate *QWaylandKeyboardPrivate::get(QWaylandKeyboard *keyboard) +{ + return keyboard->d_func(); +} + +void QWaylandKeyboardPrivate::checkFocusResource(Resource *keyboardResource) +{ + if (!keyboardResource || !focus) + return; + + // this is already the current resource, do no send enter twice + if (focusResource == keyboardResource) + return; + + // check if new wl_keyboard resource is from the client owning the focus surface + if (focus->resource()->client == keyboardResource->client()) { + sendEnter(focus, keyboardResource); + focusResource = keyboardResource; + } +} + +void QWaylandKeyboardPrivate::sendEnter(QWaylandSurface *surface, Resource *keyboardResource) +{ + uint32_t serial = compositor()->nextSerial(); + send_modifiers(keyboardResource->handle, serial, modsDepressed, modsLatched, modsLocked, group); + send_enter(keyboardResource->handle, serial, surface->resource(), QByteArray::fromRawData((char *)keys.data(), keys.size() * sizeof(uint32_t))); +} + +void QWaylandKeyboardPrivate::focused(QWaylandSurface *surface) +{ + if (surface && surface->isCursorSurface()) + surface = Q_NULLPTR; + if (focus != surface) { + if (focusResource) { + uint32_t serial = compositor()->nextSerial(); + send_leave(focusResource->handle, serial, focus->resource()); + } + focusDestroyListener.reset(); + if (surface) + focusDestroyListener.listenForDestruction(surface->resource()); + } + + Resource *resource = surface ? resourceMap().value(surface->waylandClient()) : 0; + + if (resource && (focus != surface || focusResource != resource)) + sendEnter(surface, resource); + + focusResource = resource; + focus = surface; + Q_EMIT q_func()->focusChanged(focus); +} + + +void QWaylandKeyboardPrivate::keyboard_bind_resource(wl_keyboard::Resource *resource) +{ + // Send repeat information + if (resource->version() >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) + send_repeat_info(resource->handle, repeatRate, repeatDelay); + +#ifndef QT_NO_WAYLAND_XKB + if (xkb_context) { + send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, + keymap_fd, keymap_size); + } else +#endif + { + int null_fd = open("/dev/null", O_RDONLY); + send_keymap(resource->handle, 0 /* WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP */, + null_fd, 0); + close(null_fd); + } + checkFocusResource(resource); +} + +void QWaylandKeyboardPrivate::keyboard_destroy_resource(wl_keyboard::Resource *resource) +{ + if (focusResource == resource) + focusResource = 0; +} + +void QWaylandKeyboardPrivate::keyboard_release(wl_keyboard::Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void QWaylandKeyboardPrivate::keyEvent(uint code, uint32_t state) +{ + uint key = toWaylandXkbV1Key(code); + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { + keys << key; + } else { + keys.removeAll(key); + } +} + +void QWaylandKeyboardPrivate::sendKeyEvent(uint code, uint32_t state) +{ + uint32_t time = compositor()->currentTimeMsecs(); + uint32_t serial = compositor()->nextSerial(); + uint key = toWaylandXkbV1Key(code); + if (focusResource) + send_key(focusResource->handle, serial, time, key, state); +} + +void QWaylandKeyboardPrivate::modifiers(uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, uint32_t group) +{ + if (focusResource) { + send_modifiers(focusResource->handle, serial, mods_depressed, mods_latched, mods_locked, group); + } +} + +void QWaylandKeyboardPrivate::updateModifierState(uint code, uint32_t state) +{ +#ifndef QT_NO_WAYLAND_XKB + if (!xkb_context) + return; + + xkb_state_update_key(xkb_state, code, state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); + + uint32_t modsDepressed = xkb_state_serialize_mods(xkb_state, (xkb_state_component)XKB_STATE_DEPRESSED); + uint32_t modsLatched = xkb_state_serialize_mods(xkb_state, (xkb_state_component)XKB_STATE_LATCHED); + uint32_t modsLocked = xkb_state_serialize_mods(xkb_state, (xkb_state_component)XKB_STATE_LOCKED); + uint32_t group = xkb_state_serialize_group(xkb_state, (xkb_state_component)XKB_STATE_EFFECTIVE); + + if (this->modsDepressed == modsDepressed + && this->modsLatched == modsLatched + && this->modsLocked == modsLocked + && this->group == group) + return; + + this->modsDepressed = modsDepressed; + this->modsLatched = modsLatched; + this->modsLocked = modsLocked; + this->group = group; + + modifiers(compositor()->nextSerial(), modsDepressed, modsLatched, modsLocked, group); +#else + Q_UNUSED(code); + Q_UNUSED(state); +#endif +} + +void QWaylandKeyboardPrivate::updateKeymap() +{ + // There must be no keys pressed when changing the keymap, + // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html + if (!pendingKeymap || !keys.isEmpty()) + return; + + pendingKeymap = false; +#ifndef QT_NO_WAYLAND_XKB + if (!xkb_context) + return; + + createXKBKeymap(); + foreach (Resource *res, resourceMap()) { + send_keymap(res->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymap_fd, keymap_size); + } + + xkb_state_update_mask(xkb_state, 0, modsLatched, modsLocked, 0, 0, 0); + if (focusResource) + send_modifiers(focusResource->handle, + compositor()->nextSerial(), + modsDepressed, + modsLatched, + modsLocked, + group); +#endif +} + +#ifndef QT_NO_WAYLAND_XKB +static int createAnonymousFile(size_t size) +{ + QString path = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); + if (path.isEmpty()) + return -1; + + QByteArray name = QFile::encodeName(path + QStringLiteral("/qtwayland-XXXXXX")); + + int fd = mkstemp(name.data()); + if (fd < 0) + return -1; + + long flags = fcntl(fd, F_GETFD); + if (flags == -1 || fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { + close(fd); + fd = -1; + } + unlink(name.constData()); + + if (fd < 0) + return -1; + + if (ftruncate(fd, size) < 0) { + close(fd); + return -1; + } + + return fd; +} + +void QWaylandKeyboardPrivate::initXKB() +{ + xkb_context = xkb_context_new(static_cast<xkb_context_flags>(0)); + if (!xkb_context) { + qWarning("Failed to create a XKB context: keymap will not be supported"); + return; + } + + createXKBKeymap(); +} + + +void QWaylandKeyboardPrivate::createXKBState(xkb_keymap *keymap) +{ + char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1); + if (!keymap_str) { + qWarning("Failed to compile global XKB keymap"); + return; + } + + keymap_size = strlen(keymap_str) + 1; + if (keymap_fd >= 0) + close(keymap_fd); + keymap_fd = createAnonymousFile(keymap_size); + if (keymap_fd < 0) { + qWarning("Failed to create anonymous file of size %lu", static_cast<unsigned long>(keymap_size)); + return; + } + + keymap_area = static_cast<char *>(mmap(0, keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, keymap_fd, 0)); + if (keymap_area == MAP_FAILED) { + close(keymap_fd); + keymap_fd = -1; + qWarning("Failed to map shared memory segment"); + return; + } + + strcpy(keymap_area, keymap_str); + free(keymap_str); + + if (xkb_state) + xkb_state_unref(xkb_state); + xkb_state = xkb_state_new(keymap); +} + +uint QWaylandKeyboardPrivate::toWaylandXkbV1Key(const uint nativeScanCode) +{ + const uint offset = 8; + Q_ASSERT(nativeScanCode >= offset); + return nativeScanCode - offset; +} + +void QWaylandKeyboardPrivate::createXKBKeymap() +{ + if (!xkb_context) + return; + + struct xkb_rule_names rule_names = { strdup(qPrintable(keymap.rules())), + strdup(qPrintable(keymap.model())), + strdup(qPrintable(keymap.layout())), + strdup(qPrintable(keymap.variant())), + strdup(qPrintable(keymap.options())) }; + struct xkb_keymap *keymap = xkb_keymap_new_from_names(xkb_context, &rule_names, static_cast<xkb_keymap_compile_flags>(0)); + + if (keymap) { + createXKBState(keymap); + xkb_keymap_unref(keymap); + } else { + qWarning("Failed to load the '%s' XKB keymap.", qPrintable(this->keymap.layout())); + } + + free((char *)rule_names.rules); + free((char *)rule_names.model); + free((char *)rule_names.layout); + free((char *)rule_names.variant); + free((char *)rule_names.options); +} +#endif + +void QWaylandKeyboardPrivate::sendRepeatInfo() +{ + Q_FOREACH (Resource *resource, resourceMap()) { + if (resource->version() >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) + send_repeat_info(resource->handle, repeatRate, repeatDelay); + } +} + +/*! + * \class QWaylandKeyboard + * \inmodule QtWaylandCompositor + * \preliminary + * \brief The QWaylandKeyboard class provides access to a keyboard device. + * + * This class provides access to the keyboard device in a QWaylandInputDevice. It corresponds to + * the Wayland interface wl_keyboard. + */ + +/*! + * Constructs a QWaylandKeyboard for the given \a inputDevice and with the given \a parent. + */ +QWaylandKeyboard::QWaylandKeyboard(QWaylandInputDevice *inputDevice, QObject *parent) + : QWaylandObject(* new QWaylandKeyboardPrivate(inputDevice), parent) +{ + Q_D(QWaylandKeyboard); + connect(&d->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandKeyboard::focusDestroyed); +} + +/*! + * Returns the input device for this QWaylandKeyboard. + */ +QWaylandInputDevice *QWaylandKeyboard::inputDevice() const +{ + Q_D(const QWaylandKeyboard); + return d->seat; +} + +/*! + * Returns the compositor for this QWaylandKeyboard. + */ +QWaylandCompositor *QWaylandKeyboard::compositor() const +{ + Q_D(const QWaylandKeyboard); + return d->seat->compositor(); +} + +/*! + * \internal + */ +void QWaylandKeyboard::focusDestroyed(void *data) +{ + Q_UNUSED(data); + Q_D(QWaylandKeyboard); + d->focusDestroyListener.reset(); + + d->focus = 0; + d->focusResource = 0; +} + +/*! + * Returns the client that currently has keyboard focus. + */ +QWaylandClient *QWaylandKeyboard::focusClient() const +{ + Q_D(const QWaylandKeyboard); + if (!d->focusResource) + return Q_NULLPTR; + return QWaylandClient::fromWlClient(compositor(), d->focusResource->client()); +} + +/*! + * Sends the current key modifiers to \a client with the given \a serial. + */ +void QWaylandKeyboard::sendKeyModifiers(QWaylandClient *client, uint serial) +{ + Q_D(QWaylandKeyboard); + QtWaylandServer::wl_keyboard::Resource *resource = d->resourceMap().value(client->client()); + if (resource) + d->send_modifiers(resource->handle, serial, d->modsDepressed, d->modsLatched, d->modsLocked, d->group); +} + +/*! + * Sends a key press event with the key \a code to the current keyboard focus. + */ +void QWaylandKeyboard::sendKeyPressEvent(uint code) +{ + Q_D(QWaylandKeyboard); + d->sendKeyEvent(code, WL_KEYBOARD_KEY_STATE_PRESSED); +} + +/*! + * Sends a key release event with the key \a code to the current keyboard focus. + */ +void QWaylandKeyboard::sendKeyReleaseEvent(uint code) +{ + Q_D(QWaylandKeyboard); + d->sendKeyEvent(code, WL_KEYBOARD_KEY_STATE_RELEASED); +} + +/*! + * Returns the current repeat rate. + */ +quint32 QWaylandKeyboard::repeatRate() const +{ + Q_D(const QWaylandKeyboard); + return d->repeatRate; +} + +/*! + * Sets the repeat rate to \a rate. + */ +void QWaylandKeyboard::setRepeatRate(quint32 rate) +{ + Q_D(QWaylandKeyboard); + + if (d->repeatRate == rate) + return; + + d->sendRepeatInfo(); + + d->repeatRate = rate; + Q_EMIT repeatRateChanged(rate); +} + +/*! + * Returns the current repeat delay. + */ +quint32 QWaylandKeyboard::repeatDelay() const +{ + Q_D(const QWaylandKeyboard); + return d->repeatDelay; +} + +/*! + * Sets the repeat delay to \a delay. + */ +void QWaylandKeyboard::setRepeatDelay(quint32 delay) +{ + Q_D(QWaylandKeyboard); + + if (d->repeatDelay == delay) + return; + + d->sendRepeatInfo(); + + d->repeatDelay = delay; + Q_EMIT repeatDelayChanged(delay); +} + +/*! + * Returns the currently focused surface. + */ +QWaylandSurface *QWaylandKeyboard::focus() const +{ + Q_D(const QWaylandKeyboard); + return d->focus; +} + +/*! + * Sets the current focus to \a surface. + */ +void QWaylandKeyboard::setFocus(QWaylandSurface *surface) +{ + Q_D(QWaylandKeyboard); + d->focused(surface); +} + +/*! + * Sets the keyboard's keymap to \a keymap. + */ +void QWaylandKeyboard::setKeymap(const QWaylandKeymap &keymap) +{ + Q_D(QWaylandKeyboard); + d->keymap = keymap; + d->pendingKeymap = true; + + // If there is no key currently pressed, update right away the keymap + // Otherwise, delay the update when keys are released + // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html + if (d->keys.isEmpty()) { + d->updateKeymap(); + } +} + +/*! + * \internal + */ +void QWaylandKeyboard::addClient(QWaylandClient *client, uint32_t id, uint32_t version) +{ + Q_D(QWaylandKeyboard); + d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_keyboard::interfaceVersion(), version)); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandkeyboard.h b/src/compositor/compositor_api/qwaylandkeyboard.h new file mode 100644 index 000000000..b5bf6fe5c --- /dev/null +++ b/src/compositor/compositor_api/qwaylandkeyboard.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDKEYBOARD_H +#define QWAYLANDKEYBOARD_H + +#include <QtCore/QObject> + +#include <QtWaylandCompositor/QWaylandCompositorExtension> +#include <QtWaylandCompositor/QWaylandSurface> + +QT_BEGIN_NAMESPACE + +class QWaylandKeyboard; +class QWaylandKeyboardPrivate; +class QWaylandInputDevice; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeymap +{ +public: + QWaylandKeymap(const QString &layout = QString(), const QString &variant = QString(), const QString &options = QString(), + const QString &model = QString(), const QString &rules = QString()); + + inline QString layout() const { return m_layout; } + inline QString variant() const { return m_variant; } + inline QString options() const { return m_options; } + inline QString rules() const { return m_rules; } + inline QString model() const { return m_model; } + +private: + QString m_layout; + QString m_variant; + QString m_options; + QString m_rules; + QString m_model; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeyboard : public QWaylandObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandKeyboard) + Q_PROPERTY(quint32 repeatRate READ repeatRate WRITE setRepeatRate NOTIFY repeatRateChanged) + Q_PROPERTY(quint32 repeatDelay READ repeatDelay WRITE setRepeatDelay NOTIFY repeatDelayChanged) +public: + QWaylandKeyboard(QWaylandInputDevice *inputDevice, QObject *parent = nullptr); + + QWaylandInputDevice *inputDevice() const; + QWaylandCompositor *compositor() const; + + quint32 repeatRate() const; + void setRepeatRate(quint32 rate); + + quint32 repeatDelay() const; + void setRepeatDelay(quint32 delay); + + virtual void setFocus(QWaylandSurface *surface); + virtual void setKeymap(const QWaylandKeymap &keymap); + + virtual void sendKeyModifiers(QWaylandClient *client, uint32_t serial); + virtual void sendKeyPressEvent(uint code); + virtual void sendKeyReleaseEvent(uint code); + + QWaylandSurface *focus() const; + QWaylandClient *focusClient() const; + + virtual void addClient(QWaylandClient *client, uint32_t id, uint32_t version); + +Q_SIGNALS: + void focusChanged(QWaylandSurface *surface); + void repeatRateChanged(quint32 repeatRate); + void repeatDelayChanged(quint32 repeatDelay); + +private: + void focusDestroyed(void *data); +}; + +QT_END_NAMESPACE + +#endif //QWAYLANDKEYBOARD_H diff --git a/src/compositor/compositor_api/qwaylandkeyboard_p.h b/src/compositor/compositor_api/qwaylandkeyboard_p.h new file mode 100644 index 000000000..ede97d8ba --- /dev/null +++ b/src/compositor/compositor_api/qwaylandkeyboard_p.h @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWAYLAND_QWLKEYBOARD_P_H +#define QTWAYLAND_QWLKEYBOARD_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandinput.h> +#include <QtWaylandCompositor/qwaylandkeyboard.h> +#include <QtWaylandCompositor/qwaylanddestroylistener.h> + +#include <QtCore/private/qobject_p.h> +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> + +#include <QtCore/QVector> + +#ifndef QT_NO_WAYLAND_XKB +#include <xkbcommon/xkbcommon.h> +#endif + + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeyboardPrivate : public QObjectPrivate + , public QtWaylandServer::wl_keyboard +{ +public: + Q_DECLARE_PUBLIC(QWaylandKeyboard) + + static QWaylandKeyboardPrivate *get(QWaylandKeyboard *keyboard); + + QWaylandKeyboardPrivate(QWaylandInputDevice *seat); + ~QWaylandKeyboardPrivate(); + + QWaylandCompositor *compositor() const { return seat->compositor(); } + + void focused(QWaylandSurface* surface); + void modifiers(uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, uint32_t group); + +#ifndef QT_NO_WAYLAND_XKB + struct xkb_state *xkbState() const { return xkb_state; } + uint32_t xkbModsMask() const { return modsDepressed | modsLatched | modsLocked; } +#endif + + void keyEvent(uint code, uint32_t state); + void sendKeyEvent(uint code, uint32_t state); + void updateModifierState(uint code, uint32_t state); + void updateKeymap(); + + void checkFocusResource(Resource *resource); + void sendEnter(QWaylandSurface *surface, Resource *resource); + +protected: + void keyboard_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void keyboard_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void keyboard_release(Resource *resource) Q_DECL_OVERRIDE; + +private: +#ifndef QT_NO_WAYLAND_XKB + void initXKB(); + void createXKBKeymap(); + void createXKBState(xkb_keymap *keymap); +#endif + static uint toWaylandXkbV1Key(const uint nativeScanCode); + + void sendRepeatInfo(); + + QWaylandInputDevice *seat; + + QWaylandSurface *focus; + Resource *focusResource; + QWaylandDestroyListener focusDestroyListener; + + QVector<uint32_t> keys; + uint32_t modsDepressed; + uint32_t modsLatched; + uint32_t modsLocked; + uint32_t group; + + QWaylandKeymap keymap; + bool pendingKeymap; +#ifndef QT_NO_WAYLAND_XKB + size_t keymap_size; + int keymap_fd; + char *keymap_area; + struct xkb_context *xkb_context; + struct xkb_state *xkb_state; +#endif + + quint32 repeatRate; + quint32 repeatDelay; +}; + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLKEYBOARD_P_H diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp index ba9f39887..65bac3352 100644 --- a/src/compositor/compositor_api/qwaylandoutput.cpp +++ b/src/compositor/compositor_api/qwaylandoutput.cpp @@ -4,254 +4,929 @@ ** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ +#include "qwaylandoutput.h" +#include "qwaylandoutput_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandView> + +#include <QtWaylandCompositor/private/qwaylandsurface_p.h> +#include <QtWaylandCompositor/private/qwaylandcompositor_p.h> + #include <QtCore/QCoreApplication> #include <QtCore/QtMath> #include <QtGui/QWindow> #include <QtGui/QExposeEvent> #include <private/qobject_p.h> -#include "wayland_wrapper/qwlcompositor_p.h" -#include "wayland_wrapper/qwloutput_p.h" -#include "qwaylandcompositor.h" -#include "qwaylandoutput.h" -#include "qwaylandsurface.h" +QT_BEGIN_NAMESPACE + +static QtWaylandServer::wl_output::subpixel toWlSubpixel(const QWaylandOutput::Subpixel &value) +{ + switch (value) { + case QWaylandOutput::SubpixelUnknown: + return QtWaylandServer::wl_output::subpixel_unknown; + case QWaylandOutput::SubpixelNone: + return QtWaylandServer::wl_output::subpixel_none; + case QWaylandOutput::SubpixelHorizontalRgb: + return QtWaylandServer::wl_output::subpixel_horizontal_rgb; + case QWaylandOutput::SubpixelHorizontalBgr: + return QtWaylandServer::wl_output::subpixel_horizontal_bgr; + case QWaylandOutput::SubpixelVerticalRgb: + return QtWaylandServer::wl_output::subpixel_vertical_rgb; + case QWaylandOutput::SubpixelVerticalBgr: + return QtWaylandServer::wl_output::subpixel_vertical_bgr; + default: + break; + } + + return QtWaylandServer::wl_output::subpixel_unknown; +} + +static QtWaylandServer::wl_output::transform toWlTransform(const QWaylandOutput::Transform &value) +{ + switch (value) { + case QWaylandOutput::Transform90: + return QtWaylandServer::wl_output::transform_90; + case QWaylandOutput::Transform180: + return QtWaylandServer::wl_output::transform_180; + case QWaylandOutput::Transform270: + return QtWaylandServer::wl_output::transform_270; + case QWaylandOutput::TransformFlipped: + return QtWaylandServer::wl_output::transform_flipped; + case QWaylandOutput::TransformFlipped90: + return QtWaylandServer::wl_output::transform_flipped_90; + case QWaylandOutput::TransformFlipped180: + return QtWaylandServer::wl_output::transform_flipped_180; + case QWaylandOutput::TransformFlipped270: + return QtWaylandServer::wl_output::transform_flipped_270; + default: + break; + } + + return QtWaylandServer::wl_output::transform_normal; +} + +QWaylandOutputPrivate::QWaylandOutputPrivate() + : QtWaylandServer::wl_output() + , compositor(Q_NULLPTR) + , window(Q_NULLPTR) + , subpixel(QWaylandOutput::SubpixelUnknown) + , transform(QWaylandOutput::TransformNormal) + , scaleFactor(1) + , sizeFollowsWindow(true) + , initialized(false) +{ + mode.size = QSize(); + mode.refreshRate = 60; + + qRegisterMetaType<QWaylandOutput::Mode>("WaylandOutput::Mode"); +} + +QWaylandOutputPrivate::~QWaylandOutputPrivate() +{ +} + +void QWaylandOutputPrivate::output_bind_resource(Resource *resource) +{ + send_geometry(resource->handle, + position.x(), position.y(), + physicalSize.width(), physicalSize.height(), + toWlSubpixel(subpixel), manufacturer, model, + toWlTransform(transform)); + + send_mode(resource->handle, mode_current | mode_preferred, + mode.size.width(), mode.size.height(), + mode.refreshRate * 1000); + + if (resource->version() >= 2) { + send_scale(resource->handle, scaleFactor); + send_done(resource->handle); + } +} + +void QWaylandOutputPrivate::sendGeometryInfo() +{ + Q_FOREACH (Resource *resource, resourceMap().values()) { + send_geometry(resource->handle, + position.x(), position.y(), + physicalSize.width(), physicalSize.height(), + toWlSubpixel(subpixel), manufacturer, model, + toWlTransform(transform)); + if (resource->version() >= 2) + send_done(resource->handle); + } +} + + +void QWaylandOutputPrivate::addView(QWaylandView *view, QWaylandSurface *surface) +{ + for (int i = 0; i < surfaceViews.size(); i++) { + if (surface == surfaceViews.at(i).surface) { + if (!surfaceViews.at(i).views.contains(view)) { + surfaceViews[i].views.append(view); + } + return; + } + } + + surfaceViews.append(QWaylandSurfaceViewMapper(surface,view)); +} + +void QWaylandOutputPrivate::removeView(QWaylandView *view, QWaylandSurface *surface) +{ + Q_Q(QWaylandOutput); + for (int i = 0; i < surfaceViews.size(); i++) { + if (surface == surfaceViews.at(i).surface) { + bool removed = surfaceViews[i].views.removeOne(view); + if (surfaceViews.at(i).views.isEmpty() && removed) { + if (surfaceViews.at(i).has_entered) + q->surfaceLeave(surface); + surfaceViews.remove(i); + } + return; + } + } + qWarning("%s Could not find view %p for surface %p to remove. Possible invalid state", Q_FUNC_INFO, view, surface); +} -QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window, - const QString &manufacturer, const QString &model) - : QObject() - , d_ptr(new QtWayland::Output(compositor->handle(), window)) +QWaylandOutput::QWaylandOutput() + : QWaylandObject(*new QWaylandOutputPrivate()) { - d_ptr->m_output = this; - d_ptr->setManufacturer(manufacturer); - d_ptr->setModel(model); - d_ptr->compositor()->addOutput(this); } +/*! + \qmltype WaylandOutput + \inqmlmodule QtWayland.Compositor + \preliminary + \brief Type providing access to a displayable area managed by the compositor. + + The WaylandOutput manages a rectangular part of the compositor's geometry that + can be used for displaying client content. This could, for instance, be a screen + managed by the WaylandCompositor. + + The type corresponds to the wl_output interface in the Wayland protocol. +*/ + +/*! + \class QWaylandOutput + \inmodule QtWaylandCompositor + \preliminary + \brief The QWaylandOutput class provides access to a displayable area managed by the compositor. + + The QWaylandOutput manages a rectangular part of the compositor's geometry that + can be used for displaying client content. This could, for instance, be a screen + managed by the QWaylandCompositor. + + The class corresponds to the wl_output interface in the Wayland protocol. +*/ + +/*! + * Constructs a QWaylandOutput in \a compositor and with the specified \a window. The + * \l{QWaylandCompositor::create()}{create()} function must have been called on the + * \a compositor before a QWaylandOutput is constructed for it. + * + * The QWaylandOutput object is initialized later, in reaction to an event. + * At this point it is added as an output for the \a compositor. If it is the + * first QWaylandOutput object created for this \a compositor, it becomes the + * \l{QWaylandCompositor::defaultOutput()}{default output}. + */ +QWaylandOutput::QWaylandOutput(QWaylandCompositor *compositor, QWindow *window) + : QWaylandObject(*new QWaylandOutputPrivate()) +{ + Q_D(QWaylandOutput); + d->compositor = compositor; + d->window = window; + QWaylandCompositorPrivate::get(compositor)->addPolishObject(this); +} + +/*! + * Destroys the QWaylandOutput. + */ QWaylandOutput::~QWaylandOutput() { - d_ptr->compositor()->removeOutput(this); - delete d_ptr; + Q_D(QWaylandOutput); + if (d->compositor) + QWaylandCompositorPrivate::get(d->compositor)->removeOutput(this); +} + +/*! + * \internal + */ +void QWaylandOutput::initialize() +{ + Q_D(QWaylandOutput); + + Q_ASSERT(!d->initialized); + Q_ASSERT(d->compositor); + Q_ASSERT(d->compositor->isCreated()); + + if (d->window) + d->mode.size = d->window->size(); + else + d->sizeFollowsWindow = false; + + QWaylandCompositorPrivate::get(d->compositor)->addOutput(this); + + if (d->window) { + QObject::connect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::setWidth); + QObject::connect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::setHeight); + QObject::connect(d->window, &QObject::destroyed, this, &QWaylandOutput::handleWindowDestroyed); + } + + d->init(d->compositor->display(), 2); + + d->initialized = true; } +/*! + * Returns the QWaylandOutput corresponding to \a resource. + */ QWaylandOutput *QWaylandOutput::fromResource(wl_resource *resource) { - QtWayland::OutputResource *outputResource = static_cast<QtWayland::OutputResource *>( - QtWayland::Output::Resource::fromResource(resource)); - if (!outputResource) - return Q_NULLPTR; + return static_cast<QWaylandOutputPrivate *>(QWaylandOutputPrivate::Resource::fromResource(resource)->output_object)->q_func(); +} - QtWayland::Output *output = static_cast<QtWayland::Output *>(outputResource->output_object); - if (!output) - return Q_NULLPTR; +/*! + * \internal + */ +struct ::wl_resource *QWaylandOutput::resourceForClient(QWaylandClient *client) const +{ + Q_D(const QWaylandOutput); + QWaylandOutputPrivate::Resource *r = d->resourceMap().value(client->client()); + if (r) + return r->handle; - return output->output(); + return Q_NULLPTR; } +/*! + * Schedules a QEvent::UpdateRequest to be delivered to the QWaylandOutput's \l{window()}{window}. + * + * \sa QWindow::requestUpdate() + */ void QWaylandOutput::update() { - QRect rect(QPoint(0, 0), window()->size()); - QRegion region(rect); - QExposeEvent *event = new QExposeEvent(region); - QCoreApplication::postEvent(window(), event); + Q_D(QWaylandOutput); + if (!d->window) + return; + d->window->requestUpdate(); } +/*! + * \qmlproperty object QtWaylandCompositor::WaylandOutput::compositor + * + * This property holds the compositor displaying content on this QWaylandOutput. + * This property can only be set once, before the WaylandOutput component is completed. + */ + +/*! + * Returns the compositor for this QWaylandOutput. + */ QWaylandCompositor *QWaylandOutput::compositor() const { - return d_ptr->compositor()->waylandCompositor(); + return d_func()->compositor; +} + +/*! + * \internal + */ +void QWaylandOutput::setCompositor(QWaylandCompositor *compositor) +{ + Q_D(QWaylandOutput); + + if (d->compositor == compositor) + return; + + if (d->initialized) { + qWarning("Setting QWaylandCompositor %p on QWaylandOutput %p is not supported after QWaylandOutput has been initialized\n", compositor, this); + return; + } + if (d->compositor && d->compositor != compositor) { + qWarning("Possible initialization error. Moving QWaylandOutput %p between compositor instances.\n", this); + } + + d->compositor = compositor; + + QWaylandCompositorPrivate::get(compositor)->addPolishObject(this); } +/*! + * \qmlproperty string QtWaylandCompositor::WaylandOutput::manufacturer + * + * This property holds a textual description of the manufacturer of this WaylandOutput. + */ + +/*! + * \property QWaylandOutput::manufacturer + * + * This property holds a textual description of the manufacturer of this QWaylandOutput. + */ QString QWaylandOutput::manufacturer() const { - return d_ptr->manufacturer(); + return d_func()->manufacturer; } +void QWaylandOutput::setManufacturer(const QString &manufacturer) +{ + Q_D(QWaylandOutput); + + if (d->manufacturer == manufacturer) + return; + + d->manufacturer = manufacturer; + d->sendGeometryInfo(); + Q_EMIT manufacturerChanged(); +} + +/*! + * \qmlproperty string QtWaylandCompositor::WaylandOutput::model + * + * This property holds a textual description of the model of this WaylandOutput. + */ + +/*! + * \property QWaylandOutput::model + * + * This property holds a textual description of the model of this QWaylandOutput. + */ QString QWaylandOutput::model() const { - return d_ptr->model(); + return d_func()->model; +} + +void QWaylandOutput::setModel(const QString &model) +{ + Q_D(QWaylandOutput); + + if (d->model == model) + return; + + d->model = model; + d->sendGeometryInfo(); + Q_EMIT modelChanged(); } +/*! + * \qmlproperty point QtWaylandCompositor::WaylandOutput::position + * + * This property holds the position of this WaylandOutput in the compositor's coordinate system. + */ + +/*! + * \property QWaylandOutput::position + * + * This property holds the position of this QWaylandOutput in the compositor's coordinate system. + */ QPoint QWaylandOutput::position() const { - return d_ptr->position(); + return d_func()->position; } void QWaylandOutput::setPosition(const QPoint &pt) { - if (d_ptr->position() == pt) + Q_D(QWaylandOutput); + if (d->position == pt) return; - d_ptr->setPosition(pt); + d->position = pt; + + d->sendGeometryInfo(); + Q_EMIT positionChanged(); Q_EMIT geometryChanged(); } +/*! + * \property QWaylandOutput::mode + * + * This property holds the output's size in pixels and refresh rate in Hz. + */ QWaylandOutput::Mode QWaylandOutput::mode() const { - return d_ptr->mode(); + return d_func()->mode; } void QWaylandOutput::setMode(const Mode &mode) { - if (d_ptr->mode().size == mode.size && d_ptr->mode().refreshRate == mode.refreshRate) + Q_D(QWaylandOutput); + if (d->mode.size == mode.size && d->mode.refreshRate == mode.refreshRate) return; - d_ptr->setMode(mode); + d->mode = mode; + + Q_FOREACH (QWaylandOutputPrivate::Resource *resource, d->resourceMap().values()) { + d->send_mode(resource->handle, d->mode_current, + d->mode.size.width(), d->mode.size.height(), + d->mode.refreshRate * 1000); + if (resource->version() >= 2) + d->send_done(resource->handle); + } + Q_EMIT modeChanged(); Q_EMIT geometryChanged(); - if (window()) { - window()->resize(mode.size); - window()->setMinimumSize(mode.size); - window()->setMaximumSize(mode.size); + if (d->window) { + d->window->resize(mode.size); + d->window->setMinimumSize(mode.size); + d->window->setMaximumSize(mode.size); } } +/*! + * \qmlproperty rect QtWaylandCompositor::WaylandOutput::geometry + * + * This property holds the geometry of the WaylandOutput. + */ + +/*! + * \property QWaylandOutput::geometry + * + * This property holds the geometry of the QWaylandOutput. + * + * \sa QWaylandOutput::mode + */ QRect QWaylandOutput::geometry() const { - return d_ptr->geometry(); + Q_D(const QWaylandOutput); + return QRect(d->position, d->mode.size); } void QWaylandOutput::setGeometry(const QRect &geometry) { - if (d_ptr->geometry() == geometry) + Q_D(QWaylandOutput); + if (d->position == geometry.topLeft() && d->mode.size == geometry.size()) return; - d_ptr->setGeometry(geometry); + d->position = geometry.topLeft(); + d->mode.size = geometry.size(); + + Q_FOREACH (QWaylandOutputPrivate::Resource *resource, d->resourceMap().values()) { + d->send_geometry(resource->handle, + d->position.x(), d->position.y(), + d->physicalSize.width(), d->physicalSize.height(), + toWlSubpixel(d->subpixel), d->manufacturer, d->model, + toWlTransform(d->transform)); + d->send_mode(resource->handle, d->mode_current, + d->mode.size.width(), d->mode.size.height(), + d->mode.refreshRate * 1000); + if (resource->version() >= 2) + d->send_done(resource->handle); + } Q_EMIT positionChanged(); Q_EMIT modeChanged(); - - if (window()) { - window()->resize(geometry.size()); - window()->setMinimumSize(geometry.size()); - window()->setMaximumSize(geometry.size()); - } } +/*! + * \qmlproperty rect QtWaylandCompositor::WaylandOutput::availableGeometry + * + * This property holds the geometry of the WaylandOutput available for displaying content. + * The available geometry is in output coordinates space, starts from 0,0 and it's as big + * as the output by default. + * + * \sa QWaylandOutput::geometry + */ + +/*! + * \property QWaylandOutput::availableGeometry + * + * This property holds the geometry of the QWaylandOutput available for displaying content. + * The available geometry is in output coordinates space, starts from 0,0 and it's as big + * as the output by default. + * + * \sa QWaylandOutput::mode, QWaylandOutput::geometry + */ QRect QWaylandOutput::availableGeometry() const { - if (!d_ptr->availableGeometry().isValid()) - return QRect(d_ptr->position(), d_ptr->mode().size); + Q_D(const QWaylandOutput); + if (!d->availableGeometry.isValid()) + return QRect(QPoint(0, 0), d->mode.size); - return d_ptr->availableGeometry(); + return d->availableGeometry; } void QWaylandOutput::setAvailableGeometry(const QRect &availableGeometry) { - if (d_ptr->availableGeometry() == availableGeometry) + Q_D(QWaylandOutput); + if (d->availableGeometry == availableGeometry) return; - d_ptr->setAvailableGeometry(availableGeometry); + if (availableGeometry.topLeft().x() < 0 || availableGeometry.topLeft().y() < 0) + qWarning("Available geometry should be a portion of the output"); + + d->availableGeometry = availableGeometry; + Q_EMIT availableGeometryChanged(); } +/*! + * \qmlproperty size QtWaylandCompositor::WaylandOutput::physicalSize + * + * This property holds the physical size of the WaylandOutput in millimeters. + * + * \sa QWaylandOutput::geometry + */ + +/*! + * \property QWaylandOutput::physicalSize + * + * This property holds the physical size of the QWaylandOutput in millimeters. + * + * \sa QWaylandOutput::geometry, QWaylandOutput::mode + */ QSize QWaylandOutput::physicalSize() const { - return d_ptr->physicalSize(); + return d_func()->physicalSize; } void QWaylandOutput::setPhysicalSize(const QSize &size) { - if (d_ptr->physicalSize() == size) + Q_D(QWaylandOutput); + if (d->physicalSize == size) return; - d_ptr->setPhysicalSize(size); + d->physicalSize = size; + + d->sendGeometryInfo(); + Q_EMIT physicalSizeChanged(); } +/*! + * \enum QWaylandOutput::Subpixel + * + * This enum type is used to specify the subpixel arrangement of a QWaylandOutput. + * + * \value SubpixelUnknown The subpixel arrangement is not set. + * \value SubpixelNone There are no subpixels. + * \value SubpixelHorizontalRgb The subpixels are arranged horizontally in red, green, blue order. + * \value SubpixelHorizontalBgr The subpixels are arranged horizontally in blue, green, red order. + * \value SubpixelVerticalRgb The subpixels are arranged vertically in red, green, blue order. + * \value SubpixelVerticalBgr The subpixels are arranged vertically in blue, green, red order. + * + * \sa QWaylandOutput::subpixel + */ + +/*! + * \qmlproperty enum QtWaylandCompositor::WaylandOutput::subpixel + * + * This property holds the subpixel arrangement of this WaylandOutput. + * + * \list + * \li WaylandOutput.SubpixelUnknown The subpixel arrangement is not set. + * \li WaylandOutput.SubpixelNone There are no subpixels. + * \li WaylandOutput.SubpixelHorizontalRgb The subpixels are arranged horizontally in red, green, blue order. + * \li WaylandOutput.SubpixelHorizontalBgr The subpixels are arranged horizontally in blue, green, red order. + * \li WaylandOutput.SubpixelVerticalRgb The subpixels are arranged vertically in red, green, blue order. + * \li WaylandOutput.SubpixelVerticalBgr The subpixels are arranged vertically in blue, green, red order. + * \endlist + * + * The default is WaylandOutput.SubpixelUnknown. + */ + +/*! + * \property QWaylandOutput::subpixel + * + * This property holds the subpixel arrangement of this QWaylandOutput. The default is + * QWaylandOutput::SubpixelUnknown. + */ QWaylandOutput::Subpixel QWaylandOutput::subpixel() const { - return d_ptr->subpixel(); + return d_func()->subpixel; } void QWaylandOutput::setSubpixel(const Subpixel &subpixel) { - if (d_ptr->subpixel() == subpixel) + Q_D(QWaylandOutput); + if (d->subpixel == subpixel) return; - d_ptr->setSubpixel(subpixel); + d->subpixel = subpixel; + + d->sendGeometryInfo(); + Q_EMIT subpixelChanged(); } +/*! \enum QWaylandOutput::Transform + * + * This enum type is used to specify the orientation of a QWaylandOutput. + * + * \value TransformNormal The QWaylandOutput orientation is normal. + * \value Transform90 The QWaylandOutput is rotated 90 degrees. + * \value Transform180 The QWaylandOutput is rotated 180 degrees. + * \value Transform270 The QWaylandOutput is rotated 270 degrees. + * \value TransformFlipped The QWaylandOutput is mirrored. + * \value TransformFlipped90 The QWaylandOutput is mirrored, and rotated 90 degrees. + * \value TransformFlipped180 The QWaylandOutput is mirrored, and rotated 180 degrees. + * \value TransformFlipped270 The QWaylandOutput is mirrored, and rotated 270 degrees. + * + * \sa QWaylandOutput::transform +*/ + +/*! + * \qmlproperty enum QtWaylandCompositor::WaylandOutput::transform + * + * This property holds the transformation that the QWaylandCompositor applies to a surface + * to compensate for the orientation of the QWaylandOutput. + * + * \list + * \li WaylandOutput.TransformNormal The QWaylandOutput orientation is normal. + * \li WaylandOutput.Transform90 The QWaylandOutput is rotated 90 degrees. + * \li WaylandOutput.Transform180 The QWaylandOutput is rotated 180 degrees. + * \li WaylandOutput.Transform270 The QWaylandOutput is rotated 270 degrees. + * \li WaylandOutput.TransformFlipped The QWaylandOutput is mirrored. + * \li WaylandOutput.TransformFlipped90 The QWaylandOutput is mirrored, then rotated 90 degrees. + * \li WaylandOutput.TransformFlipped180 The QWaylandOutput is mirrored, then rotated 180 degrees. + * \li WaylandOutput.TransformFlipped270 The QWaylandOutput is mirrored, then rotated 270 degrees. + * \endlist + * + * The default is WaylandOutput.TransformNormal. + */ + +/*! + * \property QWaylandOutput::transform + * + * This property holds the transformation that the QWaylandCompositor applies to a surface + * to compensate for the orientation of the QWaylandOutput. + * + * The default is QWaylandOutput::TransformNormal. + */ QWaylandOutput::Transform QWaylandOutput::transform() const { - return d_ptr->transform(); + return d_func()->transform; } void QWaylandOutput::setTransform(const Transform &transform) { - if (d_ptr->transform() == transform) + Q_D(QWaylandOutput); + if (d->transform == transform) return; - d_ptr->setTransform(transform); + d->transform = transform; + + d->sendGeometryInfo(); + Q_EMIT transformChanged(); } +/*! + * \qmlproperty int QtWaylandCompositor::WaylandOutput::scaleFactor + * + * This property holds the factor by which the WaylandCompositor scales surface buffers + * before they are displayed. This is used on high density output devices where unscaled content + * would be too small to be practical. The client can in turn set the scale factor of its + * buffer to match the output if it prefers to provide high resolution content that is + * suitable for the output device. + * + * The default is 1 (no scaling). + */ + +/*! + * \property QWaylandOutput::scaleFactor + * + * This property holds the factor by which the QWaylandCompositor scales surface buffers + * before they are displayed. This is used on high density output devices where unscaled content + * would be too small to be practical. The client can in turn set the scale factor of its + * buffer to match the output if it prefers to provide high resolution content that is + * suitable for the output device. + * + * The default is 1 (no scaling). + */ int QWaylandOutput::scaleFactor() const { - return d_ptr->scaleFactor(); + return d_func()->scaleFactor; } void QWaylandOutput::setScaleFactor(int scale) { - if (d_ptr->scaleFactor() == scale) + Q_D(QWaylandOutput); + if (d->scaleFactor == scale) return; - d_ptr->setScaleFactor(scale); + d->scaleFactor = scale; + + Q_FOREACH (QWaylandOutputPrivate::Resource *resource, d->resourceMap().values()) { + if (resource->version() >= 2) { + d->send_scale(resource->handle, scale); + d->send_done(resource->handle); + } + } + Q_EMIT scaleFactorChanged(); +} +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandOutput::sizeFollowsWindow + * + * This property controls whether the size of the WaylandOutput matches the + * size of its window. + * + * The default is true if this WaylandOutput has a window. + */ + +/*! + * \property QWaylandOutput::sizeFollowsWindow + * + * This property controls whether the size of the QWaylandOutput matches the + * size of its window. + * + * The default is true if this QWaylandOutput has a window. + */ +bool QWaylandOutput::sizeFollowsWindow() const +{ + return d_func()->sizeFollowsWindow; } +void QWaylandOutput::setSizeFollowsWindow(bool follow) +{ + Q_D(QWaylandOutput); + + if (!d->window) { + qWarning("Setting QWaylandOutput::sizeFollowsWindow without a window has no effect"); + return; + } + + if (follow != d->sizeFollowsWindow) { + if (follow) { + QObject::connect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::setWidth); + QObject::connect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::setHeight); + } else { + QObject::disconnect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::setWidth); + QObject::disconnect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::setHeight); + } + d->sizeFollowsWindow = follow; + Q_EMIT sizeFollowsWindowChanged(); + } +} + +/*! + * \qmlproperty object QtWaylandCompositor::WaylandOutput::window + * + * This property holds the Window for this WaylandOutput. This property can only be set once, + * before the WaylandOutput component is completed. + */ + +/*! + * \property QWaylandOutput::window + * + * This property holds the QWindow for this QWaylandOutput. + */ QWindow *QWaylandOutput::window() const { - return d_ptr->window(); + return d_func()->window; } -QtWayland::Output *QWaylandOutput::handle() +void QWaylandOutput::setWindow(QWindow *window) { - return d_ptr; + Q_D(QWaylandOutput); + if (d->window == window) + return; + if (d->initialized) { + qWarning("Setting QWindow %p on QWaylandOutput %p is not supported after QWaylandOutput has been initialized\n", window, this); + return; + } + d->window = window; + emit windowChanged(); +} + +/*! + * Tells the QWaylandOutput that a frame has started. + */ +void QWaylandOutput::frameStarted() +{ + Q_D(QWaylandOutput); + for (int i = 0; i < d->surfaceViews.size(); i++) { + QWaylandSurfaceViewMapper &surfacemapper = d->surfaceViews[i]; + if (surfacemapper.maybeThrottelingView()) + surfacemapper.surface->frameStarted(); + } } -QList<QWaylandSurface *> QWaylandOutput::surfaces() const +/*! + * Sends pending frame callbacks. + */ +void QWaylandOutput::sendFrameCallbacks() { - QList<QWaylandSurface *> list; - Q_FOREACH (QWaylandSurface *surface, d_ptr->compositor()->waylandCompositor()->surfaces()) { - if (surface->outputs().contains(const_cast<QWaylandOutput *>(this))) - list.append(surface); + Q_D(QWaylandOutput); + for (int i = 0; i < d->surfaceViews.size(); i++) { + const QWaylandSurfaceViewMapper &surfacemapper = d->surfaceViews.at(i); + if (surfacemapper.surface && surfacemapper.surface->isMapped()) { + if (!surfacemapper.has_entered) { + surfaceEnter(surfacemapper.surface); + d->surfaceViews[i].has_entered = true; + } + if (surfacemapper.maybeThrottelingView()) + surfacemapper.surface->sendFrameCallbacks(); + } } - return list; + wl_display_flush_clients(d->compositor->display()); +} + +/*! + * \internal + */ +void QWaylandOutput::surfaceEnter(QWaylandSurface *surface) +{ + if (!surface) + return; + + auto clientResource = resourceForClient(surface->client()); + if (clientResource) + QWaylandSurfacePrivate::get(surface)->send_enter(clientResource); +} + +/*! + * \internal + */ +void QWaylandOutput::surfaceLeave(QWaylandSurface *surface) +{ + if (!surface || !surface->client()) + return; + QWaylandSurfacePrivate::get(surface)->send_leave(resourceForClient(surface->client())); } + +/*! + * This functions sets the width of this QWaylandOutput to \a newWidth. + * + * \sa setHeight, QWaylandOutput::geometry + */ +void QWaylandOutput::setWidth(int newWidth) +{ + Q_D(QWaylandOutput); + if (d->mode.size.width() == newWidth) + return; + + QSize s = d->mode.size; + s.setWidth(newWidth); + setGeometry(QRect(d->position, s)); +} + +/*! + * This functions sets the height of this QWaylandOutput to \a newHeight. + * + * \sa setWidth, QWaylandOutput::geometry + */ +void QWaylandOutput::setHeight(int newHeight) +{ + Q_D(QWaylandOutput); + if (d->mode.size.height() == newHeight) + return; + + QSize s = d->mode.size; + s.setHeight(newHeight); + setGeometry(QRect(d->position, s)); +} + +/*! + * \internal + */ +void QWaylandOutput::handleWindowDestroyed() +{ + Q_D(QWaylandOutput); + d->window = Q_NULLPTR; + emit windowDestroyed(); +} + +/*! + * \internal + */ +bool QWaylandOutput::event(QEvent *event) +{ + if (event->type() == QEvent::Polish) + initialize(); + return QObject::event(event); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandoutput.h b/src/compositor/compositor_api/qwaylandoutput.h index 9c9dc3767..e4cbb6109 100644 --- a/src/compositor/compositor_api/qwaylandoutput.h +++ b/src/compositor/compositor_api/qwaylandoutput.h @@ -4,36 +4,32 @@ ** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -42,30 +38,33 @@ #ifndef QWAYLANDOUTPUT_H #define QWAYLANDOUTPUT_H -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandcompositorextension.h> +#include <QtCore/QObject> #include <QObject> #include <QRect> #include <QSize> -QT_BEGIN_NAMESPACE - struct wl_resource; +QT_BEGIN_NAMESPACE + +class QWaylandOutputPrivate; class QWaylandCompositor; class QWindow; class QWaylandSurface; +class QWaylandView; class QWaylandClient; +class QWaylandOutputSpace; -namespace QtWayland { - class Output; -} - -class Q_COMPOSITOR_EXPORT QWaylandOutput : public QObject +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandOutput : public QWaylandObject { Q_OBJECT - Q_PROPERTY(QString manufacturer READ manufacturer CONSTANT) - Q_PROPERTY(QString model READ model CONSTANT) + Q_DECLARE_PRIVATE(QWaylandOutput) + Q_PROPERTY(QWaylandCompositor *compositor READ compositor WRITE setCompositor NOTIFY compositorChanged) + Q_PROPERTY(QWindow *window READ window WRITE setWindow NOTIFY windowChanged) + Q_PROPERTY(QString manufacturer READ manufacturer WRITE setManufacturer NOTIFY manufacturerChanged) + Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged) Q_PROPERTY(QPoint position READ position WRITE setPosition NOTIFY positionChanged) Q_PROPERTY(QWaylandOutput::Mode mode READ mode WRITE setMode NOTIFY modeChanged) Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged) @@ -74,8 +73,9 @@ class Q_COMPOSITOR_EXPORT QWaylandOutput : public QObject Q_PROPERTY(QWaylandOutput::Subpixel subpixel READ subpixel WRITE setSubpixel NOTIFY subpixelChanged) Q_PROPERTY(QWaylandOutput::Transform transform READ transform WRITE setTransform NOTIFY transformChanged) Q_PROPERTY(int scaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged) - Q_PROPERTY(QWindow *window READ window CONSTANT) + Q_PROPERTY(bool sizeFollowsWindow READ sizeFollowsWindow WRITE setSizeFollowsWindow NOTIFY sizeFollowsWindowChanged) Q_ENUMS(Subpixel Transform) + public: enum Subpixel { SubpixelUnknown = 0, @@ -85,6 +85,7 @@ public: SubpixelVerticalRgb, SubpixelVerticalBgr }; + Q_ENUM(Subpixel) enum Transform { TransformNormal = 0, @@ -96,26 +97,32 @@ public: TransformFlipped180, TransformFlipped270 }; + Q_ENUM(Transform) struct Mode { QSize size; - int refreshRate; + qreal refreshRate; }; - QWaylandOutput(QWaylandCompositor *compositor, QWindow *window, - const QString &manufacturer, const QString &model); + QWaylandOutput(); + QWaylandOutput(QWaylandCompositor *compositor, QWindow *window); ~QWaylandOutput(); static QWaylandOutput *fromResource(wl_resource *resource); - - virtual void update(); + struct ::wl_resource *resourceForClient(QWaylandClient *client) const; QWaylandCompositor *compositor() const; + void setCompositor(QWaylandCompositor *compositor); + + QWindow *window() const; + void setWindow(QWindow *window); QString manufacturer() const; + void setManufacturer(const QString &manufacturer); QString model() const; + void setModel(const QString &model); QPoint position() const; void setPosition(const QPoint &pt); @@ -125,6 +132,8 @@ public: QRect geometry() const; void setGeometry(const QRect &geometry); + void setWidth(int newWidth); + void setHeight(int newHeight); QRect availableGeometry() const; void setAvailableGeometry(const QRect &availableGeometry); @@ -141,13 +150,23 @@ public: int scaleFactor() const; void setScaleFactor(int scale); - QWindow *window() const; + bool sizeFollowsWindow() const; + void setSizeFollowsWindow(bool follow); + + bool physicalSizeFollowsSize() const; + void setPhysicalSizeFollowsSize(bool follow); - QtWayland::Output *handle(); + void frameStarted(); + void sendFrameCallbacks(); - QList<QWaylandSurface *> surfaces() const; + void surfaceEnter(QWaylandSurface *surface); + void surfaceLeave(QWaylandSurface *surface); + + virtual void update(); Q_SIGNALS: + void compositorChanged(); + void windowChanged(); void positionChanged(); void geometryChanged(); void modeChanged(); @@ -156,13 +175,23 @@ Q_SIGNALS: void scaleFactorChanged(); void subpixelChanged(); void transformChanged(); + void sizeFollowsWindowChanged(); + void physicalSizeFollowsSizeChanged(); + void manufacturerChanged(); + void modelChanged(); + void windowDestroyed(); -private: - QtWayland::Output *const d_ptr; -}; +private Q_SLOTS: + void handleWindowDestroyed(); -Q_DECLARE_METATYPE(QWaylandOutput::Mode) +protected: + bool event(QEvent *event) Q_DECL_OVERRIDE; + + virtual void initialize(); +}; QT_END_NAMESPACE +Q_DECLARE_METATYPE(QWaylandOutput::Mode) + #endif // QWAYLANDOUTPUT_H diff --git a/src/compositor/compositor_api/qwaylandoutput_p.h b/src/compositor/compositor_api/qwaylandoutput_p.h new file mode 100644 index 000000000..9b6ba9076 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandoutput_p.h @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2014-2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDOUTPUT_P_H +#define QWAYLANDOUTPUT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/QWaylandOutput> +#include <QtWaylandCompositor/QWaylandClient> +#include <QtWaylandCompositor/QWaylandSurface> + +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> + +#include <QtCore/QRect> +#include <QtCore/QVector> + +#include <QtCore/private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +struct QWaylandSurfaceViewMapper +{ + QWaylandSurfaceViewMapper() + : surface(0) + , views() + , has_entered(false) + {} + + QWaylandSurfaceViewMapper(QWaylandSurface *s, QWaylandView *v) + : surface(s) + , views(1, v) + , has_entered(false) + {} + + QWaylandView *maybeThrottelingView() const + { + for (int i = 0; i < views.size(); i++) { + if (surface && surface->throttlingView() == views.at(i)) + return views.at(i); + } + return Q_NULLPTR; + } + + QWaylandSurface *surface; + QVector<QWaylandView *> views; + bool has_entered; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandOutputPrivate : public QObjectPrivate, public QtWaylandServer::wl_output +{ +public: + QWaylandOutputPrivate(); + + ~QWaylandOutputPrivate(); + static QWaylandOutputPrivate *get(QWaylandOutput *output) { return output->d_func(); } + + void addView(QWaylandView *view, QWaylandSurface *surface); + void removeView(QWaylandView *view, QWaylandSurface *surface); + void sendGeometryInfo(); + +protected: + void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + + +private: + QWaylandCompositor *compositor; + QWindow *window; + QString manufacturer; + QString model; + QPoint position; + QWaylandOutput::Mode mode; + QRect availableGeometry; + QVector<QWaylandSurfaceViewMapper> surfaceViews; + QSize physicalSize; + QWaylandOutput::Subpixel subpixel; + QWaylandOutput::Transform transform; + int scaleFactor; + bool sizeFollowsWindow; + bool initialized; + + Q_DECLARE_PUBLIC(QWaylandOutput) + Q_DISABLE_COPY(QWaylandOutputPrivate) +}; + + +QT_END_NAMESPACE + +#endif /*QWAYLANDOUTPUT_P_H*/ diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp new file mode 100644 index 000000000..da08e339e --- /dev/null +++ b/src/compositor/compositor_api/qwaylandpointer.cpp @@ -0,0 +1,382 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandpointer.h" +#include "qwaylandpointer_p.h" +#include <QtWaylandCompositor/QWaylandClient> +#include <QtWaylandCompositor/QWaylandCompositor> + +QT_BEGIN_NAMESPACE + +QWaylandSurfaceRole QWaylandPointerPrivate::s_role("wl_pointer"); + +QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandInputDevice *seat) + : QObjectPrivate() + , wl_pointer() + , seat(seat) + , output() + , focusResource() + , hasSentEnter(false) + , buttonCount() +{ + Q_UNUSED(pointer); +} + +void QWaylandPointerPrivate::pointer_destroy_resource(wl_pointer::Resource *resource) +{ + if (focusResource == resource->handle) + focusResource = 0; +} + +void QWaylandPointerPrivate::pointer_release(wl_pointer::Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void QWaylandPointerPrivate::pointer_set_cursor(wl_pointer::Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + + if (!surface) { + seat->cursorSurfaceRequest(Q_NULLPTR, 0, 0); + return; + } + + QWaylandSurface *s = QWaylandSurface::fromResource(surface); + // XXX FIXME + // The role concept was formalized in wayland 1.7, so that release adds one error + // code for each interface that implements a role, and we are supposed to pass here + // the newly constructed resource and the correct error code so that if setting the + // role fails, a proper error can be sent to the client. + // However we're still using wayland 1.4, which doesn't have interface specific role + // errors, so the best we can do is to use wl_display's object_id error. + wl_resource *displayRes = wl_client_get_object(resource->client(), 1); + if (s->setRole(&QWaylandPointerPrivate::s_role, displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT)) { + s->markAsCursorSurface(true); + seat->cursorSurfaceRequest(s, hotspot_x, hotspot_y); + } +} + +/*! + * \class QWaylandPointer + * \inmodule QtWaylandCompositor + * \preliminary + * \brief The QWaylandPointer class provides access to a pointer device. + * + * This class provides access to the pointer device in a QWaylandInputDevice. It corresponds to + * the Wayland interface wl_pointer. + */ + +/*! + * Constructs a QWaylandPointer for the given \a inputDevice and with the given \a parent. + */ +QWaylandPointer::QWaylandPointer(QWaylandInputDevice *inputDevice, QObject *parent) + : QWaylandObject(* new QWaylandPointerPrivate(this, inputDevice), parent) +{ + connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandPointer::focusDestroyed); + connect(inputDevice, &QWaylandInputDevice::mouseFocusChanged, this, &QWaylandPointer::pointerFocusChanged); +} + +/*! + * Returns the input device for this QWaylandPointer. + */ +QWaylandInputDevice *QWaylandPointer::inputDevice() const +{ + Q_D(const QWaylandPointer); + return d->seat; +} + +/*! + * Returns the compositor for this QWaylandPointer. + */ +QWaylandCompositor *QWaylandPointer::compositor() const +{ + Q_D(const QWaylandPointer); + return d->compositor(); +} + +/*! + * Returns the output for this QWaylandPointer. + */ +QWaylandOutput *QWaylandPointer::output() const +{ + Q_D(const QWaylandPointer); + return d->output; +} + +/*! + * Sets the output for this QWaylandPointer to \a output. + */ +void QWaylandPointer::setOutput(QWaylandOutput *output) +{ + Q_D(QWaylandPointer); + if (d->output == output) return; + d->output = output; + outputChanged(); +} + +/*! + * Sends a mouse press event for \a button to the view currently holding mouse focus. + */ +void QWaylandPointer::sendMousePressEvent(Qt::MouseButton button) +{ + Q_D(QWaylandPointer); + uint32_t time = d->compositor()->currentTimeMsecs(); + d->buttonCount++; + if (d->focusResource) + sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_PRESSED); + + if (d->buttonCount == 1) { + emit buttonPressedChanged(); + } +} + +/*! + * Sends a mouse release event for \a button to the view currently holding mouse focus. + */ +void QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button) +{ + Q_D(QWaylandPointer); + uint32_t time = d->compositor()->currentTimeMsecs(); + d->buttonCount--; + + if (d->focusResource) + sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_RELEASED); + + if (d->buttonCount == 0) + emit buttonPressedChanged(); +} + +/*! + * Sets the current mouse focus to \a view and sends a mouse move event to it with the + * local position \a localPos and output space position \a outputSpacePos. + */ +void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos) +{ + Q_D(QWaylandPointer); + if (view && (!view->surface() || view->surface()->isCursorSurface())) + view = Q_NULLPTR; + d->seat->setMouseFocus(view); + d->localPosition = localPos; + d->spacePosition = outputSpacePos; + + //we adjust if the mouse position is on the edge + //to work around Qt's event propagation + if (view && view->surface()) { + QSizeF size(view->surface()->size()); + if (d->localPosition.x() == size.width()) + d->localPosition.rx() -= 0.01; + + if (d->localPosition.y() == size.height()) + d->localPosition.ry() -= 0.01; + } + + QWaylandPointerPrivate::Resource *resource = view ? d->resourceMap().value(view->surface()->waylandClient()) : 0; + if (resource && !d->hasSentEnter) { + uint32_t serial = d->compositor()->nextSerial(); + QWaylandKeyboard *keyboard = d->seat->keyboard(); + if (keyboard) { + keyboard->sendKeyModifiers(view->surface()->client(), serial); + } + d->send_enter(resource->handle, serial, view->surface()->resource(), + wl_fixed_from_double(d->localPosition.x()), wl_fixed_from_double(d->localPosition.y())); + + d->focusDestroyListener.listenForDestruction(view->surface()->resource()); + d->hasSentEnter = true; + } + + d->focusResource = resource ? resource->handle : 0; + + if (view && view->output()) + setOutput(view->output()); + + uint32_t time = d->compositor()->currentTimeMsecs(); + + if (d->focusResource) { + wl_fixed_t x = wl_fixed_from_double(currentLocalPosition().x()); + wl_fixed_t y = wl_fixed_from_double(currentLocalPosition().y()); + wl_pointer_send_motion(d->focusResource, time, x, y); + } +} + +/*! + * Sends a mouse wheel event with the given \a orientation and \a delta to the view that currently holds mouse focus. + */ +void QWaylandPointer::sendMouseWheelEvent(Qt::Orientation orientation, int delta) +{ + Q_D(QWaylandPointer); + if (!d->focusResource) + return; + + uint32_t time = d->compositor()->currentTimeMsecs(); + uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL + : WL_POINTER_AXIS_VERTICAL_SCROLL; + d->send_axis(d->focusResource, time, axis, wl_fixed_from_int(-delta / 12)); +} + +/*! + * Returns the view that currently holds mouse focus. + */ +QWaylandView *QWaylandPointer::mouseFocus() const +{ + Q_D(const QWaylandPointer); + return d->seat->mouseFocus(); +} + +/*! + * Returns the current local position of the QWaylandPointer. + */ +QPointF QWaylandPointer::currentLocalPosition() const +{ + Q_D(const QWaylandPointer); + return d->localPosition; +} + +/*! + * Returns the current output space position of the QWaylandPointer. + */ +QPointF QWaylandPointer::currentSpacePosition() const +{ + Q_D(const QWaylandPointer); + return d->spacePosition; +} + +/*! + * Returns true if any button is currently pressed. Otherwise returns false. + */ +bool QWaylandPointer::isButtonPressed() const +{ + Q_D(const QWaylandPointer); + return d->buttonCount > 0; +} + +/*! + * \internal + */ +void QWaylandPointer::addClient(QWaylandClient *client, uint32_t id, uint32_t version) +{ + Q_D(QWaylandPointer); + d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_pointer::interfaceVersion(), version)); +} + +/*! + * Returns the Wayland resource for this QWaylandPointer. + */ +struct wl_resource *QWaylandPointer::focusResource() const +{ + Q_D(const QWaylandPointer); + if (!d->focusResource) + return Q_NULLPTR; + + return d->focusResource; +} + +/*! + * \internal + */ +void QWaylandPointer::sendButton(struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state) +{ + Q_D(QWaylandPointer); + uint32_t serial = d->compositor()->nextSerial(); + d->send_button(resource, serial, time, toWaylandButton(button), state); +} + +/*! + * \internal + */ +uint32_t QWaylandPointer::toWaylandButton(Qt::MouseButton button) +{ +#ifndef BTN_LEFT + uint32_t BTN_LEFT = 0x110; +#endif + // the range of valid buttons (evdev module) is from 0x110 + // through 0x11f. 0x120 is the first 'Joystick' button. + switch (button) { + case Qt::LeftButton: return BTN_LEFT; + case Qt::RightButton: return uint32_t(0x111); + case Qt::MiddleButton: return uint32_t(0x112); + case Qt::ExtraButton1: return uint32_t(0x113); // AKA Qt::BackButton, Qt::XButton1 + case Qt::ExtraButton2: return uint32_t(0x114); // AKA Qt::ForwardButton, Qt::XButton2 + case Qt::ExtraButton3: return uint32_t(0x115); + case Qt::ExtraButton4: return uint32_t(0x116); + case Qt::ExtraButton5: return uint32_t(0x117); + case Qt::ExtraButton6: return uint32_t(0x118); + case Qt::ExtraButton7: return uint32_t(0x119); + case Qt::ExtraButton8: return uint32_t(0x11a); + case Qt::ExtraButton9: return uint32_t(0x11b); + case Qt::ExtraButton10: return uint32_t(0x11c); + case Qt::ExtraButton11: return uint32_t(0x11d); + case Qt::ExtraButton12: return uint32_t(0x11e); + case Qt::ExtraButton13: return uint32_t(0x11f); + // default should not occur; but if it does, then return Wayland's highest possible button number. + default: return uint32_t(0x11f); + } +} + +/*! + * \internal + */ +void QWaylandPointer::focusDestroyed(void *data) +{ + Q_D(QWaylandPointer); + Q_UNUSED(data) + d->focusDestroyListener.reset(); + + d->seat->setMouseFocus(Q_NULLPTR); + d->focusResource = 0; + d->buttonCount = 0; +} + +/*! + * \internal + */ +void QWaylandPointer::pointerFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus) +{ + Q_UNUSED(newFocus); + Q_D(QWaylandPointer); + d->localPosition = QPointF(); + d->hasSentEnter = false; + if (d->focusResource && oldFocus) { + uint32_t serial = d->compositor()->nextSerial(); + d->send_leave(d->focusResource, serial, oldFocus->surfaceResource()); + d->focusDestroyListener.reset(); + d->focusResource = 0; + } + +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandpointer.h b/src/compositor/compositor_api/qwaylandpointer.h new file mode 100644 index 000000000..9d7d06807 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandpointer.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDPOINTER_H +#define QWAYLANDPOINTER_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> + +struct wl_resource; + +QT_BEGIN_NAMESPACE + +class QWaylandPointer; +class QWaylandPointerPrivate; +class QWaylandInputDevice; +class QWaylandView; +class QWaylandOutput; +class QWaylandClient; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandPointer : public QWaylandObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandPointer) + Q_PROPERTY(bool isButtonPressed READ isButtonPressed NOTIFY buttonPressedChanged) +public: + QWaylandPointer(QWaylandInputDevice *inputDevice, QObject *parent = nullptr); + + QWaylandInputDevice *inputDevice() const; + QWaylandCompositor *compositor() const; + + QWaylandOutput *output() const; + void setOutput(QWaylandOutput *output); + + virtual void sendMousePressEvent(Qt::MouseButton button); + virtual void sendMouseReleaseEvent(Qt::MouseButton button); + virtual void sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos); + virtual void sendMouseWheelEvent(Qt::Orientation orientation, int delta); + + QWaylandView *mouseFocus() const; + QPointF currentLocalPosition() const; + QPointF currentSpacePosition() const; + + bool isButtonPressed() const; + + virtual void addClient(QWaylandClient *client, uint32_t id, uint32_t version); + + wl_resource *focusResource() const; + + static uint32_t toWaylandButton(Qt::MouseButton button); + void sendButton(struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state); +Q_SIGNALS: + void outputChanged(); + void buttonPressedChanged(); + +private: + void focusDestroyed(void *data); + void pointerFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus); +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDPOINTER_H*/ diff --git a/src/compositor/compositor_api/qwaylandpointer_p.h b/src/compositor/compositor_api/qwaylandpointer_p.h new file mode 100644 index 000000000..5ac030029 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandpointer_p.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDPOINTER_P_H +#define QWAYLANDPOINTER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/QWaylandDestroyListener> +#include <QtWaylandCompositor/QWaylandPointer> + +#include <QtCore/QList> +#include <QtCore/QPoint> +#include <QtCore/QObject> +#include <QtCore/private/qobject_p.h> + +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> +#include <QtWaylandCompositor/QWaylandView> +#include <QtWaylandCompositor/QWaylandSurface> +#include <QtWaylandCompositor/QWaylandInputDevice> + +#include <stdint.h> + +QT_BEGIN_NAMESPACE + +class QWaylandView; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandPointerPrivate : public QObjectPrivate + , public QtWaylandServer::wl_pointer +{ + Q_DECLARE_PUBLIC(QWaylandPointer) +public: + QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandInputDevice *seat); + + QWaylandCompositor *compositor() const { return seat->compositor(); } + +protected: + void pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) Q_DECL_OVERRIDE; + void pointer_release(Resource *resource) Q_DECL_OVERRIDE; + void pointer_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + +private: + void focusDestroyed(void *data); + + QWaylandInputDevice *seat; + QWaylandOutput *output; + + QPointF localPosition; + QPointF spacePosition; + + struct ::wl_resource *focusResource; + bool hasSentEnter; + + int buttonCount; + + QWaylandDestroyListener focusDestroyListener; + + static QWaylandSurfaceRole s_role; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDPOINTER_P_H diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp index 3a3c0ecea..dc13368f2 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp @@ -4,9 +4,9 @@ ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -17,74 +17,155 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#include <QtCompositor/private/qwlcompositor_p.h> -#include <QtCompositor/private/qwlsurface_p.h> +#include <QtQml/QQmlEngine> +#include <QQuickWindow> +#include <QtGui/private/qopengltextureblitter_p.h> +#include <QOpenGLFramebufferObject> +#include <QMatrix4x4> +#include <QRunnable> #include "qwaylandclient.h" #include "qwaylandquickcompositor.h" #include "qwaylandquicksurface.h" -#include "qwaylandsurfaceitem.h" #include "qwaylandquickoutput.h" +#include "qwaylandquickitem.h" +#include "qwaylandoutput.h" +#include <QtWaylandCompositor/private/qwaylandcompositor_p.h> +#include "qwaylandsurfacegrabber.h" QT_BEGIN_NAMESPACE -class QWaylandQuickCompositorPrivate : public QtWayland::Compositor +class QWaylandQuickCompositorPrivate : public QWaylandCompositorPrivate { public: - QWaylandQuickCompositorPrivate(QWaylandQuickCompositor *compositor, QWaylandCompositor::ExtensionFlags extensions) - : QtWayland::Compositor(compositor, extensions) + QWaylandQuickCompositorPrivate(QWaylandCompositor *compositor) + : QWaylandCompositorPrivate(compositor) { } - - void compositor_create_surface(Resource *resource, uint32_t id) Q_DECL_OVERRIDE +protected: + QWaylandSurface *createDefaultSurface() Q_DECL_OVERRIDE { - QWaylandQuickSurface *surface = new QWaylandQuickSurface(resource->client(), id, wl_resource_get_version(resource->handle), static_cast<QWaylandQuickCompositor *>(m_qt_compositor)); - surface->handle()->addToOutput(primaryOutput()->handle()); - m_surfaces << surface->handle(); - //BUG: This may not be an on-screen window surface though - m_qt_compositor->surfaceCreated(surface); + return new QWaylandQuickSurface(); } }; +QWaylandQuickCompositor::QWaylandQuickCompositor(QObject *parent) + : QWaylandCompositor(*new QWaylandQuickCompositorPrivate(this), parent) +{ +} + +/*! + * \qmlproperty list QtWaylandCompositor::WaylandCompositor::extensions + * + * A list of extensions that the compositor advertises to its clients. For + * any Wayland extension the compositor should support, instantiate its component, + * and add it to the list of extensions. + * + * For instance, the following code would allow the clients to request wl shell surfaces + * in the compositor using the wl_shell interface. + * + * \code + * import QtWayland.Compositor 1.0 + * + * WaylandCompositor { + * extensions: [ WlShell { + * // ... + * } ] + * } + * \endcode + */ + +void QWaylandQuickCompositor::create() +{ + QWaylandCompositor::create(); +} + -QWaylandQuickCompositor::QWaylandQuickCompositor(const char *socketName, ExtensionFlags extensions) - : QWaylandCompositor(socketName, new QWaylandQuickCompositorPrivate(this, extensions)) +void QWaylandQuickCompositor::classBegin() { - qmlRegisterUncreatableType<QWaylandSurfaceItem>("QtCompositor", 1, 0, "WaylandSurfaceItem", QObject::tr("Cannot create instance of WaylandSurfaceItem")); - qmlRegisterUncreatableType<QWaylandQuickSurface>("QtCompositor", 1, 0, "WaylandQuickSurface", QObject::tr("Cannot create instance of WaylandQuickSurface")); - qmlRegisterUncreatableType<QWaylandClient>("QtCompositor", 1, 0, "WaylandClient", QObject::tr("Cannot create instance of WaylandClient")); - qmlRegisterUncreatableType<QWaylandOutput>("QtCompositor", 1, 0, "WaylandOutput", QObject::tr("Cannot create instance of WaylandOutput")); } -QWaylandSurfaceView *QWaylandQuickCompositor::createView(QWaylandSurface *surf) +void QWaylandQuickCompositor::componentComplete() { - return new QWaylandSurfaceItem(static_cast<QWaylandQuickSurface *>(surf)); + create(); } -QWaylandOutput *QWaylandQuickCompositor::createOutput(QWindow *window, - const QString &manufacturer, - const QString &model) +/*! + * Grab the surface content from the given \a buffer. + * Reimplemented from QWaylandCompositor::grabSurface. + */ +void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer) { - QQuickWindow *quickWindow = qobject_cast<QQuickWindow *>(window); - if (!quickWindow) - qFatal("%s: couldn't cast QWindow to QQuickWindow. All output windows must " - "be QQuickWindow derivates when using QWaylandQuickCompositor", Q_FUNC_INFO); - return new QWaylandQuickOutput(this, quickWindow, manufacturer, model); + if (buffer.isShm()) { + QWaylandCompositor::grabSurface(grabber, buffer); + return; + } + + QWaylandQuickOutput *output = static_cast<QWaylandQuickOutput *>(defaultOutput()); + if (!output) { + emit grabber->failed(QWaylandSurfaceGrabber::RendererNotReady); + return; + } + + // We cannot grab the surface now, we need to have a current opengl context, so we + // need to be in the render thread + class GrabState : public QRunnable + { + public: + QWaylandSurfaceGrabber *grabber; + QWaylandBufferRef buffer; + + void run() Q_DECL_OVERRIDE + { + QOpenGLFramebufferObject fbo(buffer.size()); + fbo.bind(); + QOpenGLTextureBlitter blitter; + blitter.create(); + blitter.bind(); + + glViewport(0, 0, buffer.size().width(), buffer.size().height()); + + QOpenGLTextureBlitter::Origin surfaceOrigin = + buffer.origin() == QWaylandSurface::OriginTopLeft + ? QOpenGLTextureBlitter::OriginTopLeft + : QOpenGLTextureBlitter::OriginBottomLeft; + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + buffer.bindToTexture(); + blitter.blit(texture, QMatrix4x4(), surfaceOrigin); + + blitter.release(); + glDeleteTextures(1, &texture); + + emit grabber->success(fbo.toImage()); + } + }; + + GrabState *state = new GrabState; + state->grabber = grabber; + state->buffer = buffer; + static_cast<QQuickWindow *>(output->window())->scheduleRenderJob(state, QQuickWindow::NoStage); } QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.h b/src/compositor/compositor_api/qwaylandquickcompositor.h index c43e4b267..f6fb118a0 100644 --- a/src/compositor/compositor_api/qwaylandquickcompositor.h +++ b/src/compositor/compositor_api/qwaylandquickcompositor.h @@ -3,9 +3,9 @@ ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -34,24 +37,28 @@ #ifndef QWAYLANDQUICKCOMPOSITOR_H #define QWAYLANDQUICKCOMPOSITOR_H -#include <QtCompositor/qwaylandcompositor.h> +#include <QtWaylandCompositor/qwaylandcompositor.h> +#include <QtQml/QQmlParserStatus> QT_BEGIN_NAMESPACE class QQuickWindow; class QWaylandQuickCompositorPrivate; -class QWaylandSurfaceView; -class QWaylandOutput; +class QWaylandView; -class Q_COMPOSITOR_EXPORT QWaylandQuickCompositor : public QWaylandCompositor +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickCompositor : public QWaylandCompositor, public QQmlParserStatus { + Q_INTERFACES(QQmlParserStatus) + Q_OBJECT public: - QWaylandQuickCompositor(const char *socketName = Q_NULLPTR, QWaylandCompositor::ExtensionFlags extensions = DefaultExtensions); + QWaylandQuickCompositor(QObject *parent = nullptr); + void create() Q_DECL_OVERRIDE; - QWaylandSurfaceView *createView(QWaylandSurface *surf) Q_DECL_OVERRIDE; - QWaylandOutput *createOutput(QWindow *window, - const QString &manufacturer, - const QString &model) Q_DECL_OVERRIDE; + void grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer) Q_DECL_OVERRIDE; + +protected: + void classBegin() Q_DECL_OVERRIDE; + void componentComplete() Q_DECL_OVERRIDE; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp new file mode 100644 index 000000000..f9cf45ff6 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -0,0 +1,1169 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandquickitem.h" +#include "qwaylandquickitem_p.h" +#include "qwaylandquicksurface.h" +#include "qwaylandinputmethodcontrol.h" +#include "qwaylandtextinput.h" +#include <QtWaylandCompositor/qwaylandcompositor.h> +#include <QtWaylandCompositor/qwaylandinput.h> +#include <QtWaylandCompositor/qwaylandbufferref.h> +#include <QtWaylandCompositor/private/qwlclientbufferintegration_p.h> + +#include <QtGui/QKeyEvent> +#include <QtGui/QGuiApplication> +#include <QtGui/QScreen> + +#include <QtQuick/QSGSimpleTextureNode> +#include <QtQuick/QQuickWindow> + +#include <QtCore/QMutexLocker> +#include <QtCore/QMutex> + +#include <wayland-server.h> +#include <QThread> + +#ifndef GL_TEXTURE_EXTERNAL_OES +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#endif + +QT_BEGIN_NAMESPACE + +static const struct { + const char * const vertexShaderSourceFile; + const char * const fragmentShaderSourceFile; + GLenum textureTarget; + int planeCount; + bool canProvideTexture; + QSGMaterial::Flags materialFlags; + QSGMaterialType materialType; +} bufferTypes[] = { + // BufferFormatEgl_Null + { "", "", 0, 0, false, 0, {} }, + + // BufferFormatEgl_RGB + { + ":/qt-project.org/wayland/compositor/shaders/surface.vert", + ":/qt-project.org/wayland/compositor/shaders/surface_rgbx.frag", + GL_TEXTURE_2D, 1, true, + QSGMaterial::Blending, + {} + }, + + // BufferFormatEgl_RGBA + { + ":/qt-project.org/wayland/compositor/shaders/surface.vert", + ":/qt-project.org/wayland/compositor/shaders/surface_rgba.frag", + GL_TEXTURE_2D, 1, true, + QSGMaterial::Blending, + {} + }, + + // BufferFormatEgl_EXTERNAL_OES + { + ":/qt-project.org/wayland/compositor/shaders/surface.vert", + ":/qt-project.org/wayland/compositor/shaders/surface_oes_external.frag", + GL_TEXTURE_EXTERNAL_OES, 1, false, + QSGMaterial::Blending, + {} + }, + + // BufferFormatEgl_Y_U_V + { + ":/qt-project.org/wayland/compositor/shaders/surface.vert", + ":/qt-project.org/wayland/compositor/shaders/surface_y_u_v.frag", + GL_TEXTURE_2D, 3, false, + QSGMaterial::Blending, + {} + }, + + // BufferFormatEgl_Y_UV + { + ":/qt-project.org/wayland/compositor/shaders/surface.vert", + ":/qt-project.org/wayland/compositor/shaders/surface_y_uv.frag", + GL_TEXTURE_2D, 2, false, + QSGMaterial::Blending, + {} + }, + + // BufferFormatEgl_Y_XUXV + { + ":/qt-project.org/wayland/compositor/shaders/surface.vert", + ":/qt-project.org/wayland/compositor/shaders/surface_y_xuxv.frag", + GL_TEXTURE_2D, 2, false, + QSGMaterial::Blending, + {} + } +}; + +QWaylandBufferMaterialShader::QWaylandBufferMaterialShader(QWaylandBufferRef::BufferFormatEgl format) + : QSGMaterialShader() + , m_format(format) +{ + setShaderSourceFile(QOpenGLShader::Vertex, QString::fromLatin1(bufferTypes[format].vertexShaderSourceFile)); + setShaderSourceFile(QOpenGLShader::Fragment, QString::fromLatin1(bufferTypes[format].fragmentShaderSourceFile)); +} + +void QWaylandBufferMaterialShader::updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +{ + QSGMaterialShader::updateState(state, newEffect, oldEffect); + + QWaylandBufferMaterial *material = static_cast<QWaylandBufferMaterial *>(newEffect); + material->bind(); + + if (state.isMatrixDirty()) + program()->setUniformValue(m_id_matrix, state.combinedMatrix()); + + if (state.isOpacityDirty()) + program()->setUniformValue(m_id_opacity, state.opacity()); +} + +const char * const *QWaylandBufferMaterialShader::attributeNames() const +{ + static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 }; + return attr; +} + +void QWaylandBufferMaterialShader::initialize() +{ + QSGMaterialShader::initialize(); + + m_id_matrix = program()->uniformLocation("qt_Matrix"); + m_id_opacity = program()->uniformLocation("qt_Opacity"); + + for (int i = 0; i < bufferTypes[m_format].planeCount; i++) { + m_id_tex << program()->uniformLocation("tex" + QByteArray::number(i)); + program()->setUniformValue(m_id_tex[i], i); + } + + Q_ASSERT(m_id_tex.size() == bufferTypes[m_format].planeCount); +} + +QWaylandBufferMaterial::QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEgl format) + : QSGMaterial() + , m_format(format) +{ + QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); + + gl->glBindTexture(bufferTypes[m_format].textureTarget, 0); + setFlag(bufferTypes[m_format].materialFlags); +} + +QWaylandBufferMaterial::~QWaylandBufferMaterial() +{ + QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); + + for (GLuint texture : m_textures) + gl->glDeleteTextures(1, &texture); +} + +void QWaylandBufferMaterial::setTextureForPlane(int plane, uint texture) +{ + if (plane < 0 || plane >= bufferTypes[m_format].planeCount) { + qWarning("plane index is out of range"); + return; + } + + QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); + const GLenum target = bufferTypes[m_format].textureTarget; + + gl->glBindTexture(target, texture); + setTextureParameters(target); + + ensureTextures(plane - 1); + + if (m_textures.size() <= plane) { + m_textures << texture; + } else { + std::swap(m_textures[plane], texture); + gl->glDeleteTextures(1, &texture); + } +} + +void QWaylandBufferMaterial::bind() +{ + QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); + const GLenum target = bufferTypes[m_format].textureTarget; + + ensureTextures(bufferTypes[m_format].planeCount); + + switch (m_textures.size()) { + case 3: + gl->glActiveTexture(GL_TEXTURE2); + gl->glBindTexture(target, m_textures[2]); + case 2: + gl->glActiveTexture(GL_TEXTURE1); + gl->glBindTexture(target, m_textures[1]); + case 1: + gl->glActiveTexture(GL_TEXTURE0); + gl->glBindTexture(target, m_textures[0]); + } +} + +QSGMaterialType *QWaylandBufferMaterial::type() const +{ + return const_cast<QSGMaterialType *>(&bufferTypes[m_format].materialType); +} + +QSGMaterialShader *QWaylandBufferMaterial::createShader() const +{ + return new QWaylandBufferMaterialShader(m_format); +} + + +void QWaylandBufferMaterial::setTextureParameters(GLenum target) +{ + QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); + gl->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +} + +//TODO move this into a separate centralized texture management class +void QWaylandBufferMaterial::ensureTextures(int count) +{ + QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions(); + const GLenum target = bufferTypes[m_format].textureTarget; + GLuint texture; + + for (int plane = m_textures.size(); plane < count; plane++) { + gl->glGenTextures(1, &texture); + gl->glBindTexture(target, texture); + setTextureParameters(target); + m_textures << texture; + } +} + +QMutex *QWaylandQuickItemPrivate::mutex = 0; + +class QWaylandSurfaceTextureProvider : public QSGTextureProvider +{ +public: + QWaylandSurfaceTextureProvider() + : m_smooth(false) + , m_sgTex(0) + { + } + + ~QWaylandSurfaceTextureProvider() + { + if (m_sgTex) + m_sgTex->deleteLater(); + } + + void setBufferRef(QWaylandQuickItem *surfaceItem, const QWaylandBufferRef &buffer) + { + Q_ASSERT(QThread::currentThread() == thread()); + m_ref = buffer; + delete m_sgTex; + m_sgTex = 0; + if (m_ref.hasBuffer()) { + if (buffer.isShm()) { + m_sgTex = surfaceItem->window()->createTextureFromImage(buffer.image()); + if (m_sgTex) { + m_sgTex->bind(); + } + } else { + QQuickWindow::CreateTextureOptions opt = QQuickWindow::TextureOwnsGLTexture; + QWaylandQuickSurface *surface = qobject_cast<QWaylandQuickSurface *>(surfaceItem->surface()); + if (surface && surface->useTextureAlpha()) { + opt |= QQuickWindow::TextureHasAlphaChannel; + } + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + buffer.bindToTexture(); + m_sgTex = surfaceItem->window()->createTextureFromId(texture , QSize(surfaceItem->width(), surfaceItem->height()), opt); + } + } + emit textureChanged(); + } + + QSGTexture *texture() const Q_DECL_OVERRIDE + { + if (m_sgTex) + m_sgTex->setFiltering(m_smooth ? QSGTexture::Linear : QSGTexture::Nearest); + return m_sgTex; + } + + void setSmooth(bool smooth) { m_smooth = smooth; } +private: + bool m_smooth; + QSGTexture *m_sgTex; + QWaylandBufferRef m_ref; +}; + +/*! + * \qmltype WaylandQuickItem + * \inqmlmodule QtWayland.Compositor + * \preliminary + * \brief A Qt Quick item representing a WaylandView. + * + * When writing a WaylandCompositor in Qt Quick, this type can be used to display a + * client's contents on an output device and will pass user input to the + * client. + */ + +/*! + * \class QWaylandQuickItem + * \inmodule QtWaylandCompositor + * \preliminary + * \brief A Qt Quick item representing a QWaylandView. + * + * When writing a QWaylandCompositor in Qt Quick, this class can be used to display a + * client's contents on an output device and will pass user input to the + * client. + */ + +/*! + * Constructs a QWaylandQuickItem with the given \a parent. + */ +QWaylandQuickItem::QWaylandQuickItem(QQuickItem *parent) + : QQuickItem(*new QWaylandQuickItemPrivate(), parent) +{ + d_func()->init(); +} + +/*! + * \internal + */ +QWaylandQuickItem::QWaylandQuickItem(QWaylandQuickItemPrivate &dd, QQuickItem *parent) + : QQuickItem(dd, parent) +{ + d_func()->init(); +} + +/*! + * Destroy the QWaylandQuickItem. + */ +QWaylandQuickItem::~QWaylandQuickItem() +{ + Q_D(QWaylandQuickItem); + disconnect(this, &QQuickItem::windowChanged, this, &QWaylandQuickItem::updateWindow); + QMutexLocker locker(d->mutex); + if (d->provider) + d->provider->deleteLater(); +} + +/*! + * \qmlproperty object QtWaylandCompositor::WaylandQuickItem::compositor + * + * This property holds the compositor for the surface rendered by this WaylandQuickItem. + */ + +/*! + * \property QWaylandQuickItem::compositor + * + * This property holds the compositor for the surface rendered by this QWaylandQuickItem. + */ +QWaylandCompositor *QWaylandQuickItem::compositor() const +{ + Q_D(const QWaylandQuickItem); + return d->view->surface() ? d->view->surface()->compositor() : Q_NULLPTR; +} + +/*! + * \qmlproperty object QWaylandQuickItem::view + * + * This property holds the view rendered by this WaylandQuickItem. + */ + +/*! + * \property QWaylandQuickItem::view + * + * This property holds the view rendered by this QWaylandQuickItem. + */ +QWaylandView *QWaylandQuickItem::view() const +{ + Q_D(const QWaylandQuickItem); + return d->view.data(); +} + +/*! + * \qmlproperty object QWaylandQuickItem::surface + * + * This property holds the surface rendered by this WaylandQuickItem. + */ + +/*! + * \property QWaylandQuickItem::surface + * + * This property holds the surface rendered by this QWaylandQuickItem. + */ + +QWaylandSurface *QWaylandQuickItem::surface() const +{ + Q_D(const QWaylandQuickItem); + return d->view->surface(); +} + +void QWaylandQuickItem::setSurface(QWaylandSurface *surface) +{ + Q_D(QWaylandQuickItem); + d->view->setSurface(surface); + update(); +} + +/*! + * \qmlproperty enum QtWaylandCompositor::WaylandQuickItem::origin + * + * This property holds the origin of the QWaylandQuickItem. + */ + +/*! + * \property QWaylandQuickItem::origin + * + * This property holds the origin of the QWaylandQuickItem. + */ +QWaylandSurface::Origin QWaylandQuickItem::origin() const +{ + Q_D(const QWaylandQuickItem); + return d->origin; +} + +bool QWaylandQuickItem::isTextureProvider() const +{ + Q_D(const QWaylandQuickItem); + return QQuickItem::isTextureProvider() || d->provider; +} + +/*! + * Returns the texture provider of this QWaylandQuickItem. + */ +QSGTextureProvider *QWaylandQuickItem::textureProvider() const +{ + Q_D(const QWaylandQuickItem); + + if (QQuickItem::isTextureProvider()) + return QQuickItem::textureProvider(); + + return d->provider; +} + +/*! + * \internal + */ +void QWaylandQuickItem::mousePressEvent(QMouseEvent *event) +{ + Q_D(QWaylandQuickItem); + if (!d->shouldSendInputEvents()) { + event->ignore(); + return; + } + + if (!inputRegionContains(event->pos())) { + event->ignore(); + return; + } + + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + + if (d->focusOnClick) + takeFocus(inputDevice); + + inputDevice->sendMouseMoveEvent(d->view.data(), event->localPos() / d->scaleFactor(), event->windowPos()); + inputDevice->sendMousePressEvent(event->button()); +} + +/*! + * \internal + */ +void QWaylandQuickItem::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QWaylandQuickItem); + if (d->shouldSendInputEvents()) { + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + inputDevice->sendMouseMoveEvent(d->view.data(), event->localPos() / d->scaleFactor(), event->windowPos()); + } else { + emit mouseMove(event->windowPos()); + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QWaylandQuickItem); + if (d->shouldSendInputEvents()) { + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + inputDevice->sendMouseReleaseEvent(event->button()); + } else { + emit mouseRelease(); + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::hoverEnterEvent(QHoverEvent *event) +{ + Q_D(QWaylandQuickItem); + if (!inputRegionContains(event->pos())) { + event->ignore(); + return; + } + if (d->shouldSendInputEvents()) { + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + inputDevice->sendMouseMoveEvent(d->view.data(), event->pos(), mapToScene(event->pos())); + } else { + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::hoverMoveEvent(QHoverEvent *event) +{ + Q_D(QWaylandQuickItem); + if (surface()) { + if (!inputRegionContains(event->pos())) { + event->ignore(); + return; + } + } + if (d->shouldSendInputEvents()) { + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + inputDevice->sendMouseMoveEvent(d->view.data(), event->pos() / d->scaleFactor(), mapToScene(event->pos())); + } else { + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::hoverLeaveEvent(QHoverEvent *event) +{ + Q_D(QWaylandQuickItem); + if (d->shouldSendInputEvents()) { + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + inputDevice->setMouseFocus(Q_NULLPTR); + } else { + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::wheelEvent(QWheelEvent *event) +{ + Q_D(QWaylandQuickItem); + if (d->shouldSendInputEvents()) { + if (!inputRegionContains(event->pos())) { + event->ignore(); + return; + } + + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + inputDevice->sendMouseWheelEvent(event->orientation(), event->delta()); + } else { + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::keyPressEvent(QKeyEvent *event) +{ + Q_D(QWaylandQuickItem); + if (d->shouldSendInputEvents()) { + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + inputDevice->sendFullKeyEvent(event); + } else { + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QWaylandQuickItem); + if (d->shouldSendInputEvents() && hasFocus()) { + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + inputDevice->sendFullKeyEvent(event); + } else { + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::touchEvent(QTouchEvent *event) +{ + Q_D(QWaylandQuickItem); + if (d->shouldSendInputEvents() && d->touchEventsEnabled) { + QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); + + if (event->type() == QEvent::TouchBegin) { + QQuickItem *grabber = window()->mouseGrabberItem(); + if (grabber != this) + grabMouse(); + } + + QPoint pointPos; + const QList<QTouchEvent::TouchPoint> &points = event->touchPoints(); + if (!points.isEmpty()) + pointPos = points.at(0).pos().toPoint(); + + if (event->type() == QEvent::TouchBegin && !inputRegionContains(pointPos)) { + event->ignore(); + return; + } + + event->accept(); + if (inputDevice->mouseFocus() != d->view.data()) { + inputDevice->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos)); + } + inputDevice->sendFullTouchEvent(event); + } else { + event->ignore(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::mouseUngrabEvent() +{ + if (surface()) { + QTouchEvent e(QEvent::TouchCancel); + touchEvent(&e); + } +} + +#ifndef QT_NO_IM +/*! + * \internal + */ +void QWaylandQuickItem::inputMethodEvent(QInputMethodEvent *event) +{ + Q_D(QWaylandQuickItem); + if (d->shouldSendInputEvents()) { + d->oldSurface->inputMethodControl()->inputMethodEvent(event); + } else { + event->ignore(); + } +} +#endif + +/*! + * \internal + */ +void QWaylandQuickItem::surfaceChangedEvent(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) +{ + Q_UNUSED(newSurface); + Q_UNUSED(oldSurface); +} + +void QWaylandQuickItem::handleSubsurfaceAdded(QWaylandSurface *childSurface) +{ + Q_D(QWaylandQuickItem); + if (d->subsurfaceHandler.isNull()) { + QWaylandQuickItem *childItem = new QWaylandQuickItem; + childItem->setSurface(childSurface); + childItem->setVisible(true); + childItem->setParentItem(this); + connect(childSurface, &QWaylandSurface::subsurfacePositionChanged, childItem, &QWaylandQuickItem::handleSubsurfacePosition); + } else { + bool success = QMetaObject::invokeMethod(d->subsurfaceHandler, "handleSubsurfaceAdded", Q_ARG(QWaylandSurface *, childSurface)); + if (!success) + qWarning("QWaylandQuickItem: subsurfaceHandler does not implement handleSubsurfaceAdded()"); + } +} + + + +/*! + \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::subsurfaceHandler + + This property provides a way to override the default subsurface behavior. + + By default, Qt will create a new SurfaceItem as a child of this item, and maintain the correct position. + + To override the default, assign a handler object to this property. The handler should implement + a handleSubsurfaceAdded(WaylandSurface) function. + + \code + ShellSurfaceItem { + subsurfaceHandler: QtObject { + function handleSubsurfaceAdded(child) { + //create custom surface item, and connect the subsurfacePositionChanged signal + } + } + \endcode + + The default value of this property is \c null. + */ + + +QObject *QWaylandQuickItem::subsurfaceHandler() const +{ + Q_D(const QWaylandQuickItem); + return d->subsurfaceHandler.data(); +} + +void QWaylandQuickItem::setSubsurfaceHandler(QObject *handler) +{ + Q_D(QWaylandQuickItem); + if (d->subsurfaceHandler.data() != handler) { + d->subsurfaceHandler = handler; + emit subsurfaceHandlerChanged(); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::handleSurfaceChanged() +{ + Q_D(QWaylandQuickItem); + if (d->oldSurface) { + disconnect(d->oldSurface, &QWaylandSurface::mappedChanged, this, &QWaylandQuickItem::surfaceMappedChanged); + disconnect(d->oldSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged); + disconnect(d->oldSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize); + disconnect(d->oldSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize); + disconnect(d->oldSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer); + disconnect(d->oldSurface, &QWaylandSurface::redraw, this, &QQuickItem::update); + disconnect(d->oldSurface, &QWaylandSurface::childAdded, this, &QWaylandQuickItem::handleSubsurfaceAdded); +#ifndef QT_NO_IM + disconnect(d->oldSurface->inputMethodControl(), &QWaylandInputMethodControl::updateInputMethod, this, &QWaylandQuickItem::updateInputMethod); +#endif + } + if (QWaylandSurface *newSurface = d->view->surface()) { + connect(newSurface, &QWaylandSurface::mappedChanged, this, &QWaylandQuickItem::surfaceMappedChanged); + connect(newSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged); + connect(newSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize); + connect(newSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize); + connect(newSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer); + connect(newSurface, &QWaylandSurface::redraw, this, &QQuickItem::update); + connect(newSurface, &QWaylandSurface::childAdded, this, &QWaylandQuickItem::handleSubsurfaceAdded); +#ifndef QT_NO_IM + connect(newSurface->inputMethodControl(), &QWaylandInputMethodControl::updateInputMethod, this, &QWaylandQuickItem::updateInputMethod); +#endif + + if (newSurface->origin() != d->origin) { + d->origin = newSurface->origin(); + emit originChanged(); + } + if (window()) { + QWaylandOutput *output = newSurface->compositor()->outputFor(window()); + d->view->setOutput(output); + } + + updateSize(); + } + surfaceChangedEvent(d->view->surface(), d->oldSurface); + d->oldSurface = d->view->surface(); +#ifndef QT_NO_IM + updateInputMethod(Qt::ImQueryInput); +#endif +} + +/*! + * Calling this function causes the item to take the focus of the + * input \a device. + */ +void QWaylandQuickItem::takeFocus(QWaylandInputDevice *device) +{ + forceActiveFocus(); + + if (!surface()) + return; + + QWaylandInputDevice *target = device; + if (!target) { + target = compositor()->defaultInputDevice(); + } + target->setKeyboardFocus(surface()); + QWaylandTextInput *textInput = QWaylandTextInput::findIn(target); + if (textInput) + textInput->setFocus(surface()); +} + +/*! + * \internal + */ +void QWaylandQuickItem::surfaceMappedChanged() +{ + update(); +} + +/*! + * \internal + */ +void QWaylandQuickItem::parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent) +{ + Q_UNUSED(oldParent); + + if (newParent) { + setPaintEnabled(true); + setVisible(true); + setOpacity(1); + setEnabled(true); + } +} + +/*! + * \internal + */ +void QWaylandQuickItem::updateSize() +{ + Q_D(QWaylandQuickItem); + if (d->sizeFollowsSurface && surface()) { + setSize(surface()->size() * (d->scaleFactor() / surface()->bufferScale())); + } +} + +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::focusOnClick + * + * This property specifies whether the WaylandQuickItem should take focus when + * it is clicked. + * + * The default is true. + */ + +/*! + * \property QWaylandQuickItem::focusOnClick + * + * This property specifies whether the QWaylandQuickItem should take focus when + * it is clicked. + * + * The default is true. + */ +bool QWaylandQuickItem::focusOnClick() const +{ + Q_D(const QWaylandQuickItem); + return d->focusOnClick; +} + +void QWaylandQuickItem::setFocusOnClick(bool focus) +{ + Q_D(QWaylandQuickItem); + if (d->focusOnClick == focus) + return; + + d->focusOnClick = focus; + emit focusOnClickChanged(); +} + +/*! + * Returns true if the input region of this item's surface contains the + * position given by \a localPosition. + */ +bool QWaylandQuickItem::inputRegionContains(const QPointF &localPosition) +{ + Q_D(QWaylandQuickItem); + if (QWaylandSurface *s = surface()) + return s->inputRegionContains(localPosition.toPoint() / d->scaleFactor()); + return false; +} + +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::sizeFollowsSurface + * + * This property specifies whether the size of the item should always match + * the size of its surface. + * + * The default is true. + */ + +/*! + * \property QWaylandQuickItem::sizeFollowsSurface + * + * This property specifies whether the size of the item should always match + * the size of its surface. + * + * The default is true. + */ +bool QWaylandQuickItem::sizeFollowsSurface() const +{ + Q_D(const QWaylandQuickItem); + return d->sizeFollowsSurface; +} + +void QWaylandQuickItem::setSizeFollowsSurface(bool sizeFollowsSurface) +{ + Q_D(QWaylandQuickItem); + if (d->sizeFollowsSurface == sizeFollowsSurface) + return; + d->sizeFollowsSurface = sizeFollowsSurface; + emit sizeFollowsSurfaceChanged(); +} + +#ifndef QT_NO_IM +QVariant QWaylandQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const +{ + return inputMethodQuery(query, QVariant()); +} + +QVariant QWaylandQuickItem::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const +{ + Q_D(const QWaylandQuickItem); + + if (query == Qt::ImEnabled) + return QVariant((flags() & ItemAcceptsInputMethod) != 0); + + if (d->oldSurface) + return d->oldSurface->inputMethodControl()->inputMethodQuery(query, argument); + + return QVariant(); +} +#endif + +/*! + \qmlproperty bool QtWayland::QWaylandSurfaceItem::paintEnabled + + If this property is true, the \l item is hidden, though the texture + will still be updated. As opposed to hiding the \l item by + setting \l{Item::visible}{visible} to false, setting this property to true + will not prevent mouse or keyboard input from reaching \l item. +*/ +bool QWaylandQuickItem::paintEnabled() const +{ + Q_D(const QWaylandQuickItem); + return d->paintEnabled; +} + +void QWaylandQuickItem::setPaintEnabled(bool enabled) +{ + Q_D(QWaylandQuickItem); + d->paintEnabled = enabled; + update(); +} + +bool QWaylandQuickItem::touchEventsEnabled() const +{ + Q_D(const QWaylandQuickItem); + return d->touchEventsEnabled; +} + +void QWaylandQuickItem::updateBuffer(bool hasBuffer) +{ + Q_D(QWaylandQuickItem); + Q_UNUSED(hasBuffer); + if (d->origin != surface()->origin()) { + d->origin = surface()->origin(); + emit originChanged(); + } +} + +void QWaylandQuickItem::updateWindow() +{ + Q_D(QWaylandQuickItem); + if (d->connectedWindow) { + disconnect(d->connectedWindow, &QQuickWindow::beforeSynchronizing, this, &QWaylandQuickItem::beforeSync); + } + + d->connectedWindow = window(); + + if (d->connectedWindow) { + connect(d->connectedWindow, &QQuickWindow::beforeSynchronizing, this, &QWaylandQuickItem::beforeSync, Qt::DirectConnection); + } + + if (compositor() && d->connectedWindow) { + QWaylandOutput *output = compositor()->outputFor(d->connectedWindow); + Q_ASSERT(output); + d->view->setOutput(output); + } +} + +void QWaylandQuickItem::beforeSync() +{ + Q_D(QWaylandQuickItem); + if (d->view->advance()) { + d->newTexture = true; + update(); + } +} + +#ifndef QT_NO_IM +void QWaylandQuickItem::updateInputMethod(Qt::InputMethodQueries queries) +{ + Q_D(QWaylandQuickItem); + + setFlag(QQuickItem::ItemAcceptsInputMethod, + d->oldSurface ? d->oldSurface->inputMethodControl()->enabled() : false); + QQuickItem::updateInputMethod(queries | Qt::ImEnabled); +} +#endif + +QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + Q_D(QWaylandQuickItem); + const bool mapped = surface() && surface()->isMapped() && d->view->currentBuffer().hasBuffer(); + + if (!mapped || !d->paintEnabled) { + delete oldNode; + return 0; + } + + QWaylandBufferRef ref = d->view->currentBuffer(); + const bool invertY = ref.origin() == QWaylandSurface::OriginBottomLeft; + const QRectF rect = invertY ? QRectF(0, height(), width(), -height()) + : QRectF(0, 0, width(), height()); + + if (ref.isShm() || bufferTypes[ref.bufferFormatEgl()].canProvideTexture) { + QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode); + + if (!node) { + node = new QSGSimpleTextureNode(); + d->newTexture = true; + } + + if (!d->provider) + d->provider = new QWaylandSurfaceTextureProvider(); + + if (d->newTexture) { + d->newTexture = false; + d->provider->setBufferRef(this, ref); + node->setTexture(d->provider->texture()); + } + + d->provider->setSmooth(smooth()); + node->setRect(rect); + + return node; + } else { + Q_ASSERT(!d->provider); + + QSGGeometryNode *node = static_cast<QSGGeometryNode *>(oldNode); + + if (!node) { + node = new QSGGeometryNode; + d->newTexture = true; + } + + QSGGeometry *geometry = node->geometry(); + QWaylandBufferMaterial *material = static_cast<QWaylandBufferMaterial *>(node->material()); + + if (!geometry) + geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4); + + if (!material) + material = new QWaylandBufferMaterial(ref.bufferFormatEgl()); + + if (d->newTexture) { + d->newTexture = false; + for (int plane = 0; plane < bufferTypes[ref.bufferFormatEgl()].planeCount; plane++) + if (uint texture = ref.textureForPlane(plane)) + material->setTextureForPlane(plane, texture); + material->bind(); + ref.bindToTexture(); + } + + ref.updateTexture(); + QSGGeometry::updateTexturedRectGeometry(geometry, rect, QRectF(0, 0, 1, 1)); + + node->setGeometry(geometry); + node->setFlag(QSGNode::OwnsGeometry, true); + + node->setMaterial(material); + node->setFlag(QSGNode::OwnsMaterial, true); + + return node; + } + + Q_UNREACHABLE(); +} + +void QWaylandQuickItem::setTouchEventsEnabled(bool enabled) +{ + Q_D(QWaylandQuickItem); + if (d->touchEventsEnabled != enabled) { + d->touchEventsEnabled = enabled; + emit touchEventsEnabledChanged(); + } +} + +bool QWaylandQuickItem::inputEventsEnabled() const +{ + Q_D(const QWaylandQuickItem); + return d->inputEventsEnabled; +} + +void QWaylandQuickItem::setInputEventsEnabled(bool enabled) +{ + Q_D(QWaylandQuickItem); + if (d->inputEventsEnabled != enabled) { + d->setInputEventsEnabled(enabled); + emit inputEventsEnabledChanged(); + } +} + +void QWaylandQuickItem::lower() +{ + QQuickItem *parent = parentItem(); + Q_ASSERT(parent); + QQuickItem *bottom = parent->childItems().first(); + if (this != bottom) + stackBefore(bottom); +} + +void QWaylandQuickItem::raise() +{ + QQuickItem *parent = parentItem(); + Q_ASSERT(parent); + QQuickItem *top = parent->childItems().last(); + if (this != top) + stackAfter(top); +} + +/*! + * \internal + * + * Sets the position of this item relative to the parent item. + */ +void QWaylandQuickItem::handleSubsurfacePosition(const QPoint &pos) +{ + Q_D(QWaylandQuickItem); + QQuickItem::setPosition(pos * d->scaleFactor()); +} + +QT_END_NAMESPACE + diff --git a/src/compositor/compositor_api/qwaylandquickitem.h b/src/compositor/compositor_api/qwaylandquickitem.h new file mode 100644 index 000000000..07b6a40a4 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquickitem.h @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSURFACEITEM_H +#define QWAYLANDSURFACEITEM_H + +#include <QtWaylandCompositor/qwaylandexport.h> + +#include <QtQuick/QQuickItem> +#include <QtQuick/qsgtexture.h> + +#include <QtQuick/qsgtextureprovider.h> + +#include <QtWaylandCompositor/qwaylandview.h> +#include <QtWaylandCompositor/qwaylandquicksurface.h> + +Q_DECLARE_METATYPE(QWaylandQuickSurface*) + +QT_BEGIN_NAMESPACE + +class QWaylandInputDevice; +class QWaylandQuickItemPrivate; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickItem : public QQuickItem +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandQuickItem) + Q_PROPERTY(QWaylandView *view READ view CONSTANT) + Q_PROPERTY(QWaylandCompositor *compositor READ compositor) + Q_PROPERTY(QWaylandSurface *surface READ surface WRITE setSurface NOTIFY surfaceChanged) + Q_PROPERTY(bool paintEnabled READ paintEnabled WRITE setPaintEnabled) + Q_PROPERTY(bool touchEventsEnabled READ touchEventsEnabled WRITE setTouchEventsEnabled NOTIFY touchEventsEnabledChanged) + Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged) + Q_PROPERTY(bool inputEventsEnabled READ inputEventsEnabled WRITE setInputEventsEnabled NOTIFY inputEventsEnabledChanged) + Q_PROPERTY(bool focusOnClick READ focusOnClick WRITE setFocusOnClick NOTIFY focusOnClickChanged) + Q_PROPERTY(bool sizeFollowsSurface READ sizeFollowsSurface WRITE setSizeFollowsSurface NOTIFY sizeFollowsSurfaceChanged) + Q_PROPERTY(QObject *subsurfaceHandler READ subsurfaceHandler WRITE setSubsurfaceHandler NOTIFY subsurfaceHandlerChanged) +public: + QWaylandQuickItem(QQuickItem *parent = nullptr); + ~QWaylandQuickItem(); + + QWaylandCompositor *compositor() const; + QWaylandView *view() const; + + QWaylandSurface *surface() const; + void setSurface(QWaylandSurface *surface); + + QWaylandSurface::Origin origin() const; + + bool isTextureProvider() const Q_DECL_OVERRIDE; + QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE; + + bool paintEnabled() const; + bool touchEventsEnabled() const; + + void setTouchEventsEnabled(bool enabled); + + bool inputEventsEnabled() const; + void setInputEventsEnabled(bool enabled); + + bool focusOnClick() const; + void setFocusOnClick(bool focus); + + bool inputRegionContains(const QPointF &localPosition); + + bool sizeFollowsSurface() const; + void setSizeFollowsSurface(bool sizeFollowsSurface); + +#ifndef QT_NO_IM + QVariant inputMethodQuery(Qt::InputMethodQuery query) const Q_DECL_OVERRIDE; + Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const; +#endif + + QObject *subsurfaceHandler() const; + void setSubsurfaceHandler(QObject*); + +protected: + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void hoverEnterEvent(QHoverEvent *event) Q_DECL_OVERRIDE; + void hoverMoveEvent(QHoverEvent *event) Q_DECL_OVERRIDE; + void hoverLeaveEvent(QHoverEvent *event) Q_DECL_OVERRIDE; + void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; + + void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE; + + void touchEvent(QTouchEvent *event) Q_DECL_OVERRIDE; + void mouseUngrabEvent() Q_DECL_OVERRIDE; + +#ifndef QT_NO_IM + void inputMethodEvent(QInputMethodEvent *event) Q_DECL_OVERRIDE; +#endif + + virtual void surfaceChangedEvent(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); +public Q_SLOTS: + virtual void takeFocus(QWaylandInputDevice *device = nullptr); + void setPaintEnabled(bool paintEnabled); + void raise(); + void lower(); + +private Q_SLOTS: + void surfaceMappedChanged(); + void handleSurfaceChanged(); + void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); + void updateSize(); + void updateBuffer(bool hasBuffer); + void updateWindow(); + void beforeSync(); + void handleSubsurfaceAdded(QWaylandSurface *childSurface); + void handleSubsurfacePosition(const QPoint &pos); +#ifndef QT_NO_IM + void updateInputMethod(Qt::InputMethodQueries queries); +#endif + +Q_SIGNALS: + void surfaceChanged(); + void touchEventsEnabledChanged(); + void originChanged(); + void surfaceDestroyed(); + void inputEventsEnabledChanged(); + void focusOnClickChanged(); + void mouseMove(const QPointF &windowPosition); + void mouseRelease(); + void sizeFollowsSurfaceChanged(); + void subsurfaceHandlerChanged(); +protected: + QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) Q_DECL_OVERRIDE; + + QWaylandQuickItem(QWaylandQuickItemPrivate &dd, QQuickItem *parent = nullptr); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h new file mode 100644 index 000000000..b529ba959 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandquickitem_p.h @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDQUICKITEM_P_H +#define QWAYLANDQUICKITEM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/private/qquickitem_p.h> +#include <QtQuick/QSGMaterialShader> +#include <QtQuick/QSGMaterial> + +#include "qwaylandquickitem.h" + +#include <QtWaylandCompositor/QWaylandOutput> + +QT_BEGIN_NAMESPACE + +class QWaylandSurfaceTextureProvider; +class QMutex; + +class QWaylandBufferMaterialShader : public QSGMaterialShader +{ +public: + QWaylandBufferMaterialShader(QWaylandBufferRef::BufferFormatEgl format); + + void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) Q_DECL_OVERRIDE; + char const *const *attributeNames() const Q_DECL_OVERRIDE; + +protected: + void initialize() Q_DECL_OVERRIDE; + +private: + const QWaylandBufferRef::BufferFormatEgl m_format; + int m_id_matrix; + int m_id_opacity; + QVarLengthArray<int, 3> m_id_tex; +}; + +class QWaylandBufferMaterial : public QSGMaterial +{ +public: + QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEgl format); + ~QWaylandBufferMaterial(); + + void setTextureForPlane(int plane, uint texture); + + void bind(); + + QSGMaterialType *type() const Q_DECL_OVERRIDE; + QSGMaterialShader *createShader() const Q_DECL_OVERRIDE; + +private: + void setTextureParameters(GLenum target); + void ensureTextures(int count); + + const QWaylandBufferRef::BufferFormatEgl m_format; + QVarLengthArray<GLuint, 3> m_textures; +}; + +class QWaylandQuickItemPrivate : public QQuickItemPrivate +{ + Q_DECLARE_PUBLIC(QWaylandQuickItem) +public: + QWaylandQuickItemPrivate() + : QQuickItemPrivate() + , view(Q_NULLPTR) + , oldSurface(Q_NULLPTR) + , provider(Q_NULLPTR) + , paintEnabled(true) + , touchEventsEnabled(false) + , inputEventsEnabled(true) + , newTexture(false) + , focusOnClick(true) + , sizeFollowsSurface(true) + , connectedWindow(Q_NULLPTR) + , origin(QWaylandSurface::OriginTopLeft) + { + } + + void init() + { + Q_Q(QWaylandQuickItem); + if (!mutex) + mutex = new QMutex; + + view.reset(new QWaylandView(q)); + q->setFlag(QQuickItem::ItemHasContents); + + q->update(); + + q->setSmooth(true); + + setInputEventsEnabled(true); + QObject::connect(q, &QQuickItem::windowChanged, q, &QWaylandQuickItem::updateWindow); + QObject::connect(view.data(), &QWaylandView::surfaceChanged, q, &QWaylandQuickItem::surfaceChanged); + QObject::connect(view.data(), &QWaylandView::surfaceChanged, q, &QWaylandQuickItem::handleSurfaceChanged); + QObject::connect(view.data(), &QWaylandView::surfaceDestroyed, q, &QWaylandQuickItem::surfaceDestroyed); + } + + + void setInputEventsEnabled(bool enable) + { + Q_Q(QWaylandQuickItem); + q->setAcceptedMouseButtons(enable ? (Qt::LeftButton | Qt::MiddleButton | Qt::RightButton | + Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::ExtraButton3 | Qt::ExtraButton4 | + Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 | + Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 | + Qt::ExtraButton12 | Qt::ExtraButton13) : Qt::NoButton); + q->setAcceptHoverEvents(enable); + inputEventsEnabled = enable; + } + + bool shouldSendInputEvents() const { return view->surface() && inputEventsEnabled; } + int scaleFactor() const { return view->output() ? view->output()->scaleFactor() : 1; } + + static QMutex *mutex; + + QScopedPointer<QWaylandView> view; + QWaylandSurface *oldSurface; + mutable QWaylandSurfaceTextureProvider *provider; + bool paintEnabled; + bool touchEventsEnabled; + bool inputEventsEnabled; + bool newTexture; + bool focusOnClick; + bool sizeFollowsSurface; + + QQuickWindow *connectedWindow; + QWaylandSurface::Origin origin; + QPointer<QObject> subsurfaceHandler; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDQUICKITEM_P_H*/ diff --git a/src/compositor/compositor_api/qwaylandquickoutput.cpp b/src/compositor/compositor_api/qwaylandquickoutput.cpp index 9199ff84a..8abf6cbb1 100644 --- a/src/compositor/compositor_api/qwaylandquickoutput.cpp +++ b/src/compositor/compositor_api/qwaylandquickoutput.cpp @@ -4,9 +4,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -17,16 +17,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -37,34 +40,84 @@ QT_BEGIN_NAMESPACE -QWaylandQuickOutput::QWaylandQuickOutput(QWaylandCompositor *compositor, QQuickWindow *window, - const QString &manufacturer, const QString &model) - : QWaylandOutput(compositor, window, manufacturer, model) +QWaylandQuickOutput::QWaylandQuickOutput() + : QWaylandOutput() , m_updateScheduled(false) + , m_automaticFrameCallback(true) +{ +} + +QWaylandQuickOutput::QWaylandQuickOutput(QWaylandCompositor *compositor, QWindow *window) + : QWaylandOutput(compositor, window) + , m_updateScheduled(false) + , m_automaticFrameCallback(true) { - connect(window, &QQuickWindow::beforeSynchronizing, - this, &QWaylandQuickOutput::updateStarted, - Qt::DirectConnection); } -QQuickWindow *QWaylandQuickOutput::quickWindow() const +void QWaylandQuickOutput::initialize() { - return static_cast<QQuickWindow *>(window()); + QWaylandOutput::initialize(); + + QQuickWindow *quickWindow = qobject_cast<QQuickWindow *>(window()); + if (!quickWindow) { + qWarning("Initialization error: Could not locate QQuickWindow on initializing QWaylandQuickOutput %p.\n", this); + return; + } + connect(quickWindow, &QQuickWindow::beforeSynchronizing, + this, &QWaylandQuickOutput::updateStarted, + Qt::DirectConnection); + + connect(quickWindow, &QQuickWindow::beforeRendering, + this, &QWaylandQuickOutput::doFrameCallbacks); } void QWaylandQuickOutput::update() { if (!m_updateScheduled) { - quickWindow()->update(); + //don't qobject_cast since we have verified the type in initialize + static_cast<QQuickWindow *>(window())->update(); m_updateScheduled = true; } } +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandOutput::automaticFrameCallback + * + * This property holds whether the WaylandOutput automatically sends frame + * callbacks when rendering. + * + * The default is true. + */ +bool QWaylandQuickOutput::automaticFrameCallback() const +{ + return m_automaticFrameCallback; +} + +void QWaylandQuickOutput::setAutomaticFrameCallback(bool automatic) +{ + if (m_automaticFrameCallback == automatic) + return; + + m_automaticFrameCallback = automatic; + automaticFrameCallbackChanged(); +} + +/*! + * \internal + */ void QWaylandQuickOutput::updateStarted() { m_updateScheduled = false; - compositor()->frameStarted(); - compositor()->cleanupGraphicsResources(); + + if (!compositor()) + return; + + frameStarted(); } +void QWaylandQuickOutput::doFrameCallbacks() +{ + if (m_automaticFrameCallback) + sendFrameCallbacks(); +} QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquickoutput.h b/src/compositor/compositor_api/qwaylandquickoutput.h index 702867104..83091e4c7 100644 --- a/src/compositor/compositor_api/qwaylandquickoutput.h +++ b/src/compositor/compositor_api/qwaylandquickoutput.h @@ -4,9 +4,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -17,16 +17,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -36,29 +39,40 @@ #define QWAYLANDQUICKOUTPUT_H #include <QtQuick/QQuickWindow> -#include <QtCompositor/qwaylandoutput.h> +#include <QtWaylandCompositor/qwaylandoutput.h> QT_BEGIN_NAMESPACE class QWaylandQuickCompositor; class QQuickWindow; -class Q_COMPOSITOR_EXPORT QWaylandQuickOutput : public QWaylandOutput +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickOutput : public QWaylandOutput { Q_OBJECT + Q_PROPERTY(bool automaticFrameCallback READ automaticFrameCallback WRITE setAutomaticFrameCallback NOTIFY automaticFrameCallbackChanged) public: - QWaylandQuickOutput(QWaylandCompositor *compositor, QQuickWindow *window, - const QString &manufacturer, const QString &model); - - QQuickWindow *quickWindow() const; + QWaylandQuickOutput(); + QWaylandQuickOutput(QWaylandCompositor *compositor, QWindow *window); void update() Q_DECL_OVERRIDE; + bool automaticFrameCallback() const; + void setAutomaticFrameCallback(bool automatic); + public Q_SLOTS: void updateStarted(); +Q_SIGNALS: + void automaticFrameCallbackChanged(); + +protected: + void initialize() Q_DECL_OVERRIDE; + private: + void doFrameCallbacks(); + bool m_updateScheduled; + bool m_automaticFrameCallback; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandquicksurface.cpp b/src/compositor/compositor_api/qwaylandquicksurface.cpp index c8edcb6bc..0fc07c6c5 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.cpp +++ b/src/compositor/compositor_api/qwaylandquicksurface.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -35,146 +38,59 @@ #include <QOpenGLTexture> #include <QQuickWindow> #include <QDebug> -#include <QQmlPropertyMap> #include "qwaylandquicksurface.h" #include "qwaylandquickcompositor.h" -#include "qwaylandsurfaceitem.h" -#include "qwaylandoutput.h" -#include <QtCompositor/qwaylandbufferref.h> -#include <QtCompositor/private/qwaylandsurface_p.h> +#include "qwaylandquickitem.h" +#include <QtWaylandCompositor/qwaylandbufferref.h> +#include <QtWaylandCompositor/QWaylandView> +#include <QtWaylandCompositor/private/qwaylandsurface_p.h> -QT_BEGIN_NAMESPACE - -class BufferAttacher : public QWaylandBufferAttacher -{ -public: - BufferAttacher() - : surface(0) - , texture(0) - , update(false) - { - - } - - ~BufferAttacher() - { - if (texture) - texture->deleteLater(); - bufferRef = QWaylandBufferRef(); - nextBuffer = QWaylandBufferRef(); - } - - void attach(const QWaylandBufferRef &ref) Q_DECL_OVERRIDE - { - nextBuffer = ref; - update = true; - } - - void createTexture() - { - bufferRef = nextBuffer; - delete texture; - texture = 0; - - QQuickWindow *window = static_cast<QQuickWindow *>(surface->mainOutput()->window()); - if (nextBuffer) { - if (bufferRef.isShm()) { - texture = window->createTextureFromImage(bufferRef.image()); - } else { - QQuickWindow::CreateTextureOptions opt = 0; - if (surface->useTextureAlpha()) { - opt |= QQuickWindow::TextureHasAlphaChannel; - } - texture = window->createTextureFromId(bufferRef.createTexture(), surface->size(), opt); - } - texture->bind(); - } - - update = false; - } - - void unmap() Q_DECL_OVERRIDE - { - nextBuffer = QWaylandBufferRef(); - update = true; - } - - void invalidateTexture() - { - if (bufferRef) - bufferRef.destroyTexture(); - delete texture; - texture = 0; - update = true; - bufferRef = QWaylandBufferRef(); - } - - QWaylandQuickSurface *surface; - QWaylandBufferRef bufferRef; - QWaylandBufferRef nextBuffer; - QSGTexture *texture; - bool update; -}; +#include <QtWaylandCompositor/private/qwayland-server-surface-extension.h> +#include <QtWaylandCompositor/private/qwlextendedsurface_p.h> +QT_BEGIN_NAMESPACE class QWaylandQuickSurfacePrivate : public QWaylandSurfacePrivate { + Q_DECLARE_PUBLIC(QWaylandQuickSurface) public: - QWaylandQuickSurfacePrivate(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *c, QWaylandQuickSurface *surf) - : QWaylandSurfacePrivate(client, id, version, c, surf) - , buffer(new BufferAttacher) - , compositor(c) + QWaylandQuickSurfacePrivate() + : QWaylandSurfacePrivate() , useTextureAlpha(true) - , windowPropertyMap(new QQmlPropertyMap) , clientRenderingEnabled(true) { - } ~QWaylandQuickSurfacePrivate() { - windowPropertyMap->deleteLater(); - // buffer is deleted automatically by ~Surface(), since it is the assigned attacher - } - - void surface_commit(Resource *resource) Q_DECL_OVERRIDE - { - QWaylandSurfacePrivate::surface_commit(resource); - - Q_FOREACH (QtWayland::Output *output, outputs()) - output->waylandOutput()->update(); } - BufferAttacher *buffer; - QWaylandQuickCompositor *compositor; bool useTextureAlpha; - QQmlPropertyMap *windowPropertyMap; bool clientRenderingEnabled; }; -QWaylandQuickSurface::QWaylandQuickSurface(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *compositor) - : QWaylandSurface(new QWaylandQuickSurfacePrivate(client, id, version, compositor, this)) +QWaylandQuickSurface::QWaylandQuickSurface() + : QWaylandSurface(* new QWaylandQuickSurfacePrivate()) { - Q_D(QWaylandQuickSurface); - d->buffer->surface = this; - setBufferAttacher(d->buffer); - connect(this, &QWaylandSurface::windowPropertyChanged, d->windowPropertyMap, &QQmlPropertyMap::insert); - connect(d->windowPropertyMap, &QQmlPropertyMap::valueChanged, this, &QWaylandSurface::setWindowProperty); } - -QWaylandQuickSurface::~QWaylandQuickSurface() +QWaylandQuickSurface::QWaylandQuickSurface(QWaylandCompositor *compositor, QWaylandClient *client, quint32 id, int version) + : QWaylandSurface(* new QWaylandQuickSurfacePrivate()) { - + initialize(compositor, client, id, version); } -QSGTexture *QWaylandQuickSurface::texture() const +QWaylandQuickSurface::~QWaylandQuickSurface() { - Q_D(const QWaylandQuickSurface); - return d->buffer->texture; + } +/*! + * \qmlproperty QtWaylandCompositor::WaylandSurface::useTextureAlpha + * + * This property specifies whether the surface should use texture alpha. + */ bool QWaylandQuickSurface::useTextureAlpha() const { Q_D(const QWaylandQuickSurface); @@ -187,75 +103,15 @@ void QWaylandQuickSurface::setUseTextureAlpha(bool useTextureAlpha) if (d->useTextureAlpha != useTextureAlpha) { d->useTextureAlpha = useTextureAlpha; emit useTextureAlphaChanged(); - emit configure(d->buffer->bufferRef); + emit configure(d->bufferRef.hasBuffer()); } } -QObject *QWaylandQuickSurface::windowPropertyMap() const -{ - Q_D(const QWaylandQuickSurface); - return d->windowPropertyMap; -} - -bool QWaylandQuickSurface::event(QEvent *e) -{ - if (e->type() == static_cast<QEvent::Type>(QWaylandSurfaceLeaveEvent::WaylandSurfaceLeave)) { - QWaylandSurfaceLeaveEvent *event = static_cast<QWaylandSurfaceLeaveEvent *>(e); - - if (event->output()) { - QQuickWindow *oldWindow = static_cast<QQuickWindow *>(event->output()->window()); - disconnect(oldWindow, &QQuickWindow::beforeSynchronizing, - this, &QWaylandQuickSurface::updateTexture); - disconnect(oldWindow, &QQuickWindow::sceneGraphInvalidated, - this, &QWaylandQuickSurface::invalidateTexture); - disconnect(oldWindow, &QQuickWindow::sceneGraphAboutToStop, - this, &QWaylandQuickSurface::invalidateTexture); - } - - return true; - } - - if (e->type() == static_cast<QEvent::Type>(QWaylandSurfaceEnterEvent::WaylandSurfaceEnter)) { - QWaylandSurfaceEnterEvent *event = static_cast<QWaylandSurfaceEnterEvent *>(e); - - if (event->output()) { - QQuickWindow *window = static_cast<QQuickWindow *>(event->output()->window()); - connect(window, &QQuickWindow::beforeSynchronizing, - this, &QWaylandQuickSurface::updateTexture, - Qt::DirectConnection); - connect(window, &QQuickWindow::sceneGraphInvalidated, - this, &QWaylandQuickSurface::invalidateTexture, - Qt::DirectConnection); - connect(window, &QQuickWindow::sceneGraphAboutToStop, - this, &QWaylandQuickSurface::invalidateTexture, - Qt::DirectConnection); - } - - return true; - } - - return QObject::event(e); -} - -void QWaylandQuickSurface::updateTexture() -{ - Q_D(QWaylandQuickSurface); - const bool update = d->buffer->update; - if (d->buffer->update) - d->buffer->createTexture(); - foreach (QWaylandSurfaceView *view, views()) - static_cast<QWaylandSurfaceItem *>(view)->updateTexture(update); -} - -void QWaylandQuickSurface::invalidateTexture() -{ - Q_D(QWaylandQuickSurface); - d->buffer->invalidateTexture(); - foreach (QWaylandSurfaceView *view, views()) - static_cast<QWaylandSurfaceItem *>(view)->updateTexture(true); - emit redraw(); -} - +/*! + * \qmlproperty QtWaylandCompositor::WaylandSurface::clientRenderingEnabled + * + * This property specifies whether client rendering is enabled for the surface. + */ bool QWaylandQuickSurface::clientRenderingEnabled() const { Q_D(const QWaylandQuickSurface); @@ -268,7 +124,8 @@ void QWaylandQuickSurface::setClientRenderingEnabled(bool enabled) if (d->clientRenderingEnabled != enabled) { d->clientRenderingEnabled = enabled; - sendOnScreenVisibilityChange(enabled); + if (QtWayland::ExtendedSurface *extSurface = QtWayland::ExtendedSurface::findIn(this)) + extSurface->setVisibility(enabled ? QWindow::AutomaticVisibility : QWindow::Hidden); emit clientRenderingEnabledChanged(); } diff --git a/src/compositor/compositor_api/qwaylandquicksurface.h b/src/compositor/compositor_api/qwaylandquicksurface.h index 4c37e6670..cb423da36 100644 --- a/src/compositor/compositor_api/qwaylandquicksurface.h +++ b/src/compositor/compositor_api/qwaylandquicksurface.h @@ -3,9 +3,9 @@ ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -34,50 +37,35 @@ #ifndef QQUICKWAYLANDSURFACE_H #define QQUICKWAYLANDSURFACE_H -#include <QtCompositor/qwaylandsurface.h> +#include <QtWaylandCompositor/qwaylandsurface.h> struct wl_client; QT_BEGIN_NAMESPACE -class QSGTexture; - -class QWaylandSurfaceItem; class QWaylandQuickSurfacePrivate; class QWaylandQuickCompositor; -class Q_COMPOSITOR_EXPORT QWaylandQuickSurface : public QWaylandSurface +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickSurface : public QWaylandSurface { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandQuickSurface) Q_PROPERTY(bool useTextureAlpha READ useTextureAlpha WRITE setUseTextureAlpha NOTIFY useTextureAlphaChanged) Q_PROPERTY(bool clientRenderingEnabled READ clientRenderingEnabled WRITE setClientRenderingEnabled NOTIFY clientRenderingEnabledChanged) - Q_PROPERTY(QObject *windowProperties READ windowPropertyMap CONSTANT) public: - QWaylandQuickSurface(wl_client *client, quint32 id, int version, QWaylandQuickCompositor *compositor); + QWaylandQuickSurface(); + QWaylandQuickSurface(QWaylandCompositor *compositor, QWaylandClient *client, quint32 id, int version); ~QWaylandQuickSurface(); - QSGTexture *texture() const; - bool useTextureAlpha() const; void setUseTextureAlpha(bool useTextureAlpha); bool clientRenderingEnabled() const; void setClientRenderingEnabled(bool enabled); - QObject *windowPropertyMap() const; - -private: - bool event(QEvent *event) Q_DECL_OVERRIDE; - Q_SIGNALS: void useTextureAlphaChanged(); void clientRenderingEnabledChanged(); - -private: - void updateTexture(); - void invalidateTexture(); - }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandresource.cpp b/src/compositor/compositor_api/qwaylandresource.cpp new file mode 100644 index 000000000..aea8c3778 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandresource.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandresource.h" + +QT_BEGIN_NAMESPACE + +QWaylandResource::QWaylandResource() + : m_resource(0) +{ +} + +QWaylandResource::QWaylandResource(wl_resource *resource) + : m_resource(resource) +{ +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandresource.h b/src/compositor/compositor_api/qwaylandresource.h new file mode 100644 index 000000000..bfb4b0969 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandresource.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDRESOURCE_H +#define QWAYLANDRESOURCE_H + +#include <QtCore/QObject> +#include <QtWaylandCompositor/qwaylandexport.h> + +struct wl_resource; + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandResource +{ + Q_GADGET +public: + QWaylandResource(); + explicit QWaylandResource(wl_resource *resource); + + wl_resource *resource() const { return m_resource; } + +private: + wl_resource *m_resource; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QWaylandResource) + +#endif /*QWAYLANDRESOURCE_H*/ diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index f1615521e..c4c004b25 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -4,541 +4,896 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qwaylandsurface.h" +#include "qwaylandsurface_p.h" -#include <private/qobject_p.h> - -#include "wayland_wrapper/qwlsurface_p.h" -#include "wayland_wrapper/qwlextendedsurface_p.h" -#include "wayland_wrapper/qwlsubsurface_p.h" -#include "wayland_wrapper/qwlcompositor_p.h" -#include "wayland_wrapper/qwlshellsurface_p.h" -#include "wayland_wrapper/qwlinputdevice_p.h" #include "wayland_wrapper/qwldatadevice_p.h" #include "wayland_wrapper/qwldatadevicemanager_p.h" +#include "wayland_wrapper/qwlregion_p.h" -#include "qwaylandcompositor.h" -#include "qwaylandclient.h" -#include "qwaylandsurface_p.h" -#include "qwaylandbufferref.h" -#include "qwaylandsurfaceinterface.h" +#include "extensions/qwlextendedsurface_p.h" +#include "qwaylandinputmethodcontrol_p.h" -#include <QtGui/QGuiApplication> -#include <QtGui/QScreen> +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandClient> +#include <QtWaylandCompositor/QWaylandView> +#include <QtWaylandCompositor/QWaylandBufferRef> -QT_BEGIN_NAMESPACE +#include <QtWaylandCompositor/private/qwaylandcompositor_p.h> +#include <QtWaylandCompositor/private/qwaylandview_p.h> +#include <QtWaylandCompositor/private/qwaylandinput_p.h> -const QEvent::Type QWaylandSurfaceEnterEvent::WaylandSurfaceEnter = (QEvent::Type)QEvent::registerEventType(); -const QEvent::Type QWaylandSurfaceLeaveEvent::WaylandSurfaceLeave = (QEvent::Type)QEvent::registerEventType(); +#include <QtCore/private/qobject_p.h> -QWaylandSurfacePrivate::QWaylandSurfacePrivate(wl_client *wlClient, quint32 id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface) - : QtWayland::Surface(wlClient, id, version, compositor, surface) - , closing(false) - , refCount(1) - , client(QWaylandClient::fromWlClient(wlClient)) - , windowType(QWaylandSurface::None) -{} +#include <QtGui/QGuiApplication> +#include <QtGui/QScreen> +#include <QtCore/QDebug> -class QWaylandSurfaceEnterEventPrivate -{ +QT_BEGIN_NAMESPACE + +namespace QtWayland { +class FrameCallback { public: - QWaylandSurfaceEnterEventPrivate(QWaylandOutput *_output) - : output(_output) + FrameCallback(QWaylandSurface *surf, wl_resource *res) + : surface(surf) + , resource(res) + , canSend(false) { +#if WAYLAND_VERSION_MAJOR < 1 || (WAYLAND_VERSION_MAJOR == 1 && WAYLAND_VERSION_MINOR <= 2) + res->data = this; + res->destroy = destroyCallback; +#else + wl_resource_set_implementation(res, 0, this, destroyCallback); +#endif } - - QWaylandOutput *output; + ~FrameCallback() + { + } + void destroy() + { + if (resource) + wl_resource_destroy(resource); + else + delete this; + } + void send(uint time) + { + wl_callback_send_done(resource, time); + wl_resource_destroy(resource); + } + static void destroyCallback(wl_resource *res) + { +#if WAYLAND_VERSION_MAJOR < 1 || (WAYLAND_VERSION_MAJOR == 1 && WAYLAND_VERSION_MINOR <= 2) + FrameCallback *_this = static_cast<FrameCallback *>(res->data); +#else + FrameCallback *_this = static_cast<FrameCallback *>(wl_resource_get_user_data(res)); +#endif + if (_this->surface) + QWaylandSurfacePrivate::get(_this->surface)->removeFrameCallback(_this); + delete _this; + } + QWaylandSurface *surface; + wl_resource *resource; + bool canSend; }; +} +static QRegion infiniteRegion() { + return QRegion(QRect(QPoint(std::numeric_limits<int>::min(), std::numeric_limits<int>::min()), + QPoint(std::numeric_limits<int>::max(), std::numeric_limits<int>::max()))); +} +#ifndef QT_NO_DEBUG +QList<QWaylandSurfacePrivate *> QWaylandSurfacePrivate::uninitializedSurfaces; +#endif -QWaylandSurfaceEnterEvent::QWaylandSurfaceEnterEvent(QWaylandOutput *output) - : QEvent(WaylandSurfaceEnter) - , d(new QWaylandSurfaceEnterEventPrivate(output)) -{ +QWaylandSurfacePrivate::QWaylandSurfacePrivate() + : QtWaylandServer::wl_surface() + , compositor(Q_NULLPTR) + , refCount(1) + , client(Q_NULLPTR) + , buffer(0) + , role(0) + , inputRegion(infiniteRegion()) + , bufferScale(1) + , isCursorSurface(false) + , destroyed(false) + , mapped(false) + , isInitialized(false) + , contentOrientation(Qt::PrimaryOrientation) + , inputMethodControl(Q_NULLPTR) + , subsurface(0) +{ + pending.buffer = 0; + pending.newlyAttached = false; + pending.inputRegion = infiniteRegion(); + pending.bufferScale = 1; +#ifndef QT_NO_DEBUG + addUninitializedSurface(this); +#endif +} + +QWaylandSurfacePrivate::~QWaylandSurfacePrivate() +{ + for (int i = 0; i < views.size(); i++) { + QWaylandViewPrivate::get(views.at(i))->markSurfaceAsDestroyed(q_func()); + } + views.clear(); + + bufferRef = QWaylandBufferRef(); + + for (int i = 0; i < bufferPool.size(); i++) + bufferPool[i]->setDestroyIfUnused(true); + + foreach (QtWayland::FrameCallback *c, pendingFrameCallbacks) + c->destroy(); + foreach (QtWayland::FrameCallback *c, frameCallbacks) + c->destroy(); } -QWaylandSurfaceEnterEvent::~QWaylandSurfaceEnterEvent() +void QWaylandSurfacePrivate::setSize(const QSize &s) { - delete d; + Q_Q(QWaylandSurface); + if (size != s) { + opaqueRegion = QRegion(); + size = s; + q->sizeChanged(); + } } -QWaylandOutput *QWaylandSurfaceEnterEvent::output() const +void QWaylandSurfacePrivate::setBufferScale(int scale) { - return d->output; + Q_Q(QWaylandSurface); + if (scale == bufferScale) + return; + bufferScale = scale; + emit q->bufferScaleChanged(); } +void QWaylandSurfacePrivate::removeFrameCallback(QtWayland::FrameCallback *callback) +{ + pendingFrameCallbacks.removeOne(callback); + frameCallbacks.removeOne(callback); +} -class QWaylandSurfaceLeaveEventPrivate +void QWaylandSurfacePrivate::notifyViewsAboutDestruction() { -public: - QWaylandSurfaceLeaveEventPrivate(QWaylandOutput *_output) - : output(_output) - { + Q_Q(QWaylandSurface); + foreach (QWaylandView *view, views) { + QWaylandViewPrivate::get(view)->markSurfaceAsDestroyed(q); } + if (mapped) { + mapped = false; + emit q->mappedChanged(); + } +} - QWaylandOutput *output; -}; - - -QWaylandSurfaceLeaveEvent::QWaylandSurfaceLeaveEvent(QWaylandOutput *output) - : QEvent(WaylandSurfaceLeave) - , d(new QWaylandSurfaceLeaveEventPrivate(output)) +#ifndef QT_NO_DEBUG +void QWaylandSurfacePrivate::addUninitializedSurface(QWaylandSurfacePrivate *surface) { + Q_ASSERT(!surface->isInitialized); + Q_ASSERT(!uninitializedSurfaces.contains(surface)); + uninitializedSurfaces.append(surface); } -QWaylandSurfaceLeaveEvent::~QWaylandSurfaceLeaveEvent() +void QWaylandSurfacePrivate::removeUninitializedSurface(QWaylandSurfacePrivate *surface) { - delete d; + Q_ASSERT(surface->isInitialized); + bool removed = uninitializedSurfaces.removeOne(surface); + Q_ASSERT(removed); } -QWaylandOutput *QWaylandSurfaceLeaveEvent::output() const +bool QWaylandSurfacePrivate::hasUninitializedSurface() { - return d->output; + return uninitializedSurfaces.size(); } +#endif - -QWaylandSurface::QWaylandSurface(wl_client *client, quint32 id, int version, QWaylandCompositor *compositor) - : QObject(*new QWaylandSurfacePrivate(client, id, version, compositor, this)) +void QWaylandSurfacePrivate::surface_destroy_resource(Resource *) { + Q_Q(QWaylandSurface); + notifyViewsAboutDestruction(); + destroyed = true; + emit q->surfaceDestroyed(); + q->destroy(); } -QWaylandSurface::QWaylandSurface(QWaylandSurfacePrivate *dptr) - : QObject(*dptr) +void QWaylandSurfacePrivate::surface_destroy(Resource *resource) { + wl_resource_destroy(resource->handle); +} +void QWaylandSurfacePrivate::surface_attach(Resource *, struct wl_resource *buffer, int x, int y) +{ + if (pending.buffer) + pending.buffer->disown(); + pending.buffer = createSurfaceBuffer(buffer); + pending.offset = QPoint(x, y); + pending.newlyAttached = true; } -QWaylandSurface::~QWaylandSurface() +void QWaylandSurfacePrivate::surface_damage(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) { - Q_D(QWaylandSurface); - qDeleteAll(d->interfaces); - delete d->m_attacher; + pending.damage = pending.damage.united(QRect(x, y, width, height)); } -QWaylandClient *QWaylandSurface::client() const +void QWaylandSurfacePrivate::surface_frame(Resource *resource, uint32_t callback) { - Q_D(const QWaylandSurface); - if (d->isDestroyed() || !d->compositor()->clients().contains(d->client)) - return Q_NULLPTR; - return d->client; + Q_Q(QWaylandSurface); + struct wl_resource *frame_callback = wl_resource_create(resource->client(), &wl_callback_interface, wl_callback_interface.version, callback); + pendingFrameCallbacks << new QtWayland::FrameCallback(q, frame_callback); } -QWaylandSurface *QWaylandSurface::parentSurface() const +void QWaylandSurfacePrivate::surface_set_opaque_region(Resource *, struct wl_resource *region) { - Q_D(const QWaylandSurface); - if (d->subSurface() && d->subSurface()->parent()) { - return d->subSurface()->parent()->waylandSurface(); + opaqueRegion = region ? QtWayland::Region::fromResource(region)->region() : QRegion(); +} + +void QWaylandSurfacePrivate::surface_set_input_region(Resource *, struct wl_resource *region) +{ + if (region) { + pending.inputRegion = QtWayland::Region::fromResource(region)->region(); + } else { + pending.inputRegion = infiniteRegion(); } - return 0; } -QLinkedList<QWaylandSurface *> QWaylandSurface::subSurfaces() const +void QWaylandSurfacePrivate::surface_commit(Resource *) { - Q_D(const QWaylandSurface); - if (d->subSurface()) { - return d->subSurface()->subSurfaces(); + Q_Q(QWaylandSurface); + + if (pending.buffer || pending.newlyAttached) { + setBackBuffer(pending.buffer, pending.damage); } - return QLinkedList<QWaylandSurface *>(); + + pending.buffer = 0; + pending.offset = QPoint(); + pending.newlyAttached = false; + pending.damage = QRegion(); + + setBufferScale(pending.bufferScale); + + if (buffer) + buffer->setCommitted(); + + frameCallbacks << pendingFrameCallbacks; + pendingFrameCallbacks.clear(); + + inputRegion = pending.inputRegion.intersected(QRect(QPoint(), size)); + + emit q->redraw(); } -void QWaylandSurface::addInterface(QWaylandSurfaceInterface *iface) +void QWaylandSurfacePrivate::surface_set_buffer_transform(Resource *resource, int32_t orientation) { - Q_D(QWaylandSurface); - d->interfaces.prepend(iface); + Q_UNUSED(resource); + Q_Q(QWaylandSurface); + QScreen *screen = QGuiApplication::primaryScreen(); + bool isPortrait = screen->primaryOrientation() == Qt::PortraitOrientation; + Qt::ScreenOrientation oldOrientation = contentOrientation; + switch (orientation) { + case WL_OUTPUT_TRANSFORM_90: + contentOrientation = isPortrait ? Qt::InvertedLandscapeOrientation : Qt::PortraitOrientation; + break; + case WL_OUTPUT_TRANSFORM_180: + contentOrientation = isPortrait ? Qt::InvertedPortraitOrientation : Qt::InvertedLandscapeOrientation; + break; + case WL_OUTPUT_TRANSFORM_270: + contentOrientation = isPortrait ? Qt::LandscapeOrientation : Qt::InvertedPortraitOrientation; + break; + default: + contentOrientation = Qt::PrimaryOrientation; + } + if (contentOrientation != oldOrientation) + emit q->contentOrientationChanged(); } -void QWaylandSurface::removeInterface(QWaylandSurfaceInterface *iface) +void QWaylandSurfacePrivate::surface_set_buffer_scale(QtWaylandServer::wl_surface::Resource *resource, int32_t scale) { - Q_D(QWaylandSurface); - d->interfaces.removeOne(iface); + Q_UNUSED(resource); + pending.bufferScale = scale; } -QWaylandSurface::Type QWaylandSurface::type() const +void QWaylandSurfacePrivate::setBackBuffer(QtWayland::SurfaceBuffer *b, const QRegion &d) { - Q_D(const QWaylandSurface); - return d->type(); + Q_Q(QWaylandSurface); + buffer = b; + + bufferRef = QWaylandBufferRef(buffer); + + setSize(bufferRef.size()); + damage = d.intersected(QRect(QPoint(), size)); + + for (int i = 0; i < views.size(); i++) { + views.at(i)->attach(bufferRef, damage); + } + + emit q->damaged(damage); + + bool oldMapped = mapped; + mapped = QtWayland::SurfaceBuffer::hasContent(buffer); + if (oldMapped != mapped) + emit q->mappedChanged(); + + if (!pending.offset.isNull()) + emit q->offsetForNextFrame(pending.offset); } -bool QWaylandSurface::isYInverted() const +QtWayland::SurfaceBuffer *QWaylandSurfacePrivate::createSurfaceBuffer(struct ::wl_resource *buffer) { - Q_D(const QWaylandSurface); - return d->isYInverted(); + Q_Q(QWaylandSurface); + QtWayland::SurfaceBuffer *newBuffer = 0; + for (int i = 0; i < bufferPool.size(); i++) { + if (!bufferPool[i]->isRegisteredWithBuffer()) { + newBuffer = bufferPool[i]; + newBuffer->initialize(buffer); + break; + } + } + + if (!newBuffer) { + newBuffer = new QtWayland::SurfaceBuffer(q); + newBuffer->initialize(buffer); + bufferPool.append(newBuffer); + if (bufferPool.size() > 3) + qWarning() << "Increased buffer pool size to" << bufferPool.size() << "for surface" << q; + } + + return newBuffer; } -bool QWaylandSurface::visible() const +/*! + * \qmltype WaylandSurface + * \inqmlmodule QtWayland.Compositor + * \preliminary + * \brief A rectangular area which is displayed on an output device. + * + * This type encapsulates a rectangular area of pixels that is displayed on an output device. It + * corresponds to the interface wl_surface in the Wayland protocol. + */ + +/*! + * \class QWaylandSurface + * \inmodule QtWaylandCompositor + * \preliminary + * \brief A rectangular area which is displayed on an output device. + * + * This class encapsulates a rectangular area of pixels that is displayed on an output device. It + * corresponds to the interface wl_surface in the Wayland protocol. + */ + +/*! + * Constructs a an uninitialized QWaylandSurface. + */ +QWaylandSurface::QWaylandSurface() + : QWaylandObject(*new QWaylandSurfacePrivate()) { - return isMapped(); } -bool QWaylandSurface::isMapped() const +/*! + * Constructs and initializes a QWaylandSurface for the given \a compositor and \a client, and with the given \a id + * and \a version. + */ +QWaylandSurface::QWaylandSurface(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version) + : QWaylandObject(*new QWaylandSurfacePrivate()) { - Q_D(const QWaylandSurface); - return d->mapped(); + initialize(compositor, client, id, version); } -QSize QWaylandSurface::size() const +/*! + * \internal + */ +QWaylandSurface::QWaylandSurface(QWaylandSurfacePrivate &dptr) + : QWaylandObject(dptr) { - Q_D(const QWaylandSurface); - return d->size(); } -void QWaylandSurface::requestSize(const QSize &size) +/*! + * Destroys the QWaylandSurface. + */ +QWaylandSurface::~QWaylandSurface() { Q_D(QWaylandSurface); - QWaylandSurfaceResizeOp op(size); - if (!sendInterfaceOp(op)) { - int id = wl_resource_get_id(d->resource()->handle); - qWarning("No surface interface forwarded the resize request for this surface (wl_surface@%d).", id); - } + QWaylandCompositorPrivate::get(d->compositor)->unregisterSurface(this); + d->notifyViewsAboutDestruction(); } -Qt::ScreenOrientations QWaylandSurface::orientationUpdateMask() const +/*! + * \qmlmethod void QtWaylandCompositor::WaylandSurface::initialize(object compositor, object client, int id, int version) + * + * Initializes the QWaylandSurface with the given \a compositor and \a client, and with the given \a id + * and \a version. + */ + +/*! + * Initializes the QWaylandSurface with the given \a compositor and \a client, and with the given \a id + * and \a version. + */ +void QWaylandSurface::initialize(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version) { - Q_D(const QWaylandSurface); - if (!d->extendedSurface()) - return Qt::PrimaryOrientation; - return d->extendedSurface()->contentOrientationMask(); + Q_D(QWaylandSurface); + d->compositor = compositor; + d->client = client; + d->init(client->client(), id, version); + d->isInitialized = true; + d->inputMethodControl = new QWaylandInputMethodControl(this); +#ifndef QT_NO_DEBUG + QWaylandSurfacePrivate::removeUninitializedSurface(d); +#endif } -Qt::ScreenOrientation QWaylandSurface::contentOrientation() const +/*! + * Returns true if the QWaylandSurface has been initialized. + */ +bool QWaylandSurface::isInitialized() const { Q_D(const QWaylandSurface); - return d->contentOrientation(); + return d->isInitialized; } -QWaylandSurface::WindowFlags QWaylandSurface::windowFlags() const +/*! + * \qmlproperty object QtWaylandCompositor::WaylandSurface::client + * + * This property holds the client using this QWaylandSurface. + */ + +/*! + * \property QWaylandSurface::client + * + * This property holds the client using this QWaylandSurface. + */ +QWaylandClient *QWaylandSurface::client() const { Q_D(const QWaylandSurface); - if (!d->extendedSurface()) - return QWaylandSurface::WindowFlags(0); - return d->extendedSurface()->windowFlags(); + if (isDestroyed() || !compositor() || !compositor()->clients().contains(d->client)) + return Q_NULLPTR; + + return d->client; } -QWaylandSurface::WindowType QWaylandSurface::windowType() const +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandSurface::isMapped + * + * This property holds whether the WaylandSurface has content. + */ + +/*! + * \property QWaylandSurface::isMapped + * + * This property holds whether the QWaylandSurface has content. + */ +bool QWaylandSurface::isMapped() const { Q_D(const QWaylandSurface); - return d->windowType; + return d->mapped; } -QWaylandSurface *QWaylandSurface::transientParent() const +/*! + * \qmlproperty size QtWaylandCompositor::WaylandSurface::size + * + * This property holds the WaylandSurface's size in pixels. + */ + +/*! + * \property QWaylandSurface::size + * + * This property holds the QWaylandSurface's size in pixels. + */ +QSize QWaylandSurface::size() const { Q_D(const QWaylandSurface); - return d->transientParent() ? d->transientParent()->waylandSurface() : 0; + return d->size; } -QPointF QWaylandSurface::transientOffset() const +/*! + * \qmlproperty size QtWaylandCompositor::WaylandSurface::bufferScale + * + * This property holds the WaylandSurface's buffer scale. The buffer scale lets + * a client supply higher resolution buffer data for use on high resolution + * outputs. + */ + +/*! + * \property QWaylandSurface::bufferScale + * + * This property holds the QWaylandSurface's buffer scale. The buffer scale + * lets a client supply higher resolution buffer data for use on high + * resolution outputs. + */ +int QWaylandSurface::bufferScale() const { Q_D(const QWaylandSurface); - return d->m_transientOffset; + return d->bufferScale; } -QtWayland::Surface * QWaylandSurface::handle() -{ - Q_D(QWaylandSurface); - return d; -} +/*! + * \qmlproperty enum QtWaylandCompositor::WaylandSurface::contentOrientation + * + * This property holds the orientation of the WaylandSurface's contents. + * + * \sa QWaylandOutput::transform + */ -QVariantMap QWaylandSurface::windowProperties() const +/*! + * \property QWaylandSurface::contentOrientation + * + * This property holds the orientation of the QWaylandSurface's contents. + * + * \sa QWaylandOutput::transform + */ +Qt::ScreenOrientation QWaylandSurface::contentOrientation() const { Q_D(const QWaylandSurface); - if (!d->extendedSurface()) - return QVariantMap(); - - return d->extendedSurface()->windowProperties(); + return d->contentOrientation; } -void QWaylandSurface::setWindowProperty(const QString &name, const QVariant &value) -{ - Q_D(QWaylandSurface); - if (!d->extendedSurface()) - return; +/*! + * \enum QWaylandSurface::Origin + * + * This enum type is used to specify the origin of a QWaylandSurface's buffer. + * + * \value OriginTopLeft The origin is the top left corner of the buffer. + * \value OriginBottomLeft The origin is the bottom left corner of the buffer. + */ - d->extendedSurface()->setWindowProperty(name, value); -} +/*! + * \qmlproperty enum QtWaylandCompositor::WaylandSurface::origin + * + * This property holds the origin of the WaylandSurface's buffer, or + * WaylandSurface.OriginTopLeft if the surface has no buffer. + * + * It can have the following values: + * \list + * \li WaylandSurface.OriginTopLeft The origin is the top left corner of the buffer. + * \li WaylandSurface.OriginBottomLeft The origin is the bottom left corner of the buffer. + * \endlist + */ -QWaylandCompositor *QWaylandSurface::compositor() const +/*! + * \property QWaylandSurface::origin + * + * This property holds the origin of the QWaylandSurface's buffer, or + * QWaylandSurface::OriginTopLeft if the surface has no buffer. + */ +QWaylandSurface::Origin QWaylandSurface::origin() const { Q_D(const QWaylandSurface); - return d->compositor()->waylandCompositor(); + return d->buffer ? d->buffer->origin() : QWaylandSurface::OriginTopLeft; } -QWaylandOutput *QWaylandSurface::mainOutput() const +/*! + * Returns the compositor for this QWaylandSurface. + */ +QWaylandCompositor *QWaylandSurface::compositor() const { Q_D(const QWaylandSurface); - - // Returns the output that contains the most if not all - // the surface (window managers will take care of setting - // this, defaults to the first output) - return d->mainOutput()->waylandOutput(); + return d->compositor; } -void QWaylandSurface::setMainOutput(QWaylandOutput *mainOutput) +/*! + * Prepares all frame callbacks for sending. + */ +void QWaylandSurface::frameStarted() { Q_D(QWaylandSurface); - - if (mainOutput) - d->setMainOutput(mainOutput->handle()); + foreach (QtWayland::FrameCallback *c, d->frameCallbacks) + c->canSend = true; } -QList<QWaylandOutput *> QWaylandSurface::outputs() const +/*! + * Sends pending frame callbacks. + */ +void QWaylandSurface::sendFrameCallbacks() { - Q_D(const QWaylandSurface); - - QList<QWaylandOutput *> list; - const QList<QtWayland::Output *> outputs = d->outputs(); - list.reserve(outputs.count()); - Q_FOREACH (QtWayland::Output *output, outputs) - list.append(output->waylandOutput()); - return list; + Q_D(QWaylandSurface); + uint time = d->compositor->currentTimeMsecs(); + int i = 0; + while (i < d->frameCallbacks.size()) { + if (d->frameCallbacks.at(i)->canSend) { + d->frameCallbacks.at(i)->surface = Q_NULLPTR; + d->frameCallbacks.at(i)->send(time); + d->frameCallbacks.removeAt(i); + } else { + i++; + } + } } -QWindow::Visibility QWaylandSurface::visibility() const +/*! + * Returns true if the QWaylandSurface's input region contains the point \a p. + * Otherwise returns false. + */ +bool QWaylandSurface::inputRegionContains(const QPoint &p) const { Q_D(const QWaylandSurface); - return d->m_visibility; + return d->inputRegion.contains(p); } -void QWaylandSurface::setVisibility(QWindow::Visibility v) +/*! + * \qmlmethod void QtWaylandCompositor::WaylandSurface::destroy() + * + * Destroys the QWaylandSurface. + */ + +/*! + * Destroys the QWaylandSurface. + */ +void QWaylandSurface::destroy() { Q_D(QWaylandSurface); - if (v == visibility()) - return; - - d->m_visibility = v; - QWaylandSurfaceSetVisibilityOp op(v); - sendInterfaceOp(op); - - emit visibilityChanged(); + d->deref(); } -bool QWaylandSurface::sendInterfaceOp(QWaylandSurfaceOp &op) +/*! + * \qmlmethod bool QtWaylandCompositor::WaylandSurface::isDestroyed() + * + * Returns true if the WaylandSurface has been destroyed. Otherwise returns false. + */ + +/*! + * Returns true if the QWaylandSurface has been destroyed. Otherwise returns false. + */ +bool QWaylandSurface::isDestroyed() const { - Q_D(QWaylandSurface); - foreach (QWaylandSurfaceInterface *iface, d->interfaces) { - if (iface->runOperation(&op)) - return true; - } - return false; + Q_D(const QWaylandSurface); + return d->destroyed; } -void QWaylandSurface::ping() +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandSurface::cursorSurface + * + * This property holds whether the WaylandSurface is a cursor surface. + */ + +/*! + * \property QWaylandSurface::cursorSurface + * + * This property holds whether the QWaylandSurface is a cursor surface. + */ +void QWaylandSurface::markAsCursorSurface(bool cursorSurface) { Q_D(QWaylandSurface); - - if (d->isDestroyed()) - return; - - uint32_t serial = wl_display_next_serial(compositor()->waylandDisplay()); - QWaylandSurfacePingOp op(serial); - if (!sendInterfaceOp(op)) { - int id = wl_resource_get_id(d->resource()->handle); - qWarning("No surface interface forwarded the ping for this surface (wl_surface@%d).", id); - } + d->isCursorSurface = cursorSurface; } -void QWaylandSurface::sendOnScreenVisibilityChange(bool visible) +bool QWaylandSurface::isCursorSurface() const { - setVisibility(visible ? QWindow::AutomaticVisibility : QWindow::Hidden); + Q_D(const QWaylandSurface); + return d->isCursorSurface; } -QString QWaylandSurface::className() const +QWaylandInputMethodControl *QWaylandSurface::inputMethodControl() const { Q_D(const QWaylandSurface); - return d->className(); + return d->inputMethodControl; } -QString QWaylandSurface::title() const +/*! + * Updates the surface with the compositor's retained clipboard selection. While this + * is done automatically when the surface receives keyboard focus, this function is + * useful for updating clients which do not have keyboard focus. + */ +void QWaylandSurface::updateSelection() { - Q_D(const QWaylandSurface); - return d->title(); + Q_D(QWaylandSurface); + QWaylandInputDevice *inputDevice = d->compositor->defaultInputDevice(); + if (inputDevice) { + const QtWayland::DataDevice *dataDevice = QWaylandInputDevicePrivate::get(inputDevice)->dataDevice(); + if (dataDevice) { + QWaylandCompositorPrivate::get(d->compositor)->dataDeviceManager()->offerRetainedSelection( + dataDevice->resourceMap().value(d->resource()->client())->handle); + } + } } -bool QWaylandSurface::hasInputPanelSurface() const +/*! + * Returns this QWaylandSurface's throttling view. + * + * \sa QWaylandView::advance() + */ +QWaylandView *QWaylandSurface::throttlingView() const { Q_D(const QWaylandSurface); - - return d->inputPanelSurface() != 0; + if (d->views.isEmpty()) + return Q_NULLPTR; + return d->views.first(); } /*! - * \return True if WL_SHELL_SURFACE_TRANSIENT_INACTIVE was set for this surface, meaning it should not receive keyboard focus. + * Sets this QWaylandSurface's throttling view to \a view, in case there are + * multiple views of this surface. The throttling view is the view that + * governs the client's refresh rate. It takes care of discarding buffer + * references when QWaylandView::advance() is called. See the documentation + * for QWaylandView::advance() for more details. + * + * \sa QWaylandView::advance() */ -bool QWaylandSurface::transientInactive() const +void QWaylandSurface::setThrottlingView(QWaylandView *view) { - Q_D(const QWaylandSurface); - return d->transientInactive(); + Q_D(QWaylandSurface); + + if (!view) + return; + + int index = d->views.indexOf(view); + + if (index < 0) { + view->setSurface(this); + index = d->views.indexOf(view); + } + + d->views.move(index, 0); } -bool QWaylandSurface::inputRegionContains(const QPoint &p) const +/*! + * Returns the views for this QWaylandSurface. + */ +QList<QWaylandView *> QWaylandSurface::views() const { Q_D(const QWaylandSurface); - return d->inputRegion().contains(p); + return d->views; } -void QWaylandSurface::destroy() +/*! + * Returns the QWaylandSurface corresponding to the Wayland resource \a res. + */ +QWaylandSurface *QWaylandSurface::fromResource(::wl_resource *res) { - Q_D(QWaylandSurface); - if (--d->refCount == 0) - compositor()->handle()->destroySurface(d); + return static_cast<QWaylandSurfacePrivate *>(QWaylandSurfacePrivate::Resource::fromResource(res)->surface_object)->q_func(); } -void QWaylandSurface::destroySurface() +/*! + * Returns the Wayland resource corresponding to this QWaylandSurface. + */ +struct wl_resource *QWaylandSurface::resource() const { - QWaylandSurfaceOp op(QWaylandSurfaceOp::Close); - if (!sendInterfaceOp(op)) - emit surfaceDestroyed(); + Q_D(const QWaylandSurface); + return d->resource()->handle; } /*! - Updates the surface with the compositor's retained clipboard selection. While this - is done automatically when the surface receives keyboard focus, this function is - useful for updating clients which do not have keyboard focus. -*/ -void QWaylandSurface::updateSelection() + * Sets a role on the surface. A role defines how a surface will be mapped on screen, without a role + * a surface is supposed to be hidden. Only one role at all times can be set on a surface. Attempting + * to change the role of a surface will trigger a protocol error to the client, while setting the same + * role many times is allowed. + * + * \param errorResource The resource the error will be sent to if the role is being changed. + * \param errorCode The error code that will be sent to the client. + */ +bool QWaylandSurface::setRole(QWaylandSurfaceRole *role, wl_resource *errorResource, uint32_t errorCode) { Q_D(QWaylandSurface); - const QtWayland::InputDevice *inputDevice = d->compositor()->defaultInputDevice(); - if (inputDevice) { - const QtWayland::DataDevice *dataDevice = inputDevice->dataDevice(); - if (dataDevice) { - d->compositor()->dataDeviceManager()->offerRetainedSelection( - dataDevice->resourceMap().value(d->resource()->client())->handle); - } + + if (d->role && d->role != role) { + wl_resource_post_error(errorResource, errorCode, + "Cannot assign role %s to wl_surface@%d, already has role %s\n", + role->name().constData(), wl_resource_get_id(resource()), + d->role->name().constData()); + return false; } -} -void QWaylandSurface::ref() -{ - Q_D(QWaylandSurface); - ++d->refCount; + d->role = role; + return true; } -void QWaylandSurface::setMapped(bool mapped) +QWaylandSurfaceRole *QWaylandSurface::role() const { - Q_D(QWaylandSurface); - d->setMapped(mapped); + Q_D(const QWaylandSurface); + return d->role; } -void QWaylandSurface::setBufferAttacher(QWaylandBufferAttacher *attacher) +QWaylandSurfacePrivate *QWaylandSurfacePrivate::get(QWaylandSurface *surface) { - Q_D(QWaylandSurface); - d->m_attacher = attacher; + return surface ? surface->d_func() : Q_NULLPTR; } -QWaylandBufferAttacher *QWaylandSurface::bufferAttacher() const +void QWaylandSurfacePrivate::ref() { - Q_D(const QWaylandSurface); - return d->m_attacher; + ++refCount; } -QList<QWaylandSurfaceView *> QWaylandSurface::views() const +void QWaylandSurfacePrivate::deref() { - Q_D(const QWaylandSurface); - return d->views; + if (--refCount == 0) + QWaylandCompositorPrivate::get(compositor)->destroySurface(q_func()); } -QList<QWaylandSurfaceInterface *> QWaylandSurface::interfaces() const +void QWaylandSurfacePrivate::refView(QWaylandView *view) { - Q_D(const QWaylandSurface); - return d->interfaces; -} + if (views.contains(view)) + return; -QWaylandSurface *QWaylandSurface::fromResource(::wl_resource *res) -{ - QtWayland::Surface *s = QtWayland::Surface::fromResource(res); - if (s) - return s->waylandSurface(); - return Q_NULLPTR; + views.append(view); + ref(); + QWaylandBufferRef ref(buffer); + view->attach(ref, QRect(QPoint(0,0), ref.size())); } -void QWaylandSurfacePrivate::setTitle(const QString &title) +void QWaylandSurfacePrivate::derefView(QWaylandView *view) { - Q_Q(QWaylandSurface); - if (m_title != title) { - m_title = title; - emit q->titleChanged(); + int nViews = views.removeAll(view); + + for (int i = 0; i < nViews && refCount > 0; i++) { + deref(); } } -void QWaylandSurfacePrivate::setClassName(const QString &className) +void QWaylandSurfacePrivate::initSubsurface(QWaylandSurface *parent, wl_client *client, int id, int version) { Q_Q(QWaylandSurface); - if (m_className != className) { - m_className = className; - emit q->classNameChanged(); - } + QWaylandSurface *oldParent = 0; // TODO: implement support for switching parents + + subsurface = new Subsurface(this); + subsurface->init(client, id, version); + subsurface->parentSurface = parent->d_func(); + emit q->parentChanged(parent, oldParent); + emit parent->childAdded(q); } -void QWaylandSurfacePrivate::setType(QWaylandSurface::WindowType type) +void QWaylandSurfacePrivate::Subsurface::subsurface_set_position(wl_subsurface::Resource *resource, int32_t x, int32_t y) { - Q_Q(QWaylandSurface); - if (windowType != type) { - windowType = type; - emit q->windowTypeChanged(type); - } + Q_UNUSED(resource); + position = QPoint(x,y); + emit surface->q_func()->subsurfacePositionChanged(position); + } -class QWaylandUnmapLockPrivate +void QWaylandSurfacePrivate::Subsurface::subsurface_place_above(wl_subsurface::Resource *resource, struct wl_resource *sibling) { -public: - QWaylandSurface *surface; -}; + Q_UNUSED(resource); + emit surface->q_func()->subsurfacePlaceAbove(QWaylandSurface::fromResource(sibling)); +} -/*! - Constructs a QWaylandUnmapLock object. +void QWaylandSurfacePrivate::Subsurface::subsurface_place_below(wl_subsurface::Resource *resource, struct wl_resource *sibling) +{ + Q_UNUSED(resource); + emit surface->q_func()->subsurfacePlaceBelow(QWaylandSurface::fromResource(sibling)); +} - The lock will act on the \a surface parameter, and will prevent the surface to - be unmapped, retaining the last valid buffer when the client attachs a NULL buffer. - The lock will be automatically released when deleted. -*/ -QWaylandUnmapLock::QWaylandUnmapLock(QWaylandSurface *surface) - : d(new QWaylandUnmapLockPrivate) +void QWaylandSurfacePrivate::Subsurface::subsurface_set_sync(wl_subsurface::Resource *resource) { - d->surface = surface; - surface->handle()->addUnmapLock(this); + Q_UNUSED(resource); + // TODO: sync/desync implementation + qDebug() << Q_FUNC_INFO; } -QWaylandUnmapLock::~QWaylandUnmapLock() +void QWaylandSurfacePrivate::Subsurface::subsurface_set_desync(wl_subsurface::Resource *resource) { - d->surface->handle()->removeUnmapLock(this); - delete d; + Q_UNUSED(resource); + // TODO: sync/desync implementation + qDebug() << Q_FUNC_INFO; } QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index db1e1fb44..816b5c987 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -4,36 +4,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -42,7 +38,9 @@ #ifndef QWAYLANDSURFACE_H #define QWAYLANDSURFACE_H -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandcompositorextension.h> +#include <QtWaylandCompositor/qwaylandclient.h> #include <QtCore/QScopedPointer> #include <QtGui/QImage> @@ -59,218 +57,108 @@ class QWaylandClient; class QWaylandSurfacePrivate; class QWaylandCompositor; class QWaylandBufferRef; -class QWaylandSurfaceView; -class QWaylandSurfaceInterface; +class QWaylandView; class QWaylandSurfaceOp; -class QWaylandOutput; - -namespace QtWayland { -class Surface; -class SurfacePrivate; -class ExtendedSurface; -} +class QWaylandInputMethodControl; -class Q_COMPOSITOR_EXPORT QWaylandBufferAttacher +class QWaylandSurfaceRole { public: - virtual ~QWaylandBufferAttacher() {} + QWaylandSurfaceRole(const QByteArray &n) : m_name(n) {} -protected: - virtual void attach(const QWaylandBufferRef &ref) = 0; - virtual void unmap() = 0; - - friend class QtWayland::Surface; -}; - -class QWaylandSurfaceEnterEventPrivate; - -class Q_COMPOSITOR_EXPORT QWaylandSurfaceEnterEvent : public QEvent -{ -public: - QWaylandSurfaceEnterEvent(QWaylandOutput *output); - ~QWaylandSurfaceEnterEvent(); - - QWaylandOutput *output() const; - - static const QEvent::Type WaylandSurfaceEnter; + const QByteArray name() { return m_name; } private: - QWaylandSurfaceEnterEventPrivate *d; + QByteArray m_name; }; -class QWaylandSurfaceLeaveEventPrivate; - -class Q_COMPOSITOR_EXPORT QWaylandSurfaceLeaveEvent : public QEvent -{ -public: - QWaylandSurfaceLeaveEvent(QWaylandOutput *output); - ~QWaylandSurfaceLeaveEvent(); - - QWaylandOutput *output() const; - - static const QEvent::Type WaylandSurfaceLeave; - -private: - QWaylandSurfaceLeaveEventPrivate *d; -}; - -class Q_COMPOSITOR_EXPORT QWaylandSurface : public QObject +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSurface : public QWaylandObject { Q_OBJECT Q_DECLARE_PRIVATE(QWaylandSurface) Q_PROPERTY(QWaylandClient *client READ client CONSTANT) Q_PROPERTY(QSize size READ size NOTIFY sizeChanged) - Q_PROPERTY(QWaylandSurface::WindowFlags windowFlags READ windowFlags NOTIFY windowFlagsChanged) - Q_PROPERTY(QWaylandSurface::WindowType windowType READ windowType NOTIFY windowTypeChanged) + Q_PROPERTY(int bufferScale READ bufferScale NOTIFY bufferScaleChanged) Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation NOTIFY contentOrientationChanged) - Q_PROPERTY(QString className READ className NOTIFY classNameChanged) - Q_PROPERTY(QString title READ title NOTIFY titleChanged) - Q_PROPERTY(Qt::ScreenOrientations orientationUpdateMask READ orientationUpdateMask NOTIFY orientationUpdateMaskChanged) - Q_PROPERTY(QWindow::Visibility visibility READ visibility WRITE setVisibility NOTIFY visibilityChanged) - Q_PROPERTY(QWaylandSurface *transientParent READ transientParent) - Q_PROPERTY(QPointF transientOffset READ transientOffset) - - Q_ENUMS(WindowFlag WindowType) - Q_FLAGS(WindowFlag WindowFlags) + Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged) + Q_PROPERTY(bool isMapped READ isMapped NOTIFY mappedChanged) + Q_PROPERTY(bool cursorSurface READ isCursorSurface WRITE markAsCursorSurface) public: - enum WindowFlag { - OverridesSystemGestures = 0x0001, - StaysOnTop = 0x0002, - BypassWindowManager = 0x0004 - }; - Q_DECLARE_FLAGS(WindowFlags, WindowFlag) - - enum WindowType { - None, - Toplevel, - Transient, - Popup - }; - - enum Type { - Invalid, - Shm, - Texture + enum Origin { + OriginTopLeft, + OriginBottomLeft }; + Q_ENUM(Origin) - QWaylandSurface(wl_client *client, quint32 id, int version, QWaylandCompositor *compositor); + QWaylandSurface(); + QWaylandSurface(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version); virtual ~QWaylandSurface(); - QWaylandClient *client() const; + Q_INVOKABLE void initialize(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version); + bool isInitialized() const; - QWaylandSurface *parentSurface() const; - QLinkedList<QWaylandSurface *> subSurfaces() const; - void addInterface(QWaylandSurfaceInterface *interface); - void removeInterface(QWaylandSurfaceInterface *interface); + QWaylandClient *client() const; + struct wl_client *waylandClient() const { return client()->client(); } - Type type() const; - bool isYInverted() const; + bool setRole(QWaylandSurfaceRole *role, wl_resource *errorResource, uint32_t errorCode); + QWaylandSurfaceRole *role() const; - bool visible() const; bool isMapped() const; QSize size() const; - Q_INVOKABLE void requestSize(const QSize &size); + int bufferScale() const; - Qt::ScreenOrientations orientationUpdateMask() const; Qt::ScreenOrientation contentOrientation() const; - WindowFlags windowFlags() const; - - WindowType windowType() const; - - QWindow::Visibility visibility() const; - void setVisibility(QWindow::Visibility visibility); - Q_INVOKABLE void sendOnScreenVisibilityChange(bool visible); // Compat - - QWaylandSurface *transientParent() const; - - QPointF transientOffset() const; - - QtWayland::Surface *handle(); - - QByteArray authenticationToken() const; - QVariantMap windowProperties() const; - void setWindowProperty(const QString &name, const QVariant &value); + Origin origin() const; QWaylandCompositor *compositor() const; - QWaylandOutput *mainOutput() const; - void setMainOutput(QWaylandOutput *mainOutput); - - QList<QWaylandOutput *> outputs() const; - - QString className() const; - - QString title() const; - - bool hasInputPanelSurface() const; - - bool transientInactive() const; - bool inputRegionContains(const QPoint &p) const; Q_INVOKABLE void destroy(); - Q_INVOKABLE void destroySurface(); - Q_INVOKABLE void ping(); - - void ref(); - void setMapped(bool mapped); + Q_INVOKABLE bool isDestroyed() const; - void setBufferAttacher(QWaylandBufferAttacher *attacher); - QWaylandBufferAttacher *bufferAttacher() const; + Q_INVOKABLE void frameStarted(); + Q_INVOKABLE void sendFrameCallbacks(); - QList<QWaylandSurfaceView *> views() const; - QList<QWaylandSurfaceInterface *> interfaces() const; + QWaylandView *throttlingView() const; + void setThrottlingView(QWaylandView *view); - bool sendInterfaceOp(QWaylandSurfaceOp &op); + QList<QWaylandView *> views() const; static QWaylandSurface *fromResource(::wl_resource *resource); + struct wl_resource *resource() const; + + void markAsCursorSurface(bool cursorSurface); + bool isCursorSurface() const; + + QWaylandInputMethodControl *inputMethodControl() const; public Q_SLOTS: void updateSelection(); protected: - QWaylandSurface(QWaylandSurfacePrivate *dptr); + QWaylandSurface(QWaylandSurfacePrivate &dptr); Q_SIGNALS: - void mapped(); - void unmapped(); + void mappedChanged(); void damaged(const QRegion &rect); void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); + void childAdded(QWaylandSurface *child); void sizeChanged(); - void windowPropertyChanged(const QString &name, const QVariant &value); - void windowFlagsChanged(WindowFlags flags); - void windowTypeChanged(WindowType type); + void bufferScaleChanged(); + void offsetForNextFrame(const QPoint &offset); void contentOrientationChanged(); - void orientationUpdateMaskChanged(); - void extendedSurfaceReady(); - void classNameChanged(); - void titleChanged(); - void raiseRequested(); - void lowerRequested(); - void visibilityChanged(); - void pong(); void surfaceDestroyed(); + void originChanged(); + void subsurfacePositionChanged(const QPoint &position); + void subsurfacePlaceAbove(QWaylandSurface *sibling); + void subsurfacePlaceBelow(QWaylandSurface *sibling); void configure(bool hasBuffer); void redraw(); - - friend class QWaylandSurfaceView; - friend class QWaylandSurfaceInterface; - friend class QtWayland::Surface; -}; - -class QWaylandUnmapLockPrivate; -class Q_COMPOSITOR_EXPORT QWaylandUnmapLock -{ -public: - QWaylandUnmapLock(QWaylandSurface *surface); - ~QWaylandUnmapLock(); - -private: - QWaylandUnmapLockPrivate *const d; }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h index 383a523b2..e37179cc6 100644 --- a/src/compositor/compositor_api/qwaylandsurface_p.h +++ b/src/compositor/compositor_api/qwaylandsurface_p.h @@ -4,9 +4,9 @@ ** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -17,16 +17,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -46,35 +49,161 @@ // We mean it. // -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> #include <private/qobject_p.h> -#include <QtCompositor/private/qwlsurface_p.h> +#include <private/qwlsurfacebuffer_p.h> +#include <QtWaylandCompositor/qwaylandsurface.h> +#include <QtWaylandCompositor/qwaylandbufferref.h> + +#include <QtWaylandCompositor/private/qwlregion_p.h> + +#include <QtCore/QVector> +#include <QtCore/QRect> +#include <QtGui/QRegion> +#include <QtGui/QImage> +#include <QtGui/QWindow> + +#include <QtCore/QTextStream> +#include <QtCore/QMetaType> + +#include <wayland-util.h> + +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE class QWaylandCompositor; class QWaylandSurface; -class QWaylandSurfaceView; +class QWaylandView; class QWaylandSurfaceInterface; +class QWaylandInputMethodControl; -class Q_COMPOSITOR_EXPORT QWaylandSurfacePrivate : public QObjectPrivate, public QtWayland::Surface +namespace QtWayland { +class FrameCallback; +} + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSurfacePrivate : public QObjectPrivate, public QtWaylandServer::wl_surface { - Q_DECLARE_PUBLIC(QWaylandSurface) public: - QWaylandSurfacePrivate(wl_client *wlClient, quint32 id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface); - void setType(QWaylandSurface::WindowType type); - void setTitle(const QString &title); - void setClassName(const QString &className); + static QWaylandSurfacePrivate *get(QWaylandSurface *surface); - bool closing; - int refCount; + QWaylandSurfacePrivate(); + ~QWaylandSurfacePrivate(); + + void ref(); + void deref(); + + void refView(QWaylandView *view); + void derefView(QWaylandView *view); + + using QtWaylandServer::wl_surface::resource; + + void setSize(const QSize &size); + void setBufferScale(int bufferScale); + + void removeFrameCallback(QtWayland::FrameCallback *callback); + + void notifyViewsAboutDestruction(); + +#ifndef QT_NO_DEBUG + static void addUninitializedSurface(QWaylandSurfacePrivate *surface); + static void removeUninitializedSurface(QWaylandSurfacePrivate *surface); + static bool hasUninitializedSurface(); +#endif + + void initSubsurface(QWaylandSurface *parent, struct ::wl_client *client, int id, int version); + bool isSubsurface() const { return subsurface; } + QWaylandSurfacePrivate *parentSurface() const { return subsurface ? subsurface->parentSurface : nullptr; } +protected: + void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void surface_destroy(Resource *resource) Q_DECL_OVERRIDE; + void surface_attach(Resource *resource, + struct wl_resource *buffer, int x, int y) Q_DECL_OVERRIDE; + void surface_damage(Resource *resource, + int32_t x, int32_t y, int32_t width, int32_t height) Q_DECL_OVERRIDE; + void surface_frame(Resource *resource, + uint32_t callback) Q_DECL_OVERRIDE; + void surface_set_opaque_region(Resource *resource, + struct wl_resource *region) Q_DECL_OVERRIDE; + void surface_set_input_region(Resource *resource, + struct wl_resource *region) Q_DECL_OVERRIDE; + void surface_commit(Resource *resource) Q_DECL_OVERRIDE; + void surface_set_buffer_transform(Resource *resource, int32_t transform) Q_DECL_OVERRIDE; + void surface_set_buffer_scale(Resource *resource, int32_t bufferScale) Q_DECL_OVERRIDE; + + void setBackBuffer(QtWayland::SurfaceBuffer *buffer, const QRegion &damage); + QtWayland::SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer); + +public: //member variables + QWaylandCompositor *compositor; + int refCount; QWaylandClient *client; + QList<QWaylandView *> views; + QRegion damage; + QtWayland::SurfaceBuffer *buffer; + QWaylandBufferRef bufferRef; + QWaylandSurfaceRole *role; + + struct { + QtWayland::SurfaceBuffer *buffer; + QRegion damage; + QPoint offset; + bool newlyAttached; + QRegion inputRegion; + int bufferScale; + } pending; + + QPoint lastLocalMousePos; + QPoint lastGlobalMousePos; + + QList<QtWayland::FrameCallback *> pendingFrameCallbacks; + QList<QtWayland::FrameCallback *> frameCallbacks; + + QRegion inputRegion; + QRegion opaqueRegion; - QWaylandSurface::WindowType windowType; - QList<QWaylandSurfaceView *> views; - QList<QWaylandSurfaceInterface *> interfaces; + QVector<QtWayland::SurfaceBuffer *> bufferPool; + + QSize size; + int bufferScale; + bool isCursorSurface; + bool destroyed; + bool mapped; + bool isInitialized; + Qt::ScreenOrientation contentOrientation; + QWindow::Visibility visibility; + QWaylandInputMethodControl *inputMethodControl; + + class Subsurface : public QtWaylandServer::wl_subsurface + { + public: + Subsurface(QWaylandSurfacePrivate *s) : surface(s) {} + QWaylandSurfacePrivate *surfaceFromResource(); + + protected: + void subsurface_set_position(wl_subsurface::Resource *resource, int32_t x, int32_t y); + void subsurface_place_above(wl_subsurface::Resource *resource, struct wl_resource *sibling); + void subsurface_place_below(wl_subsurface::Resource *resource, struct wl_resource *sibling); + void subsurface_set_sync(wl_subsurface::Resource *resource); + void subsurface_set_desync(wl_subsurface::Resource *resource); + + private: + friend class QWaylandSurfacePrivate; + QWaylandSurfacePrivate *surface; + QWaylandSurfacePrivate *parentSurface; + QPoint position; + }; + + Subsurface *subsurface; + +#ifndef QT_NO_DEBUG + static QList<QWaylandSurfacePrivate *> uninitializedSurfaces; +#endif + Q_DECLARE_PUBLIC(QWaylandSurface) + Q_DISABLE_COPY(QWaylandSurfacePrivate) }; QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp b/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp new file mode 100644 index 000000000..0eb85b0c6 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandsurfacegrabber.h" + +#include <QtCore/private/qobject_p.h> +#include <QtWaylandCompositor/qwaylandsurface.h> +#include <QtWaylandCompositor/qwaylandcompositor.h> +#include <QtWaylandCompositor/private/qwaylandsurface_p.h> + +QT_BEGIN_NAMESPACE + +/*! + \class QWaylandSurfaceGrabber + \inmodule QtWaylandCompositor + \preliminary + \brief The QWaylandSurfaceGrabber class allows to read the content of a QWaylandSurface + + Sometimes it is needed to get the contents of a surface, for example to provide a screenshot + to the user. The QWaylandSurfaceGrabber class provides a simple method to do so, without + having to care what type of buffer backs the surface, be it SHM, OpenGL or something else. +*/ + +/*! + \enum QWaylandSurfaceGrabber::Error + + The Error enum describes the reason for a grab failure. + + \value InvalidSurface The surface is null or otherwise not valid. + \value NoBufferAttached The client has not attached a buffer on the surface yet. + \value UnknownBufferType The buffer attached on the surface is of an unknown type. + \value RendererNotReady The compositor renderer is not ready to grab the surface content. + */ + +class QWaylandSurfaceGrabberPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QWaylandSurfaceGrabber) + + QWaylandSurface *surface; +}; + +/*! + * Create a QWaylandSurfaceGrabber object with the given \a surface and \a parent + */ +QWaylandSurfaceGrabber::QWaylandSurfaceGrabber(QWaylandSurface *surface, QObject *parent) + : QObject(*(new QWaylandSurfaceGrabberPrivate), parent) +{ + Q_D(QWaylandSurfaceGrabber); + d->surface = surface; +} + +/*! + * Returns the surface set on this object + */ +QWaylandSurface *QWaylandSurfaceGrabber::surface() const +{ + Q_D(const QWaylandSurfaceGrabber); + return d->surface; +} + +/*! + * Grab the content of the surface set on this object. + * It may not be possible to do that immediately so the \a success and \a failed signals + * should be used to be notified of when the grab is completed. + */ +void QWaylandSurfaceGrabber::grab() +{ + Q_D(QWaylandSurfaceGrabber); + if (!d->surface) { + emit failed(InvalidSurface); + return; + } + + QWaylandSurfacePrivate *surf = QWaylandSurfacePrivate::get(d->surface); + QWaylandBufferRef buf = surf->bufferRef; + if (!buf.hasBuffer()) { + emit failed(NoBufferAttached); + return; + } + + d->surface->compositor()->grabSurface(this, buf); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfacegrabber.h b/src/compositor/compositor_api/qwaylandsurfacegrabber.h new file mode 100644 index 000000000..28f984102 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandsurfacegrabber.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSURFACEGRABBER_H +#define QWAYLANDSURFACEGRABBER_H + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE + +class QWaylandSurface; +class QWaylandSurfaceGrabberPrivate; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSurfaceGrabber : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandSurfaceGrabber) +public: + enum Error { + InvalidSurface, + NoBufferAttached, + UnknownBufferType, + RendererNotReady, + }; + Q_ENUM(Error) + explicit QWaylandSurfaceGrabber(QWaylandSurface *surface, QObject *parent = Q_NULLPTR); + + QWaylandSurface *surface() const; + void grab(); + +Q_SIGNALS: + void success(const QImage &image); + void failed(Error error); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDSURFACEGRABBER_H diff --git a/src/compositor/compositor_api/qwaylandsurfaceinterface.cpp b/src/compositor/compositor_api/qwaylandsurfaceinterface.cpp deleted file mode 100644 index cddd231dd..000000000 --- a/src/compositor/compositor_api/qwaylandsurfaceinterface.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <wayland-server.h> - -#include "qwaylandsurfaceinterface.h" -#include "qwaylandsurface.h" -#include "qwaylandsurface_p.h" - -class QWaylandSurfaceInterface::Private -{ -public: - QWaylandSurface *surface; -}; - -QWaylandSurfaceInterface::QWaylandSurfaceInterface(QWaylandSurface *surface) - : d(new Private) -{ - d->surface = surface; - surface->addInterface(this); -} - -QWaylandSurfaceInterface::~QWaylandSurfaceInterface() -{ - d->surface->removeInterface(this); - delete d; -} - -QWaylandSurface *QWaylandSurfaceInterface::surface() const -{ - return d->surface; -} - -void QWaylandSurfaceInterface::setSurfaceType(QWaylandSurface::WindowType type) -{ - surface()->d_func()->setType(type); -} - -void QWaylandSurfaceInterface::setSurfaceClassName(const QString &name) -{ - surface()->d_func()->setClassName(name); -} - -void QWaylandSurfaceInterface::setSurfaceTitle(const QString &title) -{ - surface()->d_func()->setTitle(title); -} - - - -class QWaylandSurfaceOp::Private -{ -public: - int type; -}; - -QWaylandSurfaceOp::QWaylandSurfaceOp(int t) - : d(new Private) -{ - d->type = t; -} - -QWaylandSurfaceOp::~QWaylandSurfaceOp() -{ - delete d; -} - -int QWaylandSurfaceOp::type() const -{ - return d->type; -} - - - -QWaylandSurfaceSetVisibilityOp::QWaylandSurfaceSetVisibilityOp(QWindow::Visibility visibility) - : QWaylandSurfaceOp(QWaylandSurfaceOp::SetVisibility) - , m_visibility(visibility) -{ -} - -QWindow::Visibility QWaylandSurfaceSetVisibilityOp::visibility() const -{ - return m_visibility; -} - -QWaylandSurfaceResizeOp::QWaylandSurfaceResizeOp(const QSize &size) - : QWaylandSurfaceOp(QWaylandSurfaceOp::Resize) - , m_size(size) -{ -} - -QSize QWaylandSurfaceResizeOp::size() const -{ - return m_size; -} - -QWaylandSurfacePingOp::QWaylandSurfacePingOp(uint32_t serial) - : QWaylandSurfaceOp(QWaylandSurfaceOp::Ping) - , m_serial(serial) -{ -} - -uint32_t QWaylandSurfacePingOp::serial() const -{ - return m_serial; -} diff --git a/src/compositor/compositor_api/qwaylandsurfaceinterface.h b/src/compositor/compositor_api/qwaylandsurfaceinterface.h deleted file mode 100644 index 322037e6d..000000000 --- a/src/compositor/compositor_api/qwaylandsurfaceinterface.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDSURFACEINTERFACE_H -#define QWAYLANDSURFACEINTERFACE_H - -#include <QWindow> - -#include <QtCompositor/qwaylandsurface.h> -#include <QtCompositor/qwaylandexport.h> - -QT_BEGIN_NAMESPACE - -class QWaylandSurface; - -class Q_COMPOSITOR_EXPORT QWaylandSurfaceOp -{ -public: - enum Type { - Close, - SetVisibility, - Resize, - Ping, - UserType = 1000 - }; - - QWaylandSurfaceOp(int t); - virtual ~QWaylandSurfaceOp(); - - int type() const; - -private: - class Private; - Private *const d; -}; - -class Q_COMPOSITOR_EXPORT QWaylandSurfaceSetVisibilityOp : public QWaylandSurfaceOp -{ -public: - QWaylandSurfaceSetVisibilityOp(QWindow::Visibility visibility); - QWindow::Visibility visibility() const; - -private: - QWindow::Visibility m_visibility; -}; - -class Q_COMPOSITOR_EXPORT QWaylandSurfaceResizeOp : public QWaylandSurfaceOp -{ -public: - QWaylandSurfaceResizeOp(const QSize &size); - QSize size() const; - -private: - QSize m_size; -}; - -class Q_COMPOSITOR_EXPORT QWaylandSurfacePingOp : public QWaylandSurfaceOp -{ -public: - QWaylandSurfacePingOp(quint32 serial); - quint32 serial() const; - -private: - quint32 m_serial; -}; - -class Q_COMPOSITOR_EXPORT QWaylandSurfaceInterface -{ -public: - QWaylandSurfaceInterface(QWaylandSurface *surf); - virtual ~QWaylandSurfaceInterface(); - - QWaylandSurface *surface() const; - -protected: - virtual bool runOperation(QWaylandSurfaceOp *op) = 0; - - void setSurfaceType(QWaylandSurface::WindowType type); - void setSurfaceClassName(const QString &name); - void setSurfaceTitle(const QString &title); - -private: - class Private; - Private *const d; - friend class QWaylandSurface; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp b/src/compositor/compositor_api/qwaylandsurfaceitem.cpp deleted file mode 100644 index ca746ae41..000000000 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandsurfaceitem.h" -#include "qwaylandquicksurface.h" -#include <QtCompositor/qwaylandcompositor.h> -#include <QtCompositor/qwaylandinput.h> - -#include <QtGui/QKeyEvent> -#include <QtGui/QGuiApplication> -#include <QtGui/QScreen> - -#include <QtQuick/QSGSimpleTextureNode> -#include <QtQuick/QQuickWindow> - -#include <QtCore/QMutexLocker> -#include <QtCore/QMutex> - -QT_BEGIN_NAMESPACE - -QMutex *QWaylandSurfaceItem::mutex = 0; - -class QWaylandSurfaceTextureProvider : public QSGTextureProvider -{ -public: - QWaylandSurfaceTextureProvider() : t(0) { } - - QSGTexture *texture() const Q_DECL_OVERRIDE - { - if (t) - t->setFiltering(smooth ? QSGTexture::Linear : QSGTexture::Nearest); - return t; - } - - bool smooth; - QSGTexture *t; -}; - -QWaylandSurfaceItem::QWaylandSurfaceItem(QWaylandQuickSurface *surface, QQuickItem *parent) - : QQuickItem(parent) - , QWaylandSurfaceView(surface) - , m_provider(0) - , m_paintEnabled(true) - , m_touchEventsEnabled(false) - , m_resizeSurfaceToItem(false) - , m_newTexture(false) - -{ - if (!mutex) - mutex = new QMutex; - - setFlag(ItemHasContents); - - update(); - - if (surface) { - setWidth(surface->size().width()); - setHeight(surface->size().height()); - } - - setSmooth(true); - - setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton | - Qt::ExtraButton1 | Qt::ExtraButton2 | Qt::ExtraButton3 | Qt::ExtraButton4 | - Qt::ExtraButton5 | Qt::ExtraButton6 | Qt::ExtraButton7 | Qt::ExtraButton8 | - Qt::ExtraButton9 | Qt::ExtraButton10 | Qt::ExtraButton11 | - Qt::ExtraButton12 | Qt::ExtraButton13); - setAcceptHoverEvents(true); - if (surface) { - connect(surface, &QWaylandSurface::mapped, this, &QWaylandSurfaceItem::surfaceMapped); - connect(surface, &QWaylandSurface::unmapped, this, &QWaylandSurfaceItem::surfaceUnmapped); - connect(surface, &QWaylandSurface::surfaceDestroyed, this, &QWaylandSurfaceItem::surfaceDestroyed); - connect(surface, &QWaylandSurface::parentChanged, this, &QWaylandSurfaceItem::parentChanged); - connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandSurfaceItem::updateSize); - connect(surface, &QWaylandSurface::configure, this, &QWaylandSurfaceItem::updateBuffer); - connect(surface, &QWaylandSurface::redraw, this, &QQuickItem::update); - } - connect(this, &QWaylandSurfaceItem::widthChanged, this, &QWaylandSurfaceItem::updateSurfaceSize); - connect(this, &QWaylandSurfaceItem::heightChanged, this, &QWaylandSurfaceItem::updateSurfaceSize); - - - m_yInverted = surface ? surface->isYInverted() : true; - emit yInvertedChanged(); -} - -QWaylandSurfaceItem::~QWaylandSurfaceItem() -{ - QMutexLocker locker(mutex); - if (m_provider) - m_provider->deleteLater(); -} - -bool QWaylandSurfaceItem::isYInverted() const -{ - return m_yInverted; -} - -QSGTextureProvider *QWaylandSurfaceItem::textureProvider() const -{ - if (!m_provider) - m_provider = new QWaylandSurfaceTextureProvider(); - return m_provider; -} - -void QWaylandSurfaceItem::mousePressEvent(QMouseEvent *event) -{ - if (!surface()) - return; - - if (!surface()->inputRegionContains(event->pos())) { - event->ignore(); - return; - } - - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - if (inputDevice->mouseFocus() != this) - inputDevice->setMouseFocus(this, event->localPos(), event->windowPos()); - inputDevice->sendMousePressEvent(event->button(), event->localPos(), event->windowPos()); -} - -void QWaylandSurfaceItem::mouseMoveEvent(QMouseEvent *event) -{ - if (surface()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(this, event->localPos(), event->windowPos()); - } -} - -void QWaylandSurfaceItem::mouseReleaseEvent(QMouseEvent *event) -{ - if (surface()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseReleaseEvent(event->button(), event->localPos(), event->windowPos()); - } -} - -void QWaylandSurfaceItem::hoverEnterEvent(QHoverEvent *event) -{ - if (surface()) { - if (!surface()->inputRegionContains(event->pos())) { - event->ignore(); - return; - } - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(this, event->pos()); - } -} - -void QWaylandSurfaceItem::hoverMoveEvent(QHoverEvent *event) -{ - if (surface()) { - if (!surface()->inputRegionContains(event->pos())) { - event->ignore(); - return; - } - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseMoveEvent(this, event->pos()); - } -} - -void QWaylandSurfaceItem::wheelEvent(QWheelEvent *event) -{ - if (surface()) { - if (!surface()->inputRegionContains(event->pos())) { - event->ignore(); - return; - } - - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendMouseWheelEvent(event->orientation(), event->delta()); - } -} - -void QWaylandSurfaceItem::keyPressEvent(QKeyEvent *event) -{ - if (surface()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendFullKeyEvent(event); - } -} - -void QWaylandSurfaceItem::keyReleaseEvent(QKeyEvent *event) -{ - if (surface() && hasFocus()) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - inputDevice->sendFullKeyEvent(event); - } -} - -void QWaylandSurfaceItem::touchEvent(QTouchEvent *event) -{ - if (m_touchEventsEnabled) { - QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event); - - if (event->type() == QEvent::TouchBegin) { - QQuickItem *grabber = window()->mouseGrabberItem(); - if (grabber != this) - grabMouse(); - } - - QPoint pointPos; - const QList<QTouchEvent::TouchPoint> &points = event->touchPoints(); - if (!points.isEmpty()) - pointPos = points.at(0).pos().toPoint(); - - if (event->type() == QEvent::TouchBegin && !surface()->inputRegionContains(pointPos)) { - event->ignore(); - return; - } - - event->accept(); - if (inputDevice->mouseFocus() != this) { - inputDevice->setMouseFocus(this, pointPos, pointPos); - } - inputDevice->sendFullTouchEvent(event); - - const bool isEnd = event->type() == QEvent::TouchEnd || event->type() == QEvent::TouchCancel; - if (isEnd && window()->mouseGrabberItem() == this) - ungrabMouse(); - } else { - event->ignore(); - } -} - -void QWaylandSurfaceItem::mouseUngrabEvent() -{ - if (surface()) { - QTouchEvent e(QEvent::TouchCancel); - touchEvent(&e); - } -} - -void QWaylandSurfaceItem::takeFocus(QWaylandInputDevice *device) -{ - setFocus(true); - - if (!surface()) - return; - - QWaylandInputDevice *target = device; - if (!target) { - target = compositor()->defaultInputDevice(); - } - target->setKeyboardFocus(surface()); -} - -void QWaylandSurfaceItem::surfaceMapped() -{ - update(); -} - -void QWaylandSurfaceItem::surfaceUnmapped() -{ - update(); -} - -void QWaylandSurfaceItem::parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent) -{ - Q_UNUSED(oldParent); - - if (newParent) { - setPaintEnabled(true); - setVisible(true); - setOpacity(1); - setEnabled(true); - } -} - -void QWaylandSurfaceItem::updateSize() -{ - if (surface()) { - setSize(surface()->size()); - } -} - -void QWaylandSurfaceItem::updateSurfaceSize() -{ - if (surface() && m_resizeSurfaceToItem) { - surface()->requestSize(QSize(width(), height())); - } -} - -void QWaylandSurfaceItem::setPos(const QPointF &pos) -{ - setPosition(pos); -} - -QPointF QWaylandSurfaceItem::pos() const -{ - return position(); -} - -/*! - \qmlproperty bool QtWayland::QWaylandSurfaceItem::paintEnabled - - If this property is true, the \l item is hidden, though the texture - will still be updated. As opposed to hiding the \l item by - setting \l{Item::visible}{visible} to false, setting this property to true - will not prevent mouse or keyboard input from reaching \l item. -*/ -bool QWaylandSurfaceItem::paintEnabled() const -{ - return m_paintEnabled; -} - -void QWaylandSurfaceItem::setPaintEnabled(bool enabled) -{ - m_paintEnabled = enabled; - update(); -} - -void QWaylandSurfaceItem::updateBuffer(bool hasBuffer) -{ - Q_UNUSED(hasBuffer) - - bool inv = m_yInverted; - m_yInverted = surface()->isYInverted(); - if (inv != m_yInverted) - emit yInvertedChanged(); - - m_newTexture = true; -} - -void QWaylandSurfaceItem::updateTexture() -{ - updateTexture(false); -} - -void QWaylandSurfaceItem::updateTexture(bool changed) -{ - if (!m_provider) - m_provider = new QWaylandSurfaceTextureProvider(); - - m_provider->t = static_cast<QWaylandQuickSurface *>(surface())->texture(); - m_provider->smooth = smooth(); - if (m_newTexture || changed) - emit m_provider->textureChanged(); - m_newTexture = false; -} - -QSGNode *QWaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) -{ - bool mapped = surface() && surface()->isMapped(); - - if (!mapped || !m_provider || !m_provider->t || !m_paintEnabled) { - delete oldNode; - return 0; - } - - QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode); - - if (!node) - node = new QSGSimpleTextureNode(); - node->setTexture(m_provider->t); - // Surface textures come by default with the OpenGL coordinate system, which is inverted relative - // to the QtQuick one. So we're dealing with a double invertion here, and if isYInverted() returns - // true it means it is NOT inverted relative to QtQuick, while if it returns false it means it IS. - if (surface()->isYInverted()) { - node->setRect(0, 0, width(), height()); - } else { - node->setRect(0, height(), width(), -height()); - } - - return node; -} - -void QWaylandSurfaceItem::setTouchEventsEnabled(bool enabled) -{ - if (m_touchEventsEnabled != enabled) { - m_touchEventsEnabled = enabled; - emit touchEventsEnabledChanged(); - } -} - -void QWaylandSurfaceItem::setResizeSurfaceToItem(bool enabled) -{ - if (m_resizeSurfaceToItem != enabled) { - m_resizeSurfaceToItem = enabled; - emit resizeSurfaceToItemChanged(); - } -} - -QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfaceitem.h b/src/compositor/compositor_api/qwaylandsurfaceitem.h deleted file mode 100644 index cfbe410c1..000000000 --- a/src/compositor/compositor_api/qwaylandsurfaceitem.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDSURFACEITEM_H -#define QWAYLANDSURFACEITEM_H - -#include <QtCompositor/qwaylandexport.h> - -#include <QtQuick/QQuickItem> -#include <QtQuick/qsgtexture.h> - -#include <QtQuick/qsgtextureprovider.h> - -#include <QtCompositor/qwaylandsurfaceview.h> -#include <QtCompositor/qwaylandquicksurface.h> - -Q_DECLARE_METATYPE(QWaylandQuickSurface*) - -QT_BEGIN_NAMESPACE - -class QWaylandSurfaceTextureProvider; -class QMutex; -class QWaylandInputDevice; - -class Q_COMPOSITOR_EXPORT QWaylandSurfaceItem : public QQuickItem, public QWaylandSurfaceView -{ - Q_OBJECT - Q_PROPERTY(QWaylandSurface* surface READ surface CONSTANT) - Q_PROPERTY(bool paintEnabled READ paintEnabled WRITE setPaintEnabled) - Q_PROPERTY(bool touchEventsEnabled READ touchEventsEnabled WRITE setTouchEventsEnabled NOTIFY touchEventsEnabledChanged) - Q_PROPERTY(bool isYInverted READ isYInverted NOTIFY yInvertedChanged) - Q_PROPERTY(bool resizeSurfaceToItem READ resizeSurfaceToItem WRITE setResizeSurfaceToItem NOTIFY resizeSurfaceToItemChanged) - -public: - QWaylandSurfaceItem(QWaylandQuickSurface *surface, QQuickItem *parent = Q_NULLPTR); - ~QWaylandSurfaceItem(); - - Q_INVOKABLE bool isYInverted() const; - - bool isTextureProvider() const { return true; } - QSGTextureProvider *textureProvider() const; - - bool paintEnabled() const; - bool touchEventsEnabled() const { return m_touchEventsEnabled; } - bool resizeSurfaceToItem() const { return m_resizeSurfaceToItem; } - void updateTexture(); - - void setTouchEventsEnabled(bool enabled); - void setResizeSurfaceToItem(bool enabled); - - void setPos(const QPointF &pos) Q_DECL_OVERRIDE; - QPointF pos() const Q_DECL_OVERRIDE; - -protected: - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void hoverEnterEvent(QHoverEvent *event); - void hoverMoveEvent(QHoverEvent *event); - void wheelEvent(QWheelEvent *event); - - void keyPressEvent(QKeyEvent *event); - void keyReleaseEvent(QKeyEvent *event); - - void touchEvent(QTouchEvent *event); - void mouseUngrabEvent() Q_DECL_OVERRIDE; - -public Q_SLOTS: - virtual void takeFocus(QWaylandInputDevice *device = Q_NULLPTR); - void setPaintEnabled(bool paintEnabled); - -private Q_SLOTS: - void surfaceMapped(); - void surfaceUnmapped(); - void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); - void updateSize(); - void updateSurfaceSize(); - void updateBuffer(bool hasBuffer); - -Q_SIGNALS: - void touchEventsEnabledChanged(); - void yInvertedChanged(); - void resizeSurfaceToItemChanged(); - void surfaceDestroyed(); - -protected: - QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *); - -private: - friend class QWaylandSurfaceNode; - friend class QWaylandQuickSurface; - void init(QWaylandQuickSurface *); - void updateTexture(bool changed); - - static QMutex *mutex; - - mutable QWaylandSurfaceTextureProvider *m_provider; - bool m_paintEnabled; - bool m_touchEventsEnabled; - bool m_yInverted; - bool m_resizeSurfaceToItem; - bool m_newTexture; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.cpp b/src/compositor/compositor_api/qwaylandsurfaceview.cpp deleted file mode 100644 index 1d4ba304c..000000000 --- a/src/compositor/compositor_api/qwaylandsurfaceview.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandsurfaceview.h" -#include "qwaylandsurface.h" -#include "qwaylandsurface_p.h" -#include "qwaylandcompositor.h" -#include "qwaylandinput.h" - -QT_BEGIN_NAMESPACE - -class QWaylandSurfaceViewPrivate -{ -public: - QWaylandSurface *surface; - QPointF pos; -}; - -QWaylandSurfaceView::QWaylandSurfaceView(QWaylandSurface *surf) - : d(new QWaylandSurfaceViewPrivate) -{ - d->surface = surf; - if (surf) { - surf->d_func()->views << this; - surf->ref(); - } -} - -QWaylandSurfaceView::~QWaylandSurfaceView() -{ - if (d->surface) { - QWaylandInputDevice *i = d->surface->compositor()->defaultInputDevice(); - if (i->mouseFocus() == this) - i->setMouseFocus(Q_NULLPTR, QPointF()); - - d->surface->destroy(); - d->surface->d_func()->views.removeOne(this); - } - delete d; -} - -QWaylandSurface *QWaylandSurfaceView::surface() const -{ - return d->surface; -} - -QWaylandCompositor *QWaylandSurfaceView::compositor() const -{ - return d->surface ? d->surface->compositor() : 0; -} - -void QWaylandSurfaceView::setPos(const QPointF &pos) -{ - d->pos = pos; -} - -QPointF QWaylandSurfaceView::pos() const -{ - return d->pos; -} - -QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurfaceview.h b/src/compositor/compositor_api/qwaylandsurfaceview.h deleted file mode 100644 index 2da19c264..000000000 --- a/src/compositor/compositor_api/qwaylandsurfaceview.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDSURFACEVIEW_H -#define QWAYLANDSURFACEVIEW_H - -#include <QPointF> - -#include <QtCompositor/qwaylandexport.h> - -QT_BEGIN_NAMESPACE - -class QWaylandSurface; -class QWaylandCompositor; - -class Q_COMPOSITOR_EXPORT QWaylandSurfaceView -{ -public: - QWaylandSurfaceView(QWaylandSurface *surface); - virtual ~QWaylandSurfaceView(); - - QWaylandCompositor *compositor() const; - QWaylandSurface *surface() const; - - virtual void setPos(const QPointF &pos); - virtual QPointF pos() const; - -private: - class QWaylandSurfaceViewPrivate *const d; - friend class QWaylandSurfaceViewPrivate; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/compositor/compositor_api/qwaylandtouch.cpp b/src/compositor/compositor_api/qwaylandtouch.cpp new file mode 100644 index 000000000..a9b44527e --- /dev/null +++ b/src/compositor/compositor_api/qwaylandtouch.cpp @@ -0,0 +1,278 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandtouch.h" +#include "qwaylandtouch_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandView> +#include <QtWaylandCompositor/QWaylandClient> + +#include <QtWaylandCompositor/private/qwlqttouch_p.h> + +QT_BEGIN_NAMESPACE + +QWaylandTouchPrivate::QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandInputDevice *seat) + : wl_touch() + , seat(seat) + , focusResource() +{ + Q_UNUSED(touch); +} + +void QWaylandTouchPrivate::resetFocusState() +{ + focusDestroyListener.reset(); + focusResource = 0; +} + +void QWaylandTouchPrivate::touch_bind_resource(Resource *resource) +{ + focusResource = resource; +} + +void QWaylandTouchPrivate::touch_destroy_resource(Resource *resource) +{ + if (focusResource == resource) { + resetFocusState(); + } +} + +void QWaylandTouchPrivate::touch_release(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void QWaylandTouchPrivate::sendDown(uint32_t time, int touch_id, const QPointF &position) +{ + Q_Q(QWaylandTouch); + if (!focusResource || !q->mouseFocus()) + return; + + uint32_t serial = q->compositor()->nextSerial(); + + wl_touch_send_down(focusResource->handle, serial, time, q->mouseFocus()->surfaceResource(), touch_id, + wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); +} + +void QWaylandTouchPrivate::sendUp(uint32_t time, int touch_id) +{ + if (!focusResource) + return; + + uint32_t serial = compositor()->nextSerial(); + + wl_touch_send_up(focusResource->handle, serial, time, touch_id); +} +void QWaylandTouchPrivate::sendMotion(uint32_t time, int touch_id, const QPointF &position) +{ + if (!focusResource) + return; + + wl_touch_send_motion(focusResource->handle, time, touch_id, + wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); +} + +/*! + * \class QWaylandTouch + * \inmodule QtWaylandCompositor + * \preliminary + * \brief The QWaylandTouch class provides access to a touch device. + * + * This class provides access to the touch device in a QWaylandInputDevice. It corresponds to + * the Wayland interface wl_touch. + */ + +/*! + * Constructs a QWaylandTouch for the \a inputDevice and with the given \a parent. + */ +QWaylandTouch::QWaylandTouch(QWaylandInputDevice *inputDevice, QObject *parent) + : QWaylandObject(*new QWaylandTouchPrivate(this, inputDevice), parent) +{ + connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandTouch::focusDestroyed); +} + +/*! + * Returns the input device for this QWaylandTouch. + */ +QWaylandInputDevice *QWaylandTouch::inputDevice() const +{ + Q_D(const QWaylandTouch); + return d->seat; +} + +/*! + * Returns the compositor for this QWaylandTouch. + */ +QWaylandCompositor *QWaylandTouch::compositor() const +{ + Q_D(const QWaylandTouch); + return d->compositor(); +} + +/*! + * Sends a touch point event for the touch device with the given \a id, + * \a position, and \a state. + * + * + * \sa mouseFocus() + */ +void QWaylandTouch::sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state) +{ + Q_D(QWaylandTouch); + uint32_t time = compositor()->currentTimeMsecs(); + switch (state) { + case Qt::TouchPointPressed: + d->sendDown(time, id, position); + break; + case Qt::TouchPointMoved: + d->sendMotion(time, id, position); + break; + case Qt::TouchPointReleased: + d->sendUp(time, id); + break; + case Qt::TouchPointStationary: + // stationary points are not sent through wayland, the client must cache them + break; + default: + break; + } +} + +/*! + * Sends a touch frame event for the touch device. This indicates the end of a + * contact point list. + */ +void QWaylandTouch::sendFrameEvent() +{ + Q_D(QWaylandTouch); + if (d->focusResource) + d->send_frame(d->focusResource->handle); +} + +/*! + * Sends a touch cancel event for the touch device. + */ +void QWaylandTouch::sendCancelEvent() +{ + Q_D(QWaylandTouch); + if (d->focusResource) + d->send_cancel(d->focusResource->handle); +} + +/*! + * Sends all the touch points in \a event for this touch device, followed + * by a touch frame event. + * + * \sa sendTouchPointEvent(), sendFrameEvent() + */ +void QWaylandTouch::sendFullTouchEvent(QTouchEvent *event) +{ + Q_D(QWaylandTouch); + if (event->type() == QEvent::TouchCancel) { + sendCancelEvent(); + return; + } + + QtWayland::TouchExtensionGlobal *ext = QtWayland::TouchExtensionGlobal::findIn(d->compositor()); + if (ext && ext->postTouchEvent(event, d->seat->mouseFocus())) + return; + + const QList<QTouchEvent::TouchPoint> points = event->touchPoints(); + if (points.isEmpty()) + return; + + const int pointCount = points.count(); + for (int i = 0; i < pointCount; ++i) { + const QTouchEvent::TouchPoint &tp(points.at(i)); + // Convert the local pos in the compositor window to surface-relative. + sendTouchPointEvent(tp.id(), tp.pos(), tp.state()); + } + sendFrameEvent(); +} + +/*! + * \internal + */ +void QWaylandTouch::addClient(QWaylandClient *client, uint32_t id, uint32_t version) +{ + Q_D(QWaylandTouch); + d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_touch::interfaceVersion(), version)); +} + +/*! + * Returns the Wayland resource for this QWaylandTouch. + */ +struct wl_resource *QWaylandTouch::focusResource() const +{ + Q_D(const QWaylandTouch); + if (!d->focusResource) + return Q_NULLPTR; + return d->focusResource->handle; +} + +/*! + * Returns the view currently holding mouse focus in the input device. + */ +QWaylandView *QWaylandTouch::mouseFocus() const +{ + Q_D(const QWaylandTouch); + return d->seat->mouseFocus(); +} + +/*! + * \internal + */ +void QWaylandTouch::focusDestroyed(void *data) +{ + Q_UNUSED(data) + Q_D(QWaylandTouch); + d->resetFocusState(); +} + +/*! + * \internal + */ +void QWaylandTouch::mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus) +{ + Q_UNUSED(newFocus); + Q_UNUSED(oldFocus); + Q_D(QWaylandTouch); + d->resetFocusState(); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandtouch.h b/src/compositor/compositor_api/qwaylandtouch.h new file mode 100644 index 000000000..b6c40ea96 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandtouch.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDTOUCH_H +#define QWAYLANDTOUCH_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> + +#include <QtCore/QObject> +#include <QtGui/QTouchEvent> + +struct wl_resource; + +QT_BEGIN_NAMESPACE + +class QWaylandTouch; +class QWaylandTouchPrivate; +class QWaylandInputDevice; +class QWaylandView; +class QWaylandClient; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTouch : public QWaylandObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandTouch) +public: + QWaylandTouch(QWaylandInputDevice *inputDevice, QObject *parent = nullptr); + + QWaylandInputDevice *inputDevice() const; + QWaylandCompositor *compositor() const; + + virtual void sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state); + virtual void sendFrameEvent(); + virtual void sendCancelEvent(); + + virtual void sendFullTouchEvent(QTouchEvent *event); + + virtual void addClient(QWaylandClient *client, uint32_t id, uint32_t version); + + wl_resource *focusResource() const; + + QWaylandView *mouseFocus() const; +private: + void focusDestroyed(void *data); + void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus); +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDTOUCH_H*/ diff --git a/src/compositor/compositor_api/qwaylandtouch_p.h b/src/compositor/compositor_api/qwaylandtouch_p.h new file mode 100644 index 000000000..ea334eea1 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandtouch_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWAYLAND_QWLTOUCH_P_H +#define QTWAYLAND_QWLTOUCH_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/QWaylandDestroyListener> +#include <QtWaylandCompositor/QWaylandTouch> +#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandView> +#include <QtWaylandCompositor/QWaylandCompositor> + +#include <QtCore/QPoint> +#include <QtCore/private/qobject_p.h> + +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTouchPrivate : public QObjectPrivate, public QtWaylandServer::wl_touch +{ + Q_DECLARE_PUBLIC(QWaylandTouch) +public: + explicit QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandInputDevice *seat); + + QWaylandCompositor *compositor() const { return seat->compositor(); } + + void sendDown(uint32_t time, int touch_id, const QPointF &position); + void sendMotion(uint32_t time, int touch_id, const QPointF &position); + void sendUp(uint32_t time, int touch_id); + + void setFocusResource() + { + if (focusResource) + return; + + QWaylandView *mouseFocus = seat->mouseFocus(); + if (!mouseFocus || !mouseFocus->surface()) + return; + + focusResource = resourceMap().value(mouseFocus->surface()->waylandClient()); + } +private: + void resetFocusState(); + void touch_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void touch_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void touch_release(Resource *resource) Q_DECL_OVERRIDE; + + QWaylandInputDevice *seat; + + Resource *focusResource; + QWaylandDestroyListener focusDestroyListener; +}; + +QT_END_NAMESPACE + +#endif // QTWAYLAND_QWLTOUCH_P_H diff --git a/src/compositor/compositor_api/qwaylandview.cpp b/src/compositor/compositor_api/qwaylandview.cpp new file mode 100644 index 000000000..793dcf202 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandview.cpp @@ -0,0 +1,345 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandview.h" +#include "qwaylandview_p.h" +#include "qwaylandsurface.h" +#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QtWaylandCompositor/QWaylandCompositor> + +#include <QtWaylandCompositor/private/qwaylandsurface_p.h> +#include <QtWaylandCompositor/private/qwaylandoutput_p.h> + +#include <QtCore/QMutex> + +QT_BEGIN_NAMESPACE + +void QWaylandViewPrivate::markSurfaceAsDestroyed(QWaylandSurface *surface) +{ + Q_Q(QWaylandView); + Q_ASSERT(surface == this->surface); + + q->setSurface(Q_NULLPTR); + emit q->surfaceDestroyed(); +} + +/*! + * \qmltype WaylandView + * \inqmlmodule QtWayland.Compositor + * \preliminary + * \brief Represents a view of a surface on an output. + * + * The WaylandView corresponds to the presentation of a surface on a specific output, managing + * the buffers that contain the contents to be rendered. You can have several views into the same surface. + */ + +/*! + * \class QWaylandView + * \inmodule QtWaylandCompositor + * \preliminary + * \brief Represents a view of a surface on an output. + * + * The WaylandView corresponds to the presentation of a surface on a specific output, managing + * the buffers that contain the contents to be rendered. You can have several views into the same surface. + */ + +/*! + * Constructs a QWaylandView with the given \a renderObject and \a parent. + */ +QWaylandView::QWaylandView(QObject *renderObject, QObject *parent) + : QObject(*new QWaylandViewPrivate(),parent) +{ + d_func()->renderObject = renderObject; +} + +/*! + * Destroys the QWaylandView. + */ +QWaylandView::~QWaylandView() +{ + Q_D(QWaylandView); + if (d->surface) { + if (d->output) + QWaylandOutputPrivate::get(d->output)->removeView(this, d->surface); + QWaylandInputDevice *i = d->surface->compositor()->defaultInputDevice(); + if (i->mouseFocus() == this) + i->setMouseFocus(Q_NULLPTR); + + QWaylandSurfacePrivate::get(d->surface)->derefView(this); + } + +} + +/*! + \internal Didn't we decide to remove this property? +*/ +QObject *QWaylandView::renderObject() const +{ + Q_D(const QWaylandView); + return d->renderObject; +} + +/*! + * \qmlproperty object QtWaylandCompositor::WaylandView::surface + * + * This property holds the surface viewed by this WaylandView. + */ + +/*! + * \property QWaylandView::surface + * + * This property holds the surface viewed by this QWaylandView. + */ +QWaylandSurface *QWaylandView::surface() const +{ + Q_D(const QWaylandView); + return d->surface; +} + +void QWaylandView::setSurface(QWaylandSurface *newSurface) +{ + Q_D(QWaylandView); + if (d->surface == newSurface) + return; + + + if (d->surface) { + QWaylandSurfacePrivate::get(d->surface)->derefView(this); + if (d->output) + QWaylandOutputPrivate::get(d->output)->removeView(this, d->surface); + } + + d->surface = newSurface; + + if (!d->bufferLock) { + d->currentBuffer = QWaylandBufferRef(); + d->currentDamage = QRegion(); + } + + d->nextBuffer = QWaylandBufferRef(); + d->nextDamage = QRegion(); + + if (d->surface) { + QWaylandSurfacePrivate::get(d->surface)->refView(this); + if (d->output) + QWaylandOutputPrivate::get(d->output)->addView(this, d->surface); + } + + emit surfaceChanged(); + +} + +/*! + * \qmlproperty object QtWaylandCompositor::WaylandView::surface + * + * This property holds the output on which this view displays its surface. + */ + +/*! + * \property QWaylandView::output + * + * This property holds the output on which this view displays its surface. + */ +QWaylandOutput *QWaylandView::output() const +{ + Q_D(const QWaylandView); + return d->output; +} + +void QWaylandView::setOutput(QWaylandOutput *newOutput) +{ + Q_D(QWaylandView); + if (d->output == newOutput) + return; + + if (d->output && d->surface) + QWaylandOutputPrivate::get(d->output)->removeView(this, d->surface); + + d->output = newOutput; + + if (d->output && d->surface) + QWaylandOutputPrivate::get(d->output)->addView(this, d->surface); + + emit outputChanged(); +} + +/*! + * Attaches a new buffer \a ref and \a damage region to this QWaylandView. These + * will become current the next time advance() is called. + */ +void QWaylandView::attach(const QWaylandBufferRef &ref, const QRegion &damage) +{ + Q_D(QWaylandView); + QMutexLocker locker(&d->bufferMutex); + d->nextBuffer = ref; + d->nextDamage = damage; +} + +/*! + * Sets the next buffer and damage to current and returns true. If the buffer + * is locked or if no new buffer has been attached since the last call to + * advance(), the function returns false and does nothing. + * + * If this view is set as its surface's throttling view, discardCurrentBuffer() + * will be called on all views of the same surface for which the + * \l{QWaylandView::discardFrontBuffers}{discardFrontBuffers} + * property is set to true and the current buffer is the same as the + * throttling view's current buffer. + * + * This allows for a design where a primary + * view can make sure that views running on a lower frequency will release their + * front buffer references so that the buffer can be reused on the client side, + * avoiding the situation where the lower frequency views throttle the frame rate + * of the client application. + */ +bool QWaylandView::advance() +{ + Q_D(QWaylandView); + if (d->currentBuffer == d->nextBuffer && !d->forceAdvanceSucceed) + return false; + + if (d->bufferLock) + return false; + + if (d->surface && d->surface->throttlingView() == this) { + Q_FOREACH (QWaylandView *view, d->surface->views()) { + if (view != this && view->discardFrontBuffers() && view->d_func()->currentBuffer == d->currentBuffer) + view->discardCurrentBuffer(); + } + } + + QMutexLocker locker(&d->bufferMutex); + d->forceAdvanceSucceed = false; + d->currentBuffer = d->nextBuffer; + d->currentDamage = d->nextDamage; + return true; +} + +/*! + * Force the view to discard its current buffer, to allow it to be reused on the client side. + */ +void QWaylandView::discardCurrentBuffer() +{ + Q_D(QWaylandView); + QMutexLocker locker(&d->bufferMutex); + d->currentBuffer = QWaylandBufferRef(); + d->forceAdvanceSucceed = true; +} + +/*! + * Returns a reference to this view's current buffer. + */ +QWaylandBufferRef QWaylandView::currentBuffer() +{ + Q_D(QWaylandView); + QMutexLocker locker(&d->bufferMutex); + return d->currentBuffer; +} + +/*! + * Returns the current damage region of this view. + */ +QRegion QWaylandView::currentDamage() +{ + Q_D(QWaylandView); + QMutexLocker locker(&d->bufferMutex); + return d->currentDamage; +} + +/*! + * \qmlproperty bool QtWaylandCompositor::WaylandView::bufferLock + * + * This property holds whether the view's buffer is currently locked. When + * the buffer is locked, advance() will not advance to the next buffer, + * but will instead return false. + * + * The default is false. + */ + +/*! + * \property QWaylandView::bufferLock + * + * This property holds whether the view's buffer is currently locked. When + * the buffer is locked, advance() will not advance to the next buffer, + * but will instead return false. + * + * The default is false. + */ +bool QWaylandView::isBufferLocked() const +{ + Q_D(const QWaylandView); + return d->bufferLock; +} + +void QWaylandView::setBufferLock(bool locked) +{ + Q_D(QWaylandView); + d->bufferLock = locked; +} + +/*! + * \property bool QWaylandView::discardFrontBuffers + * + * By default, the view locks the current buffer until advance() is called. Set this property + * to true to allow Qt to release the buffer when the throttling view is no longer using it. + */ +bool QWaylandView::discardFrontBuffers() const +{ + Q_D(const QWaylandView); + return d->discardFrontBuffers; +} + +void QWaylandView::setDiscardFrontBuffers(bool discard) +{ + Q_D(QWaylandView); + if (d->discardFrontBuffers == discard) + return; + d->discardFrontBuffers = discard; + emit discardFrontBuffersChanged(); +} + +/*! + * Returns the Wayland surface resource for this QWaylandView. + */ +struct wl_resource *QWaylandView::surfaceResource() const +{ + Q_D(const QWaylandView); + if (!d->surface) + return Q_NULLPTR; + return d->surface->resource(); +} + +QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandview.h b/src/compositor/compositor_api/qwaylandview.h new file mode 100644 index 000000000..f89d8ca78 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandview.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSURFACEVIEW_H +#define QWAYLANDSURFACEVIEW_H + +#include <QtWaylandCompositor/QWaylandBufferRef> +#include <QtWaylandCompositor/qwaylandexport.h> + +#include <QtCore/QPointF> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE + +class QWaylandSurface; +class QWaylandViewPrivate; +class QWaylandOutput; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandView : public QObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandView) + Q_PROPERTY(QObject *renderObject READ renderObject CONSTANT) + Q_PROPERTY(QWaylandSurface *surface READ surface WRITE setSurface NOTIFY surfaceChanged) + Q_PROPERTY(QWaylandOutput *output READ output WRITE setOutput NOTIFY outputChanged) + Q_PROPERTY(bool bufferLock READ isBufferLocked WRITE setBufferLock NOTIFY bufferLockChanged) + Q_PROPERTY(bool discardFrontBuffers READ discardFrontBuffers WRITE setDiscardFrontBuffers NOTIFY discardFrontBuffersChanged) +public: + QWaylandView(QObject *renderObject = nullptr, QObject *parent = nullptr); + virtual ~QWaylandView(); + + QObject *renderObject() const; + + QWaylandSurface *surface() const; + void setSurface(QWaylandSurface *surface); + + QWaylandOutput *output() const; + void setOutput(QWaylandOutput *output); + + virtual void attach(const QWaylandBufferRef &ref, const QRegion &damage); + virtual bool advance(); + virtual void discardCurrentBuffer(); + virtual QWaylandBufferRef currentBuffer(); + virtual QRegion currentDamage(); + + bool isBufferLocked() const; + void setBufferLock(bool locked); + + bool discardFrontBuffers() const; + void setDiscardFrontBuffers(bool discard); + + struct wl_resource *surfaceResource() const; + +Q_SIGNALS: + void surfaceChanged(); + void surfaceDestroyed(); + void outputChanged(); + void bufferLockChanged(); + void discardFrontBuffersChanged(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/compositor/compositor_api/qwaylandview_p.h b/src/compositor/compositor_api/qwaylandview_p.h new file mode 100644 index 000000000..8c4cea085 --- /dev/null +++ b/src/compositor/compositor_api/qwaylandview_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSURFACEVIEW_P_H +#define QWAYLANDSURFACEVIEW_P_H + +#include <QtCore/QPoint> +#include <QtCore/QMutex> +#include <QtCore/private/qobject_p.h> + +#include <QtWaylandCompositor/QWaylandBufferRef> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QWaylandSurface; +class QWaylandOutput; + +class QWaylandViewPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QWaylandView) +public: + static QWaylandViewPrivate *get(QWaylandView *view) { return view->d_func(); } + + QWaylandViewPrivate() + : renderObject(Q_NULLPTR) + , surface(Q_NULLPTR) + , output(Q_NULLPTR) + , bufferLock(false) + , broadcastRequestedPositionChanged(false) + , forceAdvanceSucceed(false) + , discardFrontBuffers(false) + { } + + void markSurfaceAsDestroyed(QWaylandSurface *surface); + + QObject *renderObject; + QWaylandSurface *surface; + QWaylandOutput *output; + QPointF requestedPos; + QMutex bufferMutex; + QWaylandBufferRef currentBuffer; + QRegion currentDamage; + QWaylandBufferRef nextBuffer; + QRegion nextDamage; + bool bufferLock; + bool broadcastRequestedPositionChanged; + bool forceAdvanceSucceed; + bool discardFrontBuffers; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDSURFACEVIEW_P_H*/ diff --git a/src/compositor/doc/qtwaylandcompositor.qdocconf b/src/compositor/doc/qtwaylandcompositor.qdocconf new file mode 100644 index 000000000..3954cb22f --- /dev/null +++ b/src/compositor/doc/qtwaylandcompositor.qdocconf @@ -0,0 +1,47 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) + +project = QtWaylandCompositor +description = Qt Wayland Compositor Reference Documentation +version = $QT_VERSION + +qhp.projects = QtWaylandCompositor + +qhp.QtWaylandCompositor.file = qtwaylandcompositor.qhp +qhp.QtWaylandCompositor.namespace = org.qtproject.qtwaylandcompositor.$QT_VERSION_TAG +qhp.QtWaylandCompositor.virtualFolder = qtwaylandcompositor +qhp.QtWaylandCompositor.indexTitle = Qt Wayland Compositor +qhp.QtWaylandCompositor.indexRoot = +qhp.QtWaylandCompositor.filterAttributes = qtwaylandcompositor $QT_VERSION qtrefdoc +qhp.QtWaylandCompositor.customFilters.Qt.name = QtWaylandCompositor $QT_VERSION +qhp.QtWaylandCompositor.customFilters.Qt.filterAttributes = qtwaylandcompositor $QT_VERSION + +qhp.QtWaylandCompositor.subprojects = qmltypes classes examples +qhp.QtWaylandCompositor.subprojects.qmltypes.title = QML Types +qhp.QtWaylandCompositor.subprojects.qmltypes.indexTitle = Qt Wayland Compositor QML Types +qhp.QtWaylandCompositor.subprojects.qmltypes.selectors = qmlclass +qhp.QtWaylandCompositor.subprojects.qmltypes.sortPages = true +qhp.QtWaylandCompositor.subprojects.classes.title = C++ Classes +qhp.QtWaylandCompositor.subprojects.classes.indexTitle = Qt Wayland Compositor C++ Classes +qhp.QtWaylandCompositor.subprojects.classes.selectors = class fake:headerfile +qhp.QtWaylandCompositor.subprojects.classes.sortPages = true +qhp.QtWaylandCompositor.subprojects.examples.title = Examples +qhp.QtWaylandCompositor.subprojects.examples.indexTitle = Qt Wayland Compositor Examples +qhp.QtWaylandCompositor.subprojects.examples.selectors = fake:example +qhp.QtWaylandCompositor.subprojects.examples.sortPages = true + +depends += qtqml qtquick qtdoc qtquickcontrols qmake qtgui + +exampledirs += ../../../examples/wayland +headerdirs += .. +sourcedirs += .. +imagedirs += images + +examplesinstallpath = wayland + +Cpp.ignoretokens += Q_WAYLAND_COMPOSITOR_EXPORT +Cpp.ignoredirectives += Q_DECLARE_LOGGING_CATEGORY + +navigation.landingpage = "Qt Wayland Compositor" +navigation.qmltypespage = "Qt Wayland Compositor QML Types" +navigation.cppclassespage = "Qt Wayland Compositor C++ Classes" +navigation.homepage = "Qt Documentation (Technology Preview)" diff --git a/src/compositor/doc/src/qtwaylandcompositor-cpp.qdoc b/src/compositor/doc/src/qtwaylandcompositor-cpp.qdoc new file mode 100644 index 000000000..4b38c8613 --- /dev/null +++ b/src/compositor/doc/src/qtwaylandcompositor-cpp.qdoc @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtWaylandCompositor + \title Qt Wayland Compositor C++ Classes + \ingroup modules + \qtvariable waylandcompositor + + \brief Provides C++ classes for writing custom Wayland display servers. + + To include the definitions of the module's classes, use the following directive: + + \code + #include <QtWaylandCompositor> + \endcode + + To link against the module, add this line to your \l qmake \c .pro file: + + \code + QT += waylandcompositor + \endcode + + For more information about using these classes in your application, + see the \l{Qt Wayland Compositor} documentation. +*/ diff --git a/src/compositor/doc/src/qtwaylandcompositor-examples.qdoc b/src/compositor/doc/src/qtwaylandcompositor-examples.qdoc new file mode 100644 index 000000000..2b8511281 --- /dev/null +++ b/src/compositor/doc/src/qtwaylandcompositor-examples.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group qtwaylandcompositor-examples + \title Qt Wayland Compositor Examples + \brief Examples for the Qt Wayland Compositor module + + These are the Qt Wayland Compositor examples. + +*/ + diff --git a/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc b/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc new file mode 100644 index 000000000..9811d5205 --- /dev/null +++ b/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qtwaylandcompositor-index.html + \title Qt Wayland Compositor + \brief An API to develop display servers supporting the Wayland protocol + + Qt Wayland Compositor is a module consisting of QML and C++ APIs for developing + custom display servers based on the \l{http://wayland.freedesktop.org}{Wayland protocol}. + The server displays content from client applications that support the Wayland protocol. + + \section1 Environment Variables and Command-line Arguments + + The Qt Wayland Compositor API recognizes some environment variables and command-line arguments + that can be used to customize its behavior. + + The environment variables: + \list + \li QT_WAYLAND_HARDWARE_INTEGRATION Selects which hardware integration plugin to use. + \li QT_WAYLAND_CLIENT_BUFFER_INTEGRATION Selects which client buffer integration plugin to use. + \li QT_WAYLAND_SERVER_BUFFER_INTEGRATION Selects which server integration plugin to use. + \endlist + + The command-line arguments: + \list + \li --wayland-socket-name Overrides the default socket name used for communicating with clients. + \endlist + + \section1 Examples + + Take a look at the \l{Qt Wayland Compositor Examples} for a demonstration on + how the APIs can be used to write custom display servers. + + \section1 API Reference + + The Qt Wayland Compositor API can be used from C++ or QML. + + \list + \li \l{Qt Wayland Compositor QML Types} + \li \l{Qt Wayland Compositor C++ Classes} + \endlist + +*/ diff --git a/src/compositor/doc/src/qtwaylandcompositor-qmltypes.qdoc b/src/compositor/doc/src/qtwaylandcompositor-qmltypes.qdoc new file mode 100644 index 000000000..ae8398735 --- /dev/null +++ b/src/compositor/doc/src/qtwaylandcompositor-qmltypes.qdoc @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \qmlmodule QtWayland.Compositor 1.0 + \title Qt Wayland Compositor QML Types + \ingroup qmlmodules + \brief Provides QML types for writing custom Wayland display servers. + + The Qt Wayland module provides QML types that can be used to create custom + display servers supporting the Wayland protocol. + + The QML types can be imported into your application using the following + import statement: + + \code + import QtWayland.Compositor 1.0 + \endcode + + To link against the module, add this line to your \l qmake \c .pro file: + + \code + QT += waylandcompositor + \endcode + + For more information about using these types in your application, + see the \l{Qt Wayland Compositor} documentation. +*/ diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri new file mode 100644 index 000000000..4894eb3c4 --- /dev/null +++ b/src/compositor/extensions/extensions.pri @@ -0,0 +1,52 @@ +CONFIG += wayland-scanner +CONFIG += generated_privates + +WAYLANDSERVERSOURCES += \ + ../extensions/surface-extension.xml \ + ../extensions/touch-extension.xml \ + ../extensions/qtkey-extension.xml \ + ../extensions/windowmanager.xml \ + ../3rdparty/protocol/text-input-unstable-v2.xml \ + ../3rdparty/protocol/xdg-shell.xml \ + +HEADERS += \ + extensions/qwlextendedsurface_p.h \ + extensions/qwlqttouch_p.h \ + extensions/qwlqtkey_p.h \ + extensions/qwaylandwlshell.h \ + extensions/qwaylandwlshell_p.h \ + extensions/qwaylandtextinput.h \ + extensions/qwaylandtextinput_p.h \ + extensions/qwaylandtextinputmanager.h \ + extensions/qwaylandtextinputmanager_p.h \ + extensions/qwaylandwindowmanagerextension.h \ + extensions/qwaylandwindowmanagerextension_p.h \ + extensions/qwaylandxdgshell.h \ + extensions/qwaylandxdgshell_p.h \ + extensions/qwaylandshellsurface.h \ + +SOURCES += \ + extensions/qwlextendedsurface.cpp \ + extensions/qwlqttouch.cpp \ + extensions/qwlqtkey.cpp \ + extensions/qwaylandwlshell.cpp \ + extensions/qwaylandtextinput.cpp \ + extensions/qwaylandtextinputmanager.cpp \ + extensions/qwaylandwindowmanagerextension.cpp \ + extensions/qwaylandxdgshell.cpp \ + +qtHaveModule(quick) { + HEADERS += \ + extensions/qwaylandquickshellsurfaceitem.h \ + extensions/qwaylandquickshellsurfaceitem_p.h \ + extensions/qwaylandwlshellintegration_p.h \ + extensions/qwaylandxdgshellintegration_p.h \ + + SOURCES += \ + extensions/qwaylandquickshellsurfaceitem.cpp \ + extensions/qwaylandwlshellintegration.cpp \ + extensions/qwaylandxdgshellintegration.cpp \ + +} + +INCLUDEPATH += extensions diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp new file mode 100644 index 000000000..5fe43e547 --- /dev/null +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandquickshellsurfaceitem.h" +#include "qwaylandquickshellsurfaceitem_p.h" + +#include <QtWaylandCompositor/QWaylandShellSurface> +#include <QGuiApplication> + +QT_BEGIN_NAMESPACE + +/*! + * \qmltype ShellSurfaceItem + * \inqmlmodule QtWayland.Compositor + * \preliminary + * \brief An item representing a WlShellSurface. + * + * This type is used to render wl_shell or xdg_shell surfaces as part of a Qt Quick + * scene. It handles moving and resizing triggered by clicking on the window decorations. + */ + +/*! + * \class QWaylandQuickShellSurfaceItem + * \inmodule QtWaylandCompositor + * \preliminary + * \brief A Qt Quick item for QWaylandShellSurface. + * + * This class is used to render wl_shell or xdg_shell surfaces as part of a Qt Quick + * scene. It handles moving and resizing triggered by clicking on the window decorations. + * + * \sa QWaylandQuickItem + */ + +/*! + * Constructs a QWaylandQuickWlShellSurfaceItem with the given \a parent. + */ +QWaylandQuickShellSurfaceItem::QWaylandQuickShellSurfaceItem(QQuickItem *parent) + : QWaylandQuickItem(*new QWaylandQuickShellSurfaceItemPrivate(), parent) +{ +} + +/*! + * \internal + */ +QWaylandQuickShellSurfaceItem::QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent) + : QWaylandQuickItem(dd, parent) +{ +} + +/*! + * \qmlproperty object QtWaylandCompositor::ShellSurfaceItem::shellSurface + * + * This property holds the shell surface rendered by this ShellSurfaceItem. + * It may either be an XdgSurface or a WlShellSurface depending on which + * shell protocol is in use. + */ + +/*! + * \property QWaylandQuickShellSurfaceItem::shellSurface + * + * This property holds the shell surface rendered by this + * QWaylandQuickShellSurfaceItem. It may either be a QWaylandXdgSurface or a + * QWaylandWlShellSurface depending on which shell protocol is in use. + * + */ +QWaylandShellSurface *QWaylandQuickShellSurfaceItem::shellSurface() const +{ + Q_D(const QWaylandQuickShellSurfaceItem); + return d->m_shellSurface; +} + +void QWaylandQuickShellSurfaceItem::setShellSurface(QWaylandShellSurface *shellSurface) +{ + Q_D(QWaylandQuickShellSurfaceItem); + if (d->m_shellSurface == shellSurface) + return; + + d->m_shellSurface = shellSurface; + + d->m_shellIntegration = shellSurface->createIntegration(this); + emit shellSurfaceChanged(); +} + +/*! + * \property QWaylandQuickShellSurfaceItem::moveItem + * + * This property holds the move item for this QWaylandQuickShellSurfaceItem. + */ +QQuickItem *QWaylandQuickShellSurfaceItem::moveItem() const +{ + Q_D(const QWaylandQuickShellSurfaceItem); + return d->m_moveItem ? d->m_moveItem : const_cast<QWaylandQuickShellSurfaceItem *>(this); +} + +void QWaylandQuickShellSurfaceItem::setMoveItem(QQuickItem *moveItem) +{ + Q_D(QWaylandQuickShellSurfaceItem); + moveItem = moveItem ? moveItem : this; + if (this->moveItem() == moveItem) + return; + d->m_moveItem = moveItem; + moveItemChanged(); +} + +void QWaylandQuickShellSurfaceItem::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(QWaylandQuickShellSurfaceItem); + if (!d->m_shellIntegration->mouseMoveEvent(event)) + QWaylandQuickItem::mouseMoveEvent(event); +} + +void QWaylandQuickShellSurfaceItem::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(QWaylandQuickShellSurfaceItem); + if (!d->m_shellIntegration->mouseReleaseEvent(event)) + QWaylandQuickItem::mouseReleaseEvent(event); +} + +/*! +\class QWaylandQuickShellEventFilter +\brief QWaylandQuickShellEventFilter implements a Wayland popup grab +\internal +*/ + +void QWaylandQuickShellEventFilter::startFilter(QWaylandClient *client, CallbackFunction closePopups) +{ + if (!self) + self = new QWaylandQuickShellEventFilter(qGuiApp); + if (!self->eventFilterInstalled) { + qGuiApp->installEventFilter(self); + self->eventFilterInstalled = true; + self->client = client; + self->closePopups = closePopups; + } +} + +void QWaylandQuickShellEventFilter::cancelFilter() +{ + if (!self) + return; + if (self->eventFilterInstalled && !self->waitForRelease) + self->stopFilter(); +} + +void QWaylandQuickShellEventFilter::stopFilter() +{ + if (eventFilterInstalled) { + qGuiApp->removeEventFilter(this); + eventFilterInstalled = false; + } +} +QWaylandQuickShellEventFilter *QWaylandQuickShellEventFilter::self = nullptr; + +QWaylandQuickShellEventFilter::QWaylandQuickShellEventFilter(QObject *parent) + : QObject(parent), eventFilterInstalled(false), waitForRelease(false), closePopups(nullptr) +{ +} + +bool QWaylandQuickShellEventFilter::eventFilter(QObject *receiver, QEvent *e) +{ + if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) { + bool press = e->type() == QEvent::MouseButtonPress; + if (press && !waitForRelease) { + // The user clicked something: we need to close popups unless this press is caught later + if (!mousePressTimeout.isActive()) + mousePressTimeout.start(0, this); + } + + QQuickItem *item = qobject_cast<QQuickItem*>(receiver); + if (!item) + return false; + + QMouseEvent *event = static_cast<QMouseEvent*>(e); + QWaylandQuickShellSurfaceItem *shellSurfaceItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(item); + bool finalRelease = (event->type() == QEvent::MouseButtonRelease) && (event->buttons() == Qt::NoButton); + bool popupClient = shellSurfaceItem && shellSurfaceItem->surface()->client() == client; + + if (waitForRelease) { + // We are eating events until all mouse buttons are released + if (finalRelease) { + waitForRelease = false; + stopFilter(); + } + return true; + } + + if (finalRelease && mousePressTimeout.isActive()) { + // the user somehow managed to press and release the mouse button in 0 milliseconds + qWarning("Badly written autotest detected"); + mousePressTimeout.stop(); + stopFilter(); + } + + if (press && !shellSurfaceItem && !QQmlProperty(item, QStringLiteral("qtwayland_blocking_overlay")).isValid()) { + // the user clicked on something that's not blocking mouse events + e->ignore(); //propagate the event to items below + return true; // don't give the event to the item + } + + mousePressTimeout.stop(); // we've got this + + if (press && !popupClient) { + // The user clicked outside the active popup's client. The popups should + // be closed, but the event filter will stay to catch the release- + // event before removing itself. + waitForRelease = true; + closePopups(); + return true; + } + } + + return false; +} + +void QWaylandQuickShellEventFilter::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == mousePressTimeout.timerId()) { + mousePressTimeout.stop(); + closePopups(); + stopFilter(); + // Don't wait for release: Since the press wasn't accepted, + // the release won't be delivered. + } +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h new file mode 100644 index 000000000..e233c99e5 --- /dev/null +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDQUICKSHELLSURFACEITEM_H +#define QWAYLANDQUICKSHELLSURFACEITEM_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> +#include <QtWaylandCompositor/QWaylandQuickItem> + +QT_BEGIN_NAMESPACE + +class QWaylandQuickShellSurfaceItemPrivate; +class QWaylandShellSurface; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellSurfaceItem : public QWaylandQuickItem +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandQuickShellSurfaceItem) + Q_PROPERTY(QWaylandShellSurface *shellSurface READ shellSurface WRITE setShellSurface NOTIFY shellSurfaceChanged) + Q_PROPERTY(QQuickItem *moveItem READ moveItem WRITE setMoveItem NOTIFY moveItemChanged) + + QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent); +public: + QWaylandQuickShellSurfaceItem(QQuickItem *parent = nullptr); + + QWaylandShellSurface *shellSurface() const; + void setShellSurface(QWaylandShellSurface *shellSurface); + + QQuickItem *moveItem() const; + void setMoveItem(QQuickItem *moveItem); + +Q_SIGNALS: + void shellSurfaceChanged(); + void moveItemChanged(); + +protected: + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDQUICKSHELLSURFACEITEM_H diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h new file mode 100644 index 000000000..c39a1cd08 --- /dev/null +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDQUICKSHELLSURFACEITEM_P_H +#define QWAYLANDQUICKSHELLSURFACEITEM_P_H + +#include <QtWaylandCompositor/private/qwaylandquickitem_p.h> +#include <QtCore/QBasicTimer> + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +class QWaylandQuickShellIntegration; +class QWaylandShellSurface; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellSurfaceItemPrivate : public QWaylandQuickItemPrivate +{ +public: + QWaylandQuickShellSurfaceItemPrivate() + : QWaylandQuickItemPrivate() + , m_shellIntegration(nullptr) + , m_shellSurface(nullptr) + , m_moveItem(nullptr) + {} + QWaylandQuickShellIntegration *m_shellIntegration; + QWaylandShellSurface *m_shellSurface; + QQuickItem *m_moveItem; +}; + +class QWaylandQuickShellIntegration : public QObject +{ + Q_OBJECT +public: + QWaylandQuickShellIntegration(QObject *parent = nullptr) : QObject(parent) {} + virtual bool mouseMoveEvent(QMouseEvent *) { return false; } + virtual bool mouseReleaseEvent(QMouseEvent *) { return false; } +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellEventFilter : public QObject +{ + Q_OBJECT +public: + typedef void (*CallbackFunction)(void); + static void startFilter(QWaylandClient *client, CallbackFunction closePopupCallback); + static void cancelFilter(); + +protected: + void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + +private: + void stopFilter(); + + QWaylandQuickShellEventFilter(QObject *parent = nullptr); + bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE; + bool eventFilterInstalled; + bool waitForRelease; + QPointer<QWaylandClient> client; + CallbackFunction closePopups; + QBasicTimer mousePressTimeout; + static QWaylandQuickShellEventFilter *self; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDQUICKSHELLSURFACEITEM_P_H diff --git a/src/compositor/extensions/qwaylandshellsurface.h b/src/compositor/extensions/qwaylandshellsurface.h new file mode 100644 index 000000000..1e9fcb5ab --- /dev/null +++ b/src/compositor/extensions/qwaylandshellsurface.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSHELLSURFACE_H +#define QWAYLANDSHELLSURFACE_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> + +QT_BEGIN_NAMESPACE + +class QWaylandQuickShellIntegration; +class QWaylandQuickShellSurfaceItem; +class QWaylandShellSurfacePrivate; +class QWaylandShellSurfaceTemplatePrivate; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShellSurface : public QWaylandCompositorExtension +{ + Q_OBJECT +public: + virtual QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) = 0; + QWaylandShellSurface(QWaylandObject *waylandObject) : QWaylandCompositorExtension(waylandObject) {} + +protected: + QWaylandShellSurface(QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(dd){} + QWaylandShellSurface(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(container, dd) {} +}; + +template <typename T> +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShellSurfaceTemplate : public QWaylandShellSurface +{ +public: + QWaylandShellSurfaceTemplate(QWaylandObject *container) + : QWaylandShellSurface(container) + { } + + const struct wl_interface *extensionInterface() const Q_DECL_OVERRIDE + { + return T::interface(); + } + + static T *findIn(QWaylandObject *container) + { + if (!container) return nullptr; + return qobject_cast<T *>(container->extension(T::interfaceName())); + } + +protected: + QWaylandShellSurfaceTemplate(QWaylandCompositorExtensionPrivate &dd) + : QWaylandShellSurface(dd) + { } + + QWaylandShellSurfaceTemplate(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd) + : QWaylandShellSurface(container,dd) + { } +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDSHELLSURFACE_H diff --git a/src/compositor/extensions/qwaylandtextinput.cpp b/src/compositor/extensions/qwaylandtextinput.cpp new file mode 100644 index 000000000..973308f2f --- /dev/null +++ b/src/compositor/extensions/qwaylandtextinput.cpp @@ -0,0 +1,619 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandtextinput.h" +#include "qwaylandtextinput_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/private/qwaylandinput_p.h> + +#include "qwaylandsurface.h" +#include "qwaylandview.h" +#include "qwaylandxkb_p.h" +#include "qwaylandinputmethodeventbuilder_p.h" + +#include <QGuiApplication> +#include <QInputMethodEvent> + +QT_BEGIN_NAMESPACE + +QWaylandTextInputClientState::QWaylandTextInputClientState() + : hints(0) + , cursorRectangle() + , surroundingText() + , cursorPosition(0) + , anchorPosition(0) + , preferredLanguage() + , changedState() +{ +} + +Qt::InputMethodQueries QWaylandTextInputClientState::updatedQueries(const QWaylandTextInputClientState &other) const +{ + Qt::InputMethodQueries queries; + + if (hints != other.hints) + queries |= Qt::ImHints; + if (cursorRectangle != other.cursorRectangle) + queries |= Qt::ImCursorRectangle; + if (surroundingText != other.surroundingText) + queries |= Qt::ImSurroundingText | Qt::ImCurrentSelection; + if (cursorPosition != other.cursorPosition) + queries |= Qt::ImCursorPosition | Qt::ImCurrentSelection; + if (anchorPosition != other.anchorPosition) + queries |= Qt::ImAnchorPosition | Qt::ImCurrentSelection; + if (preferredLanguage != other.preferredLanguage) + queries |= Qt::ImPreferredLanguage; + + return queries; +} + +Qt::InputMethodQueries QWaylandTextInputClientState::mergeChanged(const QWaylandTextInputClientState &other) { + Qt::InputMethodQueries queries; + + if ((other.changedState & Qt::ImHints) && hints != other.hints) { + hints = other.hints; + queries |= Qt::ImHints; + } + + if ((other.changedState & Qt::ImCursorRectangle) && cursorRectangle != other.cursorRectangle) { + cursorRectangle = other.cursorRectangle; + queries |= Qt::ImCursorRectangle; + } + + if ((other.changedState & Qt::ImSurroundingText) && surroundingText != other.surroundingText) { + surroundingText = other.surroundingText; + queries |= Qt::ImSurroundingText | Qt::ImCurrentSelection; + } + + if ((other.changedState & Qt::ImCursorPosition) && cursorPosition != other.cursorPosition) { + cursorPosition = other.cursorPosition; + queries |= Qt::ImCursorPosition | Qt::ImCurrentSelection; + } + + if ((other.changedState & Qt::ImAnchorPosition) && anchorPosition != other.anchorPosition) { + anchorPosition = other.anchorPosition; + queries |= Qt::ImAnchorPosition | Qt::ImCurrentSelection; + } + + if ((other.changedState & Qt::ImPreferredLanguage) && preferredLanguage != other.preferredLanguage) { + preferredLanguage = other.preferredLanguage; + queries |= Qt::ImPreferredLanguage; + } + + return queries; +} + +QWaylandTextInputPrivate::QWaylandTextInputPrivate(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionPrivate() + , QtWaylandServer::zwp_text_input_v2() + , compositor(compositor) + , focus(nullptr) + , focusResource(nullptr) + , focusDestroyListener() + , inputPanelVisible(false) + , currentState(new QWaylandTextInputClientState) + , pendingState(new QWaylandTextInputClientState) + , serial(0) + , enabledSurfaces() +{ +} + +void QWaylandTextInputPrivate::sendInputMethodEvent(QInputMethodEvent *event) +{ + Q_Q(QWaylandTextInput); + + if (!focusResource || !focusResource->handle) + return; + + QWaylandTextInputClientState afterCommit; + + afterCommit.surroundingText = currentState->surroundingText; + afterCommit.cursorPosition = qMin(currentState->cursorPosition, currentState->anchorPosition); + + // Remove selection + afterCommit.surroundingText.remove(afterCommit.cursorPosition, qAbs(currentState->cursorPosition - currentState->anchorPosition)); + + if (event->replacementLength() > 0 || event->replacementStart() != 0) { + // Remove replacement + afterCommit.cursorPosition = qBound(0, afterCommit.cursorPosition + event->replacementStart(), afterCommit.surroundingText.length()); + afterCommit.surroundingText.remove(afterCommit.cursorPosition, + qMin(event->replacementLength(), + afterCommit.surroundingText.length() - afterCommit.cursorPosition)); + + if (event->replacementStart() <= 0 && (event->replacementLength() >= -event->replacementStart())) { + const int selectionStart = qMin(currentState->cursorPosition, currentState->anchorPosition); + const int selectionEnd = qMax(currentState->cursorPosition, currentState->anchorPosition); + const int before = QWaylandInputMethodEventBuilder::indexToWayland(currentState->surroundingText, -event->replacementStart(), selectionStart + event->replacementStart()); + const int after = QWaylandInputMethodEventBuilder::indexToWayland(currentState->surroundingText, event->replacementLength() + event->replacementStart(), selectionEnd); + send_delete_surrounding_text(focusResource->handle, before, after); + } else { + // TODO: Implement this case + qWarning() << "Not yet supported case of replacement. Start:" << event->replacementStart() << "length:" << event->replacementLength(); + } + } + + // Insert commit string + afterCommit.surroundingText.insert(afterCommit.cursorPosition, event->commitString()); + afterCommit.cursorPosition += event->commitString().length(); + afterCommit.anchorPosition = afterCommit.cursorPosition; + + foreach (const QInputMethodEvent::Attribute &attribute, event->attributes()) { + if (attribute.type == QInputMethodEvent::Selection) { + afterCommit.cursorPosition = attribute.start; + afterCommit.anchorPosition = attribute.length; + int cursor = QWaylandInputMethodEventBuilder::indexToWayland(afterCommit.surroundingText, qAbs(attribute.start - afterCommit.cursorPosition), qMin(attribute.start, afterCommit.cursorPosition)); + int anchor = QWaylandInputMethodEventBuilder::indexToWayland(afterCommit.surroundingText, qAbs(attribute.length - afterCommit.cursorPosition), qMin(attribute.length, afterCommit.cursorPosition)); + send_cursor_position(focusResource->handle, + attribute.start < afterCommit.cursorPosition ? -cursor : cursor, + attribute.length < afterCommit.cursorPosition ? -anchor : anchor); + } + } + send_commit_string(focusResource->handle, event->commitString()); + foreach (const QInputMethodEvent::Attribute &attribute, event->attributes()) { + if (attribute.type == QInputMethodEvent::Cursor) { + int index = QWaylandInputMethodEventBuilder::indexToWayland(event->preeditString(), attribute.start); + send_preedit_cursor(focusResource->handle, index); + } else if (attribute.type == QInputMethodEvent::TextFormat) { + int start = QWaylandInputMethodEventBuilder::indexToWayland(event->preeditString(), attribute.start); + int length = QWaylandInputMethodEventBuilder::indexToWayland(event->preeditString(), attribute.length, attribute.start); + // TODO add support for different stylesQWaylandTextInput + send_preedit_styling(focusResource->handle, start, length, preedit_style_default); + } + } + send_preedit_string(focusResource->handle, event->preeditString(), event->preeditString()); + + Qt::InputMethodQueries queries = currentState->updatedQueries(afterCommit); + currentState->surroundingText = afterCommit.surroundingText; + currentState->cursorPosition = afterCommit.cursorPosition; + currentState->anchorPosition = afterCommit.anchorPosition; + + if (queries) { + qCDebug(qLcCompositorInputMethods) << "QInputMethod::update() after QInputMethodEvent" << queries; + + emit q->updateInputMethod(queries); + } +} + +void QWaylandTextInputPrivate::sendKeyEvent(QKeyEvent *event) +{ + if (!focusResource || !focusResource->handle) + return; + + // TODO add support for modifiers + + foreach (xkb_keysym_t keysym, QWaylandXkb::toKeysym(event)) { + send_keysym(focusResource->handle, event->timestamp(), keysym, + event->type() == QEvent::KeyPress ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED, + 0); + } +} + +void QWaylandTextInputPrivate::sendInputPanelState() +{ + if (!focusResource || !focusResource->handle) + return; + + QInputMethod *inputMethod = qApp->inputMethod(); + const QRectF& keyboardRect = inputMethod->keyboardRectangle(); + const QRectF& sceneInputRect = inputMethod->inputItemTransform().mapRect(inputMethod->inputItemRectangle()); + const QRectF& localRect = sceneInputRect.intersected(keyboardRect).translated(-sceneInputRect.topLeft()); + + send_input_panel_state(focusResource->handle, + inputMethod->isVisible() ? input_panel_visibility_visible : input_panel_visibility_hidden, + localRect.x(), localRect.y(), localRect.width(), localRect.height()); +} + +void QWaylandTextInputPrivate::sendTextDirection() +{ + if (!focusResource || !focusResource->handle) + return; + + const Qt::LayoutDirection direction = qApp->inputMethod()->inputDirection(); + send_text_direction(focusResource->handle, + (direction == Qt::LeftToRight) ? text_direction_ltr : + (direction == Qt::RightToLeft) ? text_direction_rtl : text_direction_auto); +} + +void QWaylandTextInputPrivate::sendLocale() +{ + if (!focusResource || !focusResource->handle) + return; + + const QLocale locale = qApp->inputMethod()->locale(); + send_language(focusResource->handle, locale.bcp47Name()); +} + +QVariant QWaylandTextInputPrivate::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const +{ + switch (property) { + case Qt::ImHints: + return QVariant(static_cast<int>(currentState->hints)); + case Qt::ImCursorRectangle: + return currentState->cursorRectangle; + case Qt::ImFont: + // Not supported + return QVariant(); + case Qt::ImCursorPosition: + return currentState->cursorPosition; + case Qt::ImSurroundingText: + return currentState->surroundingText; + case Qt::ImCurrentSelection: + return currentState->surroundingText.mid(qMin(currentState->cursorPosition, currentState->anchorPosition), + qAbs(currentState->anchorPosition - currentState->cursorPosition)); + case Qt::ImMaximumTextLength: + // Not supported + return QVariant(); + case Qt::ImAnchorPosition: + return currentState->anchorPosition; + case Qt::ImAbsolutePosition: + // We assume the surrounding text is our whole document for now + return currentState->cursorPosition; + case Qt::ImTextAfterCursor: + if (argument.isValid()) + return currentState->surroundingText.mid(currentState->cursorPosition, argument.toInt()); + return currentState->surroundingText.mid(currentState->cursorPosition); + case Qt::ImTextBeforeCursor: + if (argument.isValid()) + return currentState->surroundingText.left(currentState->cursorPosition).right(argument.toInt()); + return currentState->surroundingText.left(currentState->cursorPosition); + case Qt::ImPreferredLanguage: + return currentState->preferredLanguage; + + default: + return QVariant(); + } +} + +void QWaylandTextInputPrivate::setFocus(QWaylandSurface *surface) +{ + Q_Q(QWaylandTextInput); + + if (focusResource && focus != surface) { + uint32_t serial = compositor->nextSerial(); + send_leave(focusResource->handle, serial, focus->resource()); + focusDestroyListener.reset(); + } + + Resource *resource = surface ? resourceMap().value(surface->waylandClient()) : 0; + + if (resource && (focus != surface || focusResource != resource)) { + uint32_t serial = compositor->nextSerial(); + currentState.reset(new QWaylandTextInputClientState); + pendingState.reset(new QWaylandTextInputClientState); + send_enter(resource->handle, serial, surface->resource()); + focusResource = resource; + sendInputPanelState(); + sendLocale(); + sendTextDirection(); + focusDestroyListener.listenForDestruction(surface->resource()); + if (inputPanelVisible && q->isSurfaceEnabled(surface)) + qApp->inputMethod()->show(); + } + + focusResource = resource; + focus = surface; +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_bind_resource(Resource *resource) +{ + send_modifiers_map(resource->handle, QByteArray("")); +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_destroy_resource(Resource *resource) +{ + if (focusResource == resource) + focusResource = 0; +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_enable(Resource *resource, wl_resource *surface) +{ + Q_Q(QWaylandTextInput); + + QWaylandSurface *s = QWaylandSurface::fromResource(surface); + enabledSurfaces.insert(resource, s); + emit q->surfaceEnabled(s); +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_disable(QtWaylandServer::zwp_text_input_v2::Resource *resource, wl_resource *) +{ + Q_Q(QWaylandTextInput); + + QWaylandSurface *s = enabledSurfaces.take(resource); + emit q->surfaceDisabled(s); +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_show_input_panel(Resource *) +{ + inputPanelVisible = true; + + qApp->inputMethod()->show(); +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_hide_input_panel(Resource *) +{ + inputPanelVisible = false; + + qApp->inputMethod()->hide(); +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_set_cursor_rectangle(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) +{ + if (resource != focusResource) + return; + + pendingState->cursorRectangle = QRect(x, y, width, height); + + pendingState->changedState |= Qt::ImCursorRectangle; +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_update_state(Resource *resource, uint32_t serial, uint32_t flags) +{ + Q_Q(QWaylandTextInput); + + qCDebug(qLcCompositorInputMethods) << "update_state" << serial << flags; + + if (resource != focusResource) + return; + + if (flags == update_state_reset || flags == update_state_enter) { + qCDebug(qLcCompositorInputMethods) << "QInputMethod::reset()"; + qApp->inputMethod()->reset(); + } + + this->serial = serial; + + Qt::InputMethodQueries queries; + if (flags == update_state_change) { + queries = currentState->mergeChanged(*pendingState.data()); + } else { + queries = pendingState->updatedQueries(*currentState.data()); + currentState.swap(pendingState); + } + + pendingState.reset(new QWaylandTextInputClientState); + + if (queries) { + qCDebug(qLcCompositorInputMethods) << "QInputMethod::update()" << queries; + + emit q->updateInputMethod(queries); + } +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_set_content_type(Resource *resource, uint32_t hint, uint32_t purpose) +{ + if (resource != focusResource) + return; + + pendingState->hints = 0; + + if ((hint & content_hint_auto_completion) == 0 + && (hint & content_hint_auto_correction) == 0) + pendingState->hints |= Qt::ImhNoPredictiveText; + if ((hint & content_hint_auto_capitalization) == 0) + pendingState->hints |= Qt::ImhNoAutoUppercase; + if ((hint & content_hint_lowercase) != 0) + pendingState->hints |= Qt::ImhPreferLowercase; + if ((hint & content_hint_uppercase) != 0) + pendingState->hints |= Qt::ImhPreferUppercase; + if ((hint & content_hint_hidden_text) != 0) + pendingState->hints |= Qt::ImhHiddenText; + if ((hint & content_hint_sensitive_data) != 0) + pendingState->hints |= Qt::ImhSensitiveData; + if ((hint & content_hint_latin) != 0) + pendingState->hints |= Qt::ImhLatinOnly; + if ((hint & content_hint_multiline) != 0) + pendingState->hints |= Qt::ImhMultiLine; + + switch (purpose) { + case content_purpose_normal: + break; + case content_purpose_alpha: + pendingState->hints |= Qt::ImhUppercaseOnly | Qt::ImhLowercaseOnly; + break; + case content_purpose_digits: + pendingState->hints |= Qt::ImhDigitsOnly; + break; + case content_purpose_number: + pendingState->hints |= Qt::ImhFormattedNumbersOnly; + break; + case content_purpose_phone: + pendingState->hints |= Qt::ImhDialableCharactersOnly; + break; + case content_purpose_url: + pendingState->hints |= Qt::ImhUrlCharactersOnly; + break; + case content_purpose_email: + pendingState->hints |= Qt::ImhEmailCharactersOnly; + break; + case content_purpose_name: + case content_purpose_password: + break; + case content_purpose_date: + pendingState->hints |= Qt::ImhDate; + break; + case content_purpose_time: + pendingState->hints |= Qt::ImhTime; + break; + case content_purpose_datetime: + pendingState->hints |= Qt::ImhDate | Qt::ImhTime; + break; + case content_purpose_terminal: + default: + break; + } + + pendingState->changedState |= Qt::ImHints; +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_set_preferred_language(Resource *resource, const QString &language) +{ + if (resource != focusResource) + return; + + pendingState->preferredLanguage = language; + + pendingState->changedState |= Qt::ImPreferredLanguage; +} + +void QWaylandTextInputPrivate::zwp_text_input_v2_set_surrounding_text(Resource *resource, const QString &text, int32_t cursor, int32_t anchor) +{ + if (resource != focusResource) + return; + + pendingState->surroundingText = text; + pendingState->cursorPosition = QWaylandInputMethodEventBuilder::indexFromWayland(text, cursor); + pendingState->anchorPosition = QWaylandInputMethodEventBuilder::indexFromWayland(text, anchor); + + pendingState->changedState |= Qt::ImSurroundingText | Qt::ImCursorPosition | Qt::ImAnchorPosition; +} + +QWaylandTextInput::QWaylandTextInput(QWaylandObject *container, QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate(container, *new QWaylandTextInputPrivate(compositor)) +{ + connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, + this, &QWaylandTextInput::focusSurfaceDestroyed); + + connect(qApp->inputMethod(), &QInputMethod::visibleChanged, + this, &QWaylandTextInput::sendInputPanelState); + connect(qApp->inputMethod(), &QInputMethod::keyboardRectangleChanged, + this, &QWaylandTextInput::sendInputPanelState); + connect(qApp->inputMethod(), &QInputMethod::inputDirectionChanged, + this, &QWaylandTextInput::sendTextDirection); + connect(qApp->inputMethod(), &QInputMethod::localeChanged, + this, &QWaylandTextInput::sendLocale); +} + +QWaylandTextInput::~QWaylandTextInput() +{ +} + +void QWaylandTextInput::sendInputMethodEvent(QInputMethodEvent *event) +{ + Q_D(QWaylandTextInput); + + d->sendInputMethodEvent(event); +} + +void QWaylandTextInput::sendKeyEvent(QKeyEvent *event) +{ + Q_D(QWaylandTextInput); + + d->sendKeyEvent(event); +} + +void QWaylandTextInput::sendInputPanelState() +{ + Q_D(QWaylandTextInput); + + d->sendInputPanelState(); +} + +void QWaylandTextInput::sendTextDirection() +{ + Q_D(QWaylandTextInput); + + d->sendTextDirection(); +} + +void QWaylandTextInput::sendLocale() +{ + Q_D(QWaylandTextInput); + + d->sendLocale(); +} + +QVariant QWaylandTextInput::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const +{ + const Q_D(QWaylandTextInput); + + return d->inputMethodQuery(property, argument); +} + +QWaylandSurface *QWaylandTextInput::focus() const +{ + const Q_D(QWaylandTextInput); + + return d->focus; +} + +void QWaylandTextInput::setFocus(QWaylandSurface *surface) +{ + Q_D(QWaylandTextInput); + + d->setFocus(surface); +} + +void QWaylandTextInput::focusSurfaceDestroyed(void *) +{ + Q_D(QWaylandTextInput); + + d->focusDestroyListener.reset(); + + d->focus = nullptr; + d->focusResource = nullptr; +} + +bool QWaylandTextInput::isSurfaceEnabled(QWaylandSurface *surface) const +{ + const Q_D(QWaylandTextInput); + + return d->enabledSurfaces.values().contains(surface); +} + +void QWaylandTextInput::add(::wl_client *client, uint32_t id, int version) +{ + Q_D(QWaylandTextInput); + + d->add(client, id, version); +} + +const wl_interface *QWaylandTextInput::interface() +{ + return QWaylandTextInputPrivate::interface(); +} + +QByteArray QWaylandTextInput::interfaceName() +{ + return QWaylandTextInputPrivate::interfaceName(); +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandtextinput.h b/src/compositor/extensions/qwaylandtextinput.h new file mode 100644 index 000000000..f050ab1c3 --- /dev/null +++ b/src/compositor/extensions/qwaylandtextinput.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDTEXTINPUT_H +#define QWAYLANDTEXTINPUT_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> + +struct wl_client; + +QT_BEGIN_NAMESPACE + +class QWaylandTextInputPrivate; + +class QInputMethodEvent; +class QKeyEvent; +class QWaylandSurface; + +class QWaylandTextInput : public QWaylandCompositorExtensionTemplate<QWaylandTextInput> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandTextInput) +public: + explicit QWaylandTextInput(QWaylandObject *container, QWaylandCompositor *compositor); + ~QWaylandTextInput(); + + void sendInputMethodEvent(QInputMethodEvent *event); + void sendKeyEvent(QKeyEvent *event); + + QVariant inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const; + + QWaylandSurface *focus() const; + void setFocus(QWaylandSurface *surface); + + bool isSurfaceEnabled(QWaylandSurface *surface) const; + + void add(::wl_client *client, uint32_t id, int version); + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + +Q_SIGNALS: + void updateInputMethod(Qt::InputMethodQueries queries); + void surfaceEnabled(QWaylandSurface *surface); + void surfaceDisabled(QWaylandSurface *surface); + +private: + void focusSurfaceDestroyed(void *); + void sendInputPanelState(); + void sendTextDirection(); + void sendLocale(); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDTEXTINPUT_H diff --git a/src/compositor/extensions/qwaylandtextinput_p.h b/src/compositor/extensions/qwaylandtextinput_p.h new file mode 100644 index 000000000..da90cc90b --- /dev/null +++ b/src/compositor/extensions/qwaylandtextinput_p.h @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDTEXTINPUT_P_H +#define QWAYLANDTEXTINPUT_P_H + +#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> +#include <QtWaylandCompositor/private/qwayland-server-text-input-unstable-v2.h> +#include <QtWaylandCompositor/QWaylandDestroyListener> + +#include <QtCore/QObject> +#include <QtCore/QMap> +#include <QtCore/QRect> +#include <QtCore/QVector> +#include <QtGui/QInputMethod> +#include <QtWaylandCompositor/QWaylandSurface> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QInputMethodEvent; +class QKeyEvent; +class QWaylandCompositor; +class QWaylandView; + +class QWaylandTextInputClientState { +public: + QWaylandTextInputClientState(); + + Qt::InputMethodQueries updatedQueries(const QWaylandTextInputClientState &other) const; + Qt::InputMethodQueries mergeChanged(const QWaylandTextInputClientState &other); + + Qt::InputMethodHints hints; + QRect cursorRectangle; + QString surroundingText; + int cursorPosition; + int anchorPosition; + QString preferredLanguage; + + Qt::InputMethodQueries changedState; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTextInputPrivate : public QWaylandCompositorExtensionPrivate, public QtWaylandServer::zwp_text_input_v2 +{ + Q_DECLARE_PUBLIC(QWaylandTextInput) +public: + explicit QWaylandTextInputPrivate(QWaylandCompositor *compositor); + + void sendInputMethodEvent(QInputMethodEvent *event); + void sendKeyEvent(QKeyEvent *event); + void sendInputPanelState(); + void sendTextDirection(); + void sendLocale(); + + QVariant inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const; + + void setFocus(QWaylandSurface *surface); + + QWaylandCompositor *compositor; + + QWaylandSurface *focus; + Resource *focusResource; + QWaylandDestroyListener focusDestroyListener; + + bool inputPanelVisible; + + QScopedPointer<QWaylandTextInputClientState> currentState; + QScopedPointer<QWaylandTextInputClientState> pendingState; + + uint32_t serial; + + QHash<Resource *, QWaylandSurface*> enabledSurfaces; + +protected: + void zwp_text_input_v2_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void zwp_text_input_v2_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void zwp_text_input_v2_destroy(Resource *resource) Q_DECL_OVERRIDE; + void zwp_text_input_v2_enable(Resource *resource, wl_resource *surface) Q_DECL_OVERRIDE; + void zwp_text_input_v2_disable(Resource *resource, wl_resource *surface) Q_DECL_OVERRIDE; + void zwp_text_input_v2_show_input_panel(Resource *resource) Q_DECL_OVERRIDE; + void zwp_text_input_v2_hide_input_panel(Resource *resource) Q_DECL_OVERRIDE; + void zwp_text_input_v2_set_surrounding_text(Resource *resource, const QString &text, int32_t cursor, int32_t anchor) Q_DECL_OVERRIDE; + void zwp_text_input_v2_set_content_type(Resource *resource, uint32_t hint, uint32_t purpose) Q_DECL_OVERRIDE; + void zwp_text_input_v2_set_cursor_rectangle(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) Q_DECL_OVERRIDE; + void zwp_text_input_v2_set_preferred_language(Resource *resource, const QString &language) Q_DECL_OVERRIDE; + void zwp_text_input_v2_update_state(Resource *resource, uint32_t serial, uint32_t flags) Q_DECL_OVERRIDE; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDTEXTINPUT_P_H diff --git a/src/compositor/extensions/qwaylandtextinputmanager.cpp b/src/compositor/extensions/qwaylandtextinputmanager.cpp new file mode 100644 index 000000000..9dd7ace8f --- /dev/null +++ b/src/compositor/extensions/qwaylandtextinputmanager.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandtextinputmanager.h" +#include "qwaylandtextinputmanager_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandInputDevice> + +#include "qwaylandtextinput.h" + +QT_BEGIN_NAMESPACE + +QWaylandTextInputManagerPrivate::QWaylandTextInputManagerPrivate() + : QWaylandCompositorExtensionPrivate() + , QtWaylandServer::zwp_text_input_manager_v2() +{ +} + +void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seat) +{ + Q_Q(QWaylandTextInputManager); + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); + QWaylandInputDevice *inputDevice = QWaylandInputDevice::fromSeatResource(seat); + QWaylandTextInput *textInput = QWaylandTextInput::findIn(inputDevice); + if (!textInput) { + textInput = new QWaylandTextInput(inputDevice, compositor); + } + textInput->add(resource->client(), id, wl_resource_get_version(resource->handle)); +} + +QWaylandTextInputManager::QWaylandTextInputManager() + : QWaylandCompositorExtensionTemplate<QWaylandTextInputManager>(*new QWaylandTextInputManagerPrivate) +{ +} + +QWaylandTextInputManager::QWaylandTextInputManager(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate<QWaylandTextInputManager>(compositor, *new QWaylandTextInputManagerPrivate) +{ +} + +void QWaylandTextInputManager::initialize() +{ + Q_D(QWaylandTextInputManager); + + QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandTextInputManager"; + return; + } + d->init(compositor->display(), 1); +} + +const wl_interface *QWaylandTextInputManager::interface() +{ + return QWaylandTextInputManagerPrivate::interface(); +} + +QByteArray QWaylandTextInputManager::interfaceName() +{ + return QWaylandTextInputManagerPrivate::interfaceName(); +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandtextinputmanager.h b/src/compositor/extensions/qwaylandtextinputmanager.h new file mode 100644 index 000000000..805c61af8 --- /dev/null +++ b/src/compositor/extensions/qwaylandtextinputmanager.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDTEXTINPUTMANAGER_H +#define QWAYLANDTEXTINPUTMANAGER_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> + +#include <QtCore/QSize> + +QT_BEGIN_NAMESPACE + +class QWaylandTextInputManagerPrivate; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTextInputManager : public QWaylandCompositorExtensionTemplate<QWaylandTextInputManager> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandTextInputManager) +public: + QWaylandTextInputManager(); + QWaylandTextInputManager(QWaylandCompositor *compositor); + + void initialize() Q_DECL_OVERRIDE; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDTEXTINPUTMANAGER_H diff --git a/src/compositor/extensions/qwaylandtextinputmanager_p.h b/src/compositor/extensions/qwaylandtextinputmanager_p.h new file mode 100644 index 000000000..4af717096 --- /dev/null +++ b/src/compositor/extensions/qwaylandtextinputmanager_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013-2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDTEXTINPUTMANAGER_P_H +#define QWAYLANDTEXTINPUTMANAGER_P_H + +#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> + +#include <QtWaylandCompositor/private/qwayland-server-text-input-unstable-v2.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTextInputManagerPrivate : public QWaylandCompositorExtensionPrivate, public QtWaylandServer::zwp_text_input_manager_v2 +{ + Q_DECLARE_PUBLIC(QWaylandTextInputManager) +public: + QWaylandTextInputManagerPrivate(); + +protected: + void zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDTEXTINPUTMANAGER_P_H diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.cpp b/src/compositor/extensions/qwaylandwindowmanagerextension.cpp new file mode 100644 index 000000000..1e7ed2892 --- /dev/null +++ b/src/compositor/extensions/qwaylandwindowmanagerextension.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandwindowmanagerextension.h" +#include "qwaylandwindowmanagerextension_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandClient> + +#include <QtCore/QUrl> + +QT_BEGIN_NAMESPACE + +QWaylandWindowManagerExtension::QWaylandWindowManagerExtension() + : QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>(*new QWaylandWindowManagerExtensionPrivate) +{ +} + +QWaylandWindowManagerExtension::QWaylandWindowManagerExtension(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>(compositor, *new QWaylandWindowManagerExtensionPrivate) +{ +} + +QWaylandWindowManagerExtensionPrivate::QWaylandWindowManagerExtensionPrivate() + : QWaylandCompositorExtensionPrivate() + , QtWaylandServer::qt_windowmanager() + , showIsFullScreen(false) +{ +} + +bool QWaylandWindowManagerExtension::showIsFullScreen() const +{ + Q_D(const QWaylandWindowManagerExtension); + return d->showIsFullScreen; +} + +void QWaylandWindowManagerExtension::setShowIsFullScreen(bool value) +{ + Q_D(QWaylandWindowManagerExtension); + + if (d->showIsFullScreen == value) + return; + + d->showIsFullScreen = value; + Q_FOREACH (QWaylandWindowManagerExtensionPrivate::Resource *resource, d->resourceMap().values()) { + d->send_hints(resource->handle, static_cast<int32_t>(d->showIsFullScreen)); + } + Q_EMIT showIsFullScreenChanged(); +} + +void QWaylandWindowManagerExtension::sendQuitMessage(wl_client *client) +{ + Q_D(QWaylandWindowManagerExtension); + QWaylandWindowManagerExtensionPrivate::Resource *resource = d->resourceMap().value(client); + + if (resource) + d->send_quit(resource->handle); +} + +void QWaylandWindowManagerExtension::initialize() +{ + Q_D(QWaylandWindowManagerExtension); + + QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandWindowManagerExtension"; + return; + } + d->init(compositor->display(), 1); +} + +void QWaylandWindowManagerExtensionPrivate::windowmanager_bind_resource(Resource *resource) +{ + send_hints(resource->handle, static_cast<int32_t>(showIsFullScreen)); +} + +void QWaylandWindowManagerExtensionPrivate::windowmanager_destroy_resource(Resource *resource) +{ + urls.remove(resource); +} + +void QWaylandWindowManagerExtensionPrivate::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl) +{ + Q_Q(QWaylandWindowManagerExtension); + + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor from QWaylandWindowManagerExtension::windowmanager_open_url()"; + return; + } + + QString url = urls.value(resource, QString()); + + url.append(newUrl); + + if (remaining) + urls.insert(resource, url); + else { + urls.remove(resource); + q->openUrl(QWaylandClient::fromWlClient(compositor, resource->client()), QUrl(url)); + } +} + +const struct wl_interface *QWaylandWindowManagerExtension::interface() +{ + return QWaylandWindowManagerExtensionPrivate::interface(); +} + +QByteArray QWaylandWindowManagerExtension::interfaceName() +{ + return QWaylandWindowManagerExtensionPrivate::interfaceName(); +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.h b/src/compositor/extensions/qwaylandwindowmanagerextension.h new file mode 100644 index 000000000..184bcc3c5 --- /dev/null +++ b/src/compositor/extensions/qwaylandwindowmanagerextension.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WAYLANDWINDOWMANAGERINTEGRATION_H +#define WAYLANDWINDOWMANAGERINTEGRATION_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> +#include <QtWaylandCompositor/QWaylandClient> + +#include <QtCore/QUrl> + +QT_BEGIN_NAMESPACE + +class QWaylandCompositor; + +class QWaylandWindowManagerExtensionPrivate; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWindowManagerExtension : public QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension> +{ + Q_OBJECT + Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen WRITE setShowIsFullScreen NOTIFY showIsFullScreenChanged) + Q_DECLARE_PRIVATE(QWaylandWindowManagerExtension) +public: + QWaylandWindowManagerExtension(); + explicit QWaylandWindowManagerExtension(QWaylandCompositor *compositor); + + bool showIsFullScreen() const; + void setShowIsFullScreen(bool value); + + void sendQuitMessage(wl_client *client); + + void initialize() Q_DECL_OVERRIDE; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + +Q_SIGNALS: + void showIsFullScreenChanged(); + void openUrl(QWaylandClient *client, const QUrl &url); +}; + +QT_END_NAMESPACE + +#endif // WAYLANDWINDOWMANAGERINTEGRATION_H diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension_p.h b/src/compositor/extensions/qwaylandwindowmanagerextension_p.h new file mode 100644 index 000000000..9573855d5 --- /dev/null +++ b/src/compositor/extensions/qwaylandwindowmanagerextension_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDWINDOWMANAGEREXTENSION_P_H +#define QWAYLANDWINDOWMANAGEREXTENSION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> + +#include <QtWaylandCompositor/private/qwayland-server-windowmanager.h> + +#include <QMap> + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWindowManagerExtensionPrivate + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::qt_windowmanager +{ + Q_DECLARE_PUBLIC(QWaylandWindowManagerExtension) +public: + QWaylandWindowManagerExtensionPrivate(); + +protected: + void windowmanager_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void windowmanager_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &url) Q_DECL_OVERRIDE; + +private: + bool showIsFullScreen; + QMap<Resource*, QString> urls; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDWINDOWMANAGEREXTENSION_P_H*/ diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp new file mode 100644 index 000000000..e3ab2eecb --- /dev/null +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -0,0 +1,615 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandwlshell.h" +#include "qwaylandwlshell_p.h" + +#include "qwaylandwlshellintegration_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandView> +#include <QtWaylandCompositor/QWaylandOutput> +#include <QtWaylandCompositor/QWaylandClient> + +#include <QtCore/QObject> +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +QWaylandSurfaceRole QWaylandWlShellSurfacePrivate::s_role("wl_shell_surface"); + +QWaylandWlShellPrivate::QWaylandWlShellPrivate() + : QWaylandCompositorExtensionPrivate() + , wl_shell() +{ +} + +void QWaylandWlShellPrivate::shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface_res) +{ + Q_Q(QWaylandWlShell); + QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res); + + QWaylandResource shellSurfaceResource(wl_resource_create(resource->client(), &wl_shell_surface_interface, + wl_resource_get_version(resource->handle), id)); + + // XXX FIXME + // The role concept was formalized in wayland 1.7, so that release adds one error + // code for each interface that implements a role, and we are supposed to pass here + // the newly constructed resource and the correct error code so that if setting the + // role fails, a proper error can be sent to the client. + // However we're still using wayland 1.4, which doesn't have interface specific role + // errors, so the best we can do is to use wl_display's object_id error. + wl_resource *displayRes = wl_client_get_object(resource->client(), 1); + if (!surface->setRole(QWaylandWlShellSurface::role(), displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT)) + return; + + emit q->createShellSurface(surface, shellSurfaceResource); + + QWaylandWlShellSurface *shellSurface = QWaylandWlShellSurface::fromResource(shellSurfaceResource.resource()); + if (!shellSurface) { + // A QWaylandShellSurface was not created in response to the createShellSurface signal + // we create one as fallback here instead. + shellSurface = new QWaylandWlShellSurface(q, surface, shellSurfaceResource); + } + + emit q->shellSurfaceCreated(shellSurface); +} + +QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate() + : QWaylandCompositorExtensionPrivate() + , wl_shell_surface() + , m_shell(Q_NULLPTR) + , m_surface(Q_NULLPTR) + , m_focusPolicy(QWaylandWlShellSurface::DefaultFocus) +{ +} + +QWaylandWlShellSurfacePrivate::~QWaylandWlShellSurfacePrivate() +{ +} + +void QWaylandWlShellSurfacePrivate::ping(uint32_t serial) +{ + m_pings.insert(serial); + send_ping(serial); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_destroy_resource(Resource *) +{ + Q_Q(QWaylandWlShellSurface); + + delete q; +} + +void QWaylandWlShellSurfacePrivate::shell_surface_move(Resource *resource, + struct wl_resource *input_device_super, + uint32_t serial) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + + Q_Q(QWaylandWlShellSurface); + QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super); + emit q->startMove(input_device); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_resize(Resource *resource, + struct wl_resource *input_device_super, + uint32_t serial, + uint32_t edges) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + Q_Q(QWaylandWlShellSurface); + + QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super); + emit q->startResize(input_device, QWaylandWlShellSurface::ResizeEdge(edges)); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_set_toplevel(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandWlShellSurface); + setFocusPolicy(QWaylandWlShellSurface::DefaultFocus); + emit q->setDefaultToplevel(); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_set_transient(Resource *resource, + struct wl_resource *parent_surface_resource, + int x, + int y, + uint32_t flags) +{ + + Q_UNUSED(resource); + Q_Q(QWaylandWlShellSurface); + QWaylandSurface *parent_surface = QWaylandSurface::fromResource(parent_surface_resource); + QWaylandWlShellSurface::FocusPolicy focusPolicy = + flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE ? QWaylandWlShellSurface::NoKeyboardFocus + : QWaylandWlShellSurface::DefaultFocus; + setFocusPolicy(focusPolicy); + emit q->setTransient(parent_surface, QPoint(x,y), focusPolicy); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_set_fullscreen(Resource *resource, + uint32_t method, + uint32_t framerate, + struct wl_resource *output_resource) +{ + Q_UNUSED(resource); + Q_UNUSED(method); + Q_UNUSED(framerate); + Q_Q(QWaylandWlShellSurface); + setFocusPolicy(QWaylandWlShellSurface::DefaultFocus); + QWaylandOutput *output = output_resource + ? QWaylandOutput::fromResource(output_resource) + : Q_NULLPTR; + emit q->setFullScreen(QWaylandWlShellSurface::FullScreenMethod(method), framerate, output); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_set_popup(Resource *resource, wl_resource *input_device, uint32_t serial, wl_resource *parent, int32_t x, int32_t y, uint32_t flags) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + Q_UNUSED(flags); + Q_Q(QWaylandWlShellSurface); + setFocusPolicy(QWaylandWlShellSurface::DefaultFocus); + QWaylandInputDevice *input = QWaylandInputDevice::fromSeatResource(input_device); + QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent); + emit q->setPopup(input, parentSurface, QPoint(x,y)); + +} + +void QWaylandWlShellSurfacePrivate::shell_surface_set_maximized(Resource *resource, + struct wl_resource *output_resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandWlShellSurface); + setFocusPolicy(QWaylandWlShellSurface::DefaultFocus); + QWaylandOutput *output = output_resource + ? QWaylandOutput::fromResource(output_resource) + : Q_NULLPTR; + emit q->setMaximized(output); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_pong(Resource *resource, + uint32_t serial) +{ + Q_UNUSED(resource); + Q_Q(QWaylandWlShellSurface); + if (m_pings.remove(serial)) + emit q->pong(); + else + qWarning("Received an unexpected pong!"); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_set_title(Resource *resource, + const QString &title) +{ + Q_UNUSED(resource); + if (title == m_title) + return; + Q_Q(QWaylandWlShellSurface); + m_title = title; + emit q->titleChanged(); +} + +void QWaylandWlShellSurfacePrivate::shell_surface_set_class(Resource *resource, + const QString &className) +{ + Q_UNUSED(resource); + if (className == m_className) + return; + Q_Q(QWaylandWlShellSurface); + m_className = className; + emit q->classNameChanged(); +} + +/*! + * \qmltype WlShell + * \inqmlmodule QtWayland.Compositor + * \preliminary + * \brief Extension for desktop-style user interfaces. + * + * The WlShell extension provides a way to assiociate a ShellSurface + * with a regular Wayland surface. Using the shell surface interface, the client + * can request that the surface is resized, moved, and so on. + * + * WlShell corresponds to the Wayland interface wl_shell. + * + * To provide the functionality of the shell extension in a compositor, create + * an instance of the WlShell component and add it to the list of extensions + * supported by the compositor: + * \code + * import QtWayland.Compositor 1.0 + * + * WaylandCompositor { + * extensions: WlShell { + * // ... + * } + * } + * \endcode + */ + +/*! + * \class QWaylandWlShell + * \inmodule QtWaylandCompositor + * \preliminary + * \brief Extension for desktop-style user interfaces. + * + * The QWaylandWlShell extension provides a way to assiociate a QWaylandWlShellSurface with + * a regular Wayland surface. Using the shell surface interface, the client + * can request that the surface is resized, moved, and so on. + * + * WlShell corresponds to the Wayland interface wl_shell. + */ + +/*! + * Constructs a QWaylandWlShell object. + */ +QWaylandWlShell::QWaylandWlShell() + : QWaylandCompositorExtensionTemplate<QWaylandWlShell>(*new QWaylandWlShellPrivate()) +{ } + +/*! + * Constructs a QWaylandWlShell object for the provided \a compositor. + */ +QWaylandWlShell::QWaylandWlShell(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate<QWaylandWlShell>(compositor, *new QWaylandWlShellPrivate()) +{ } + + +/*! + * Initializes the WlShell extension. + */ +void QWaylandWlShell::initialize() +{ + Q_D(QWaylandWlShell); + QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandWlShell"; + return; + } + d->init(compositor->display(), 1); +} + +/*! + * Returns the Wayland interface for the QWaylandWlShell. + */ +const struct wl_interface *QWaylandWlShell::interface() +{ + return QWaylandWlShellPrivate::interface(); +} + +/*! + * \qmlsignal void QtWaylandCompositor::WlShell::createShellSurface(object surface, object client, int id) + * + * This signal is emitted when the \a client has requested a wl_shell_surface to be associated + * with \a surface and be assigned the given \a id. The handler for this signal is + * expected to create the shell surface and initialize it within the scope of the + * signal emission. + */ + +/*! + * \fn void QWaylandWlShell::createShellSurface(QWaylandSurface *surface, QWaylandClient *client, uint id) + * + * This signal is emitted when the \a client has requested a shell surface to be associated + * with \a surface and be assigned the given \a id. The handler for this signal is + * expected to create the shell surface and initialize it within the scope of the + * signal emission. + */ + +/*! + * \internal + */ +QByteArray QWaylandWlShell::interfaceName() +{ + return QWaylandWlShellPrivate::interfaceName(); +} + +/*! + * \qmltype WlShellSurface + * \inqmlmodule QtWayland.Compositor + * \preliminary + * \brief A wl_shell_surface providing desktop-style compositor-specific features to a surface. + * + * This type is part of the \l{WlShell} extension and provides a way to extend + * the functionality of an existing WaylandSurface with features specific to desktop-style + * compositors, such as resizing and moving the surface. + * + * It corresponds to the Wayland interface wl_shell_surface. + */ + +/*! + * \class QWaylandWlShellSurface + * \inmodule QtWaylandCompositor + * \preliminary + * \brief A shell surface providing desktop-style compositor-specific features to a surface. + * + * This class is part of the QWaylandWlShell extension and provides a way to extend + * the functionality of an existing QWaylandSurface with features specific to desktop-style + * compositors, such as resizing and moving the surface. + * + * It corresponds to the Wayland interface wl_shell_surface. + */ + +/*! + * Constructs a QWaylandWlShellSurface. + */ +QWaylandWlShellSurface::QWaylandWlShellSurface() + : QWaylandShellSurfaceTemplate<QWaylandWlShellSurface>(*new QWaylandWlShellSurfacePrivate) +{ +} + +/*! + * Constructs a QWaylandWlShellSurface for \a surface and initializes it with the given \a shell and \a resource. + */ +QWaylandWlShellSurface::QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &res) + : QWaylandShellSurfaceTemplate<QWaylandWlShellSurface>(*new QWaylandWlShellSurfacePrivate) +{ + initialize(shell, surface, res); +} + +/*! + * \qmlmethod void QtWaylandCompositor::WlShellSurface::initialize(object shell, object surface, object client, int id) + * + * Initializes the WlShellSurface, associating it with the given \a shell, \a surface, \a client, and \a id. + */ + +/*! + * Initializes the QWaylandWlShellSurface, associating it with the given \a shell, \a surface and \a resource. + */ +void QWaylandWlShellSurface::initialize(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource) +{ + Q_D(QWaylandWlShellSurface); + d->m_shell = shell; + d->m_surface = surface; + d->init(resource.resource()); + setExtensionContainer(surface); + emit surfaceChanged(); + QWaylandCompositorExtension::initialize(); +} + +/*! + * \internal + */ +void QWaylandWlShellSurface::initialize() +{ + QWaylandCompositorExtension::initialize(); +} + +const struct wl_interface *QWaylandWlShellSurface::interface() +{ + return QWaylandWlShellSurfacePrivate::interface(); +} + +/*! + * \internal + */ +QByteArray QWaylandWlShellSurface::interfaceName() +{ + return QWaylandWlShellSurfacePrivate::interfaceName(); +} + +QSize QWaylandWlShellSurface::sizeForResize(const QSizeF &size, const QPointF &delta, QWaylandWlShellSurface::ResizeEdge edge) +{ + qreal width = size.width(); + qreal height = size.height(); + if (edge & LeftEdge) + width -= delta.x(); + else if (edge & RightEdge) + width += delta.x(); + + if (edge & TopEdge) + height -= delta.y(); + else if (edge & BottomEdge) + height += delta.y(); + + return QSizeF(width, height).toSize(); +} + +/*! + * \enum QWaylandWlShellSurface::ResizeEdge + * + * This enum type provides a way to specify a specific edge or corner of + * the surface. + * + * \value None No edge. + * \value TopEdge The top edge. + * \value BottomEdge The bottom edge. + * \value LeftEdge The left edge. + * \value TopLeftEdge The top left corner. + * \value BottomLeftEdge The bottom left corner. + * \value RightEdge The right edge. + * \value TopRightEdge The top right corner. + * \value BottomRightEdge The bottom right corner. + */ + +/*! + * \qmlmethod void QtWaylandCompositor::WlShellSurface::sendConfigure(size size, enum edges) + * + * Sends a configure event to the client, suggesting that it resize its surface to + * the provided \a size. The \a edges provide a hint about how the surface + * was resized. + */ + +/*! + * Sends a configure event to the client, suggesting that it resize its surface to + * the provided \a size. The \a edges provide a hint about how the surface + * was resized. + */ +void QWaylandWlShellSurface::sendConfigure(const QSize &size, ResizeEdge edges) +{ + Q_D(QWaylandWlShellSurface); + d->send_configure(edges, size.width(), size.height()); +} + +/*! + * \qmlmethod void QtWaylandCompositor::WlShellSurface::sendPopupDone() + * + * Sends a popup_done event to the client to indicate that the user has clicked + * somewhere outside the client's surfaces. + */ + +/*! + * Sends a popup_done event to the client to indicate that the user has clicked + * somewhere outside the client's surfaces. + */ +void QWaylandWlShellSurface::sendPopupDone() +{ + Q_D(QWaylandWlShellSurface); + d->send_popup_done(); +} + +QWaylandQuickShellIntegration *QWaylandWlShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) +{ + return new QtWayland::WlShellIntegration(item); +} + +/*! + * \qmlproperty object QtWaylandCompositor::WlShellSurface::surface + * + * This property holds the wl_surface associated with this WlShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::surface + * + * This property holds the surface associated with this QWaylandWlShellSurface. + */ +QWaylandSurface *QWaylandWlShellSurface::surface() const +{ + Q_D(const QWaylandWlShellSurface); + return d->m_surface; +} + +/*! + * \enum QWaylandWlShellSurface::FocusPolicy + * + * This enum type is used to specify the focus policy of a shell surface. + * + * \value DefaultFocus The default focus policy should be used. + * \value NoKeyboardFocus The shell surface should not get keyboard focus. + */ + +/*! + * \qmlproperty enum QtWaylandCompositor::WlShellSurface::focusPolicy + * + * This property holds the focus policy of the WlShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::focusPolicy + * + * This property holds the focus policy of the QWaylandWlShellSurface. + */ +QWaylandWlShellSurface::FocusPolicy QWaylandWlShellSurface::focusPolicy() const +{ + Q_D(const QWaylandWlShellSurface); + return d->m_focusPolicy; +} + +/*! + * \qmlproperty string QtWaylandCompositor::WlShellSurface::title + * + * This property holds the title of the WlShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::title + * + * This property holds the title of the QWaylandWlShellSurface. + */ +QString QWaylandWlShellSurface::title() const +{ + Q_D(const QWaylandWlShellSurface); + return d->m_title; +} + +/*! + * \qmlproperty string QtWaylandCompositor::WlShellSurface::className + * + * This property holds the class name of the WlShellSurface. + */ + +/*! + * \property QWaylandWlShellSurface::className + * + * This property holds the class name of the QWaylandWlShellSurface. + */ +QString QWaylandWlShellSurface::className() const +{ + Q_D(const QWaylandWlShellSurface); + return d->m_className; +} + +QWaylandSurfaceRole *QWaylandWlShellSurface::role() +{ + return &QWaylandWlShellSurfacePrivate::s_role; +} + +/*! + * \qmlmethod void QtWaylandCompositor::WlShellSurface::ping() + * + * Sends a ping event to the client. If the client replies to the event the \a pong + * signal will be emitted. + */ + +/*! + * Sends a ping event to the client. If the client replies to the event the \a pong + * signal will be emitted. + */ +void QWaylandWlShellSurface::ping() +{ + Q_D(QWaylandWlShellSurface); + uint32_t serial = d->m_surface->compositor()->nextSerial(); + d->ping(serial); +} + +/*! + * Returns the QWaylandWlShellSurface object associated with the given \a resource, or null if no such object exists. + */ +QWaylandWlShellSurface *QWaylandWlShellSurface::fromResource(wl_resource *resource) +{ + QWaylandWlShellSurfacePrivate::Resource *res = QWaylandWlShellSurfacePrivate::Resource::fromResource(resource); + if (res) + return static_cast<QWaylandWlShellSurfacePrivate *>(res->shell_surface_object)->q_func(); + return 0; +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandwlshell.h b/src/compositor/extensions/qwaylandwlshell.h new file mode 100644 index 000000000..5bddd4f7b --- /dev/null +++ b/src/compositor/extensions/qwaylandwlshell.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDWLSHELL_H +#define QWAYLANDWLSHELL_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> +#include <QtWaylandCompositor/QWaylandResource> +#include <QtWaylandCompositor/QWaylandShellSurface> + +#include <QtCore/QSize> + +QT_BEGIN_NAMESPACE + +class QWaylandWlShellPrivate; +class QWaylandWlShellSurfacePrivate; +class QWaylandSurface; +class QWaylandClient; +class QWaylandInputDevice; +class QWaylandOutput; +class QWaylandSurfaceRole; +class QWaylandWlShellSurface; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShell : public QWaylandCompositorExtensionTemplate<QWaylandWlShell> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandWlShell) +public: + QWaylandWlShell(); + QWaylandWlShell(QWaylandCompositor *compositor); + + void initialize() Q_DECL_OVERRIDE; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + +Q_SIGNALS: + void createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource); + void shellSurfaceCreated(QWaylandWlShellSurface *shellSurface); +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurface : public QWaylandShellSurfaceTemplate<QWaylandWlShellSurface> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandWlShellSurface) + Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) + Q_PROPERTY(QString title READ title NOTIFY titleChanged) + Q_PROPERTY(QString className READ className NOTIFY classNameChanged) + Q_PROPERTY(FocusPolicy focusPolicy READ focusPolicy NOTIFY focusPolicyChanged) + +public: + enum FullScreenMethod { + DefaultFullScreen, + ScaleFullScreen, + DriverFullScreen, + FillFullScreen + }; + Q_ENUM(FullScreenMethod); + + enum ResizeEdge { + NoneEdge = 0, + TopEdge = 1, + BottomEdge = 2, + LeftEdge = 4, + TopLeftEdge = 5, + BottomLeftEdge = 6, + RightEdge = 8, + TopRightEdge = 9, + BottomRightEdge = 10 + }; + Q_ENUM(ResizeEdge); + + enum FocusPolicy{ + DefaultFocus, + NoKeyboardFocus + }; + Q_ENUM(FocusPolicy) + + QWaylandWlShellSurface(); + QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource); + + Q_INVOKABLE void initialize(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource); + + QString title() const; + QString className() const; + + QWaylandSurface *surface() const; + + FocusPolicy focusPolicy() const; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + static QWaylandSurfaceRole *role(); + + static QWaylandWlShellSurface *fromResource(wl_resource *res); + + Q_INVOKABLE QSize sizeForResize(const QSizeF &size, const QPointF &delta, ResizeEdge edges); + Q_INVOKABLE void sendConfigure(const QSize &size, ResizeEdge edges); + Q_INVOKABLE void sendPopupDone(); + + QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; + +public Q_SLOTS: + void ping(); + +Q_SIGNALS: + void surfaceChanged(); + void titleChanged(); + void classNameChanged(); + void focusPolicyChanged(); + void pong(); + void startMove(QWaylandInputDevice *inputDevice); + void startResize(QWaylandInputDevice *inputDevice, ResizeEdge edges); + + void setDefaultToplevel(); + void setTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, FocusPolicy focusPolicy); + void setFullScreen(FullScreenMethod method, uint framerate, QWaylandOutput *output); + void setPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parentSurface, const QPoint &relativeToParent); + void setMaximized(QWaylandOutput *output); + +private: + void initialize() override; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDWLSHELL_H*/ diff --git a/src/compositor/extensions/qwaylandwlshell_p.h b/src/compositor/extensions/qwaylandwlshell_p.h new file mode 100644 index 000000000..39ed645c1 --- /dev/null +++ b/src/compositor/extensions/qwaylandwlshell_p.h @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDWLSHELL_P_H +#define QWAYLANDWLSHELL_P_H + +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandsurface.h> +#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> +#include <QtWaylandCompositor/QWaylandWlShellSurface> +#include <QtWaylandCompositor/QWaylandInputDevice> + +#include <wayland-server.h> +#include <QHash> +#include <QPoint> +#include <QSet> + +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellPrivate + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::wl_shell +{ + Q_DECLARE_PUBLIC(QWaylandWlShell) +public: + QWaylandWlShellPrivate(); + static QWaylandWlShellPrivate *get(QWaylandWlShell *shell) { return shell->d_func(); } + +protected: + void shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurfacePrivate + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::wl_shell_surface +{ + Q_DECLARE_PUBLIC(QWaylandWlShellSurface) +public: + QWaylandWlShellSurfacePrivate(); + ~QWaylandWlShellSurfacePrivate(); + + static QWaylandWlShellSurfacePrivate *get(QWaylandWlShellSurface *surface) { return surface->d_func(); } + + void ping(uint32_t serial); + + void setFocusPolicy(QWaylandWlShellSurface::FocusPolicy focusPolicy) + { + if (focusPolicy == m_focusPolicy) + return; + Q_Q(QWaylandWlShellSurface); + m_focusPolicy = focusPolicy; + emit q->focusPolicyChanged(); + } +private: + QWaylandWlShell *m_shell; + QWaylandSurface *m_surface; + + QSet<uint32_t> m_pings; + + QString m_title; + QString m_className; + QWaylandWlShellSurface::FocusPolicy m_focusPolicy; + + void shell_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void shell_surface_move(Resource *resource, + struct wl_resource *input_device_super, + uint32_t time) Q_DECL_OVERRIDE; + void shell_surface_resize(Resource *resource, + struct wl_resource *input_device, + uint32_t time, + uint32_t edges) Q_DECL_OVERRIDE; + void shell_surface_set_toplevel(Resource *resource) Q_DECL_OVERRIDE; + void shell_surface_set_transient(Resource *resource, + struct wl_resource *parent_surface_resource, + int x, + int y, + uint32_t flags) Q_DECL_OVERRIDE; + void shell_surface_set_fullscreen(Resource *resource, + uint32_t method, + uint32_t framerate, + struct wl_resource *output_resource) Q_DECL_OVERRIDE; + void shell_surface_set_popup(Resource *resource, + struct wl_resource *input_device, + uint32_t time, + struct wl_resource *parent, + int32_t x, + int32_t y, + uint32_t flags) Q_DECL_OVERRIDE; + void shell_surface_set_maximized(Resource *resource, + struct wl_resource *output_resource) Q_DECL_OVERRIDE; + void shell_surface_pong(Resource *resource, + uint32_t serial) Q_DECL_OVERRIDE; + void shell_surface_set_title(Resource *resource, + const QString &title) Q_DECL_OVERRIDE; + void shell_surface_set_class(Resource *resource, + const QString &class_) Q_DECL_OVERRIDE; + + static QWaylandSurfaceRole s_role; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDWLSHELL_P_H diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp new file mode 100644 index 000000000..a1ef5f32a --- /dev/null +++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandwlshellintegration_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandWlShellSurface> +#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> +#include <QtWaylandCompositor/QWaylandInputDevice> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +WlShellIntegration::WlShellIntegration(QWaylandQuickShellSurfaceItem *item) + : QWaylandQuickShellIntegration(item) + , m_item(item) + , m_shellSurface(qobject_cast<QWaylandWlShellSurface *>(item->shellSurface())) + , grabberState(GrabberState::Default) + , isPopup(false) +{ + m_item->setSurface(m_shellSurface->surface()); + connect(m_shellSurface, &QWaylandWlShellSurface::startMove, this, &WlShellIntegration::handleStartMove); + connect(m_shellSurface, &QWaylandWlShellSurface::startResize, this, &WlShellIntegration::handleStartResize); + connect(m_shellSurface->surface(), &QWaylandSurface::offsetForNextFrame, this, &WlShellIntegration::adjustOffsetForNextFrame); + connect(m_shellSurface, &QWaylandWlShellSurface::setPopup, this, &WlShellIntegration::handleSetPopup); + connect(m_shellSurface, &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed); +} + +void WlShellIntegration::handleStartMove(QWaylandInputDevice *inputDevice) +{ + grabberState = GrabberState::Move; + moveState.inputDevice = inputDevice; + moveState.initialized = false; +} + +void WlShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QWaylandWlShellSurface::ResizeEdge edges) +{ + grabberState = GrabberState::Resize; + resizeState.inputDevice = inputDevice; + resizeState.resizeEdges = edges; + float scaleFactor = m_item->view()->output()->scaleFactor(); + resizeState.initialSize = m_shellSurface->surface()->size() / scaleFactor; + resizeState.initialized = false; +} + +void WlShellIntegration::handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent) +{ + Q_UNUSED(inputDevice); + + QWaylandQuickShellSurfaceItem* parentItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(parent->views().first()->renderObject()); + if (parentItem) { + // Clear all the transforms for this ShellSurfaceItem. They are not + // applicable when the item becomes a child to a surface that has its + // own transforms. Otherwise the transforms would be applied twice. + QQmlListProperty<QQuickTransform> t = m_item->transform(); + t.clear(&t); + m_item->setRotation(0); + m_item->setScale(1.0); + m_item->setX(relativeToParent.x()); + m_item->setY(relativeToParent.y()); + m_item->setParentItem(parentItem); + } + + isPopup = true; + QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), &closePopups); + + if (!popupShellSurfaces.contains(m_shellSurface)) { + popupShellSurfaces.append(m_shellSurface); + QObject::connect(m_shellSurface->surface(), &QWaylandSurface::mappedChanged, + this, &WlShellIntegration::handleSurfaceUnmapped); + } +} + +void WlShellIntegration::handlePopupClosed() +{ + handlePopupRemoved(); + if (m_shellSurface) + QObject::disconnect(m_shellSurface->surface(), &QWaylandSurface::mappedChanged, + this, &WlShellIntegration::handleSurfaceUnmapped); +} + +void WlShellIntegration::handlePopupRemoved() +{ + if (m_shellSurface) + popupShellSurfaces.removeOne(m_shellSurface); + if (popupShellSurfaces.isEmpty()) + QWaylandQuickShellEventFilter::cancelFilter(); + isPopup = false; +} + + +void WlShellIntegration::handleShellSurfaceDestroyed() +{ + if (isPopup) + handlePopupRemoved(); + m_shellSurface = nullptr; +} + +void WlShellIntegration::handleSurfaceUnmapped() +{ + if (!m_shellSurface || !m_shellSurface->surface()->size().isEmpty()) + return; + handlePopupClosed(); +} + +void WlShellIntegration::adjustOffsetForNextFrame(const QPointF &offset) +{ + float scaleFactor = m_item->view()->output()->scaleFactor(); + QQuickItem *moveItem = m_item->moveItem(); + moveItem->setPosition(moveItem->position() + offset * scaleFactor); +} + +bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event) +{ + if (grabberState == GrabberState::Resize) { + Q_ASSERT(resizeState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + if (!resizeState.initialized) { + resizeState.initialMousePos = event->windowPos(); + resizeState.initialized = true; + return true; + } + float scaleFactor = m_item->view()->output()->scaleFactor(); + QPointF delta = (event->windowPos() - resizeState.initialMousePos) / scaleFactor; + QSize newSize = m_shellSurface->sizeForResize(resizeState.initialSize, delta, resizeState.resizeEdges); + m_shellSurface->sendConfigure(newSize, resizeState.resizeEdges); + } else if (grabberState == GrabberState::Move) { + Q_ASSERT(moveState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + QQuickItem *moveItem = m_item->moveItem(); + if (!moveState.initialized) { + moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos()); + moveState.initialized = true; + return true; + } + if (!moveItem->parentItem()) + return true; + QPointF parentPos = moveItem->parentItem()->mapFromItem(nullptr, event->windowPos()); + moveItem->setPosition(parentPos - moveState.initialOffset); + } + return false; +} + +bool WlShellIntegration::mouseReleaseEvent(QMouseEvent *event) +{ + Q_UNUSED(event); + if (grabberState != GrabberState::Default) { + grabberState = GrabberState::Default; + return true; + } + return false; +} + +QVector<QWaylandWlShellSurface*> WlShellIntegration::popupShellSurfaces; + +void WlShellIntegration::closePopups() +{ + if (!popupShellSurfaces.isEmpty()) { + Q_FOREACH (QWaylandWlShellSurface* shellSurface, popupShellSurfaces) { + shellSurface->sendPopupDone(); + } + popupShellSurfaces.clear(); + } +} + +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandwlshellintegration_p.h b/src/compositor/extensions/qwaylandwlshellintegration_p.h new file mode 100644 index 000000000..3f063af39 --- /dev/null +++ b/src/compositor/extensions/qwaylandwlshellintegration_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDWLSHELLINTEGRATION_H +#define QWAYLANDWLSHELLINTEGRATION_H + +#include <QtWaylandCompositor/private/qwaylandquickshellsurfaceitem_p.h> + +#include <QtWaylandCompositor/QWaylandWlShellSurface> + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace QtWayland { + +class WlShellIntegration : public QWaylandQuickShellIntegration +{ + Q_OBJECT +public: + WlShellIntegration(QWaylandQuickShellSurfaceItem *item); + bool mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void handleStartMove(QWaylandInputDevice *inputDevice); + void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandWlShellSurface::ResizeEdge edges); + void handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent); + void handleShellSurfaceDestroyed(); + void handleSurfaceUnmapped(); + void adjustOffsetForNextFrame(const QPointF &offset); + +private: + enum class GrabberState { + Default, + Resize, + Move + }; + + void handlePopupClosed(); + void handlePopupRemoved(); + + static void closePopups(); + + QWaylandQuickShellSurfaceItem *m_item; + QWaylandWlShellSurface *m_shellSurface; + GrabberState grabberState; + struct { + QWaylandInputDevice *inputDevice; + QPointF initialOffset; + bool initialized; + } moveState; + struct { + QWaylandInputDevice *inputDevice; + QWaylandWlShellSurface::ResizeEdge resizeEdges; + QSizeF initialSize; + QPointF initialMousePos; + bool initialized; + } resizeState; + + static QVector<QWaylandWlShellSurface*> popupShellSurfaces; + bool isPopup; +}; + +} + +QT_END_NAMESPACE + +#endif // QWAYLANDWLSHELLINTEGRATION_H diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp new file mode 100644 index 000000000..dfc68e254 --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshell.cpp @@ -0,0 +1,1061 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandxdgshell.h" +#include "qwaylandxdgshell_p.h" +#include "qwaylandxdgshellintegration_p.h" + +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandSurface> +#include <QtWaylandCompositor/QWaylandSurfaceRole> +#include <QtWaylandCompositor/QWaylandResource> +#include <QtWaylandCompositor/QWaylandInputDevice> + +#include <QtCore/QObject> + +#include <algorithm> + +QT_BEGIN_NAMESPACE + +QWaylandSurfaceRole QWaylandXdgSurfacePrivate::s_role("xdg_surface"); +QWaylandSurfaceRole QWaylandXdgPopupPrivate::s_role("xdg_popup"); + +QWaylandXdgShellPrivate::QWaylandXdgShellPrivate() + : QWaylandCompositorExtensionPrivate() + , xdg_shell() +{ +} + +void QWaylandXdgShellPrivate::ping(Resource *resource, uint32_t serial) +{ + m_pings.insert(serial); + send_ping(resource->handle, serial); +} + +void QWaylandXdgShellPrivate::registerSurface(QWaylandXdgSurface *xdgSurface) +{ + m_xdgSurfaces.insert(xdgSurface->surface()->client()->client(), xdgSurface); +} + +void QWaylandXdgShellPrivate::unregisterXdgSurface(QWaylandXdgSurface *xdgSurface) +{ + auto xdgSurfacePrivate = QWaylandXdgSurfacePrivate::get(xdgSurface); + if (!m_xdgSurfaces.remove(xdgSurfacePrivate->resource()->client(), xdgSurface)) + qWarning("%s Unexpected state. Can't find registered xdg surface\n", Q_FUNC_INFO); +} + +void QWaylandXdgShellPrivate::registerXdgPopup(QWaylandXdgPopup *xdgPopup) +{ + m_xdgPopups.insert(xdgPopup->surface()->client()->client(), xdgPopup); +} + +void QWaylandXdgShellPrivate::unregisterXdgPopup(QWaylandXdgPopup *xdgPopup) +{ + auto xdgPopupPrivate = QWaylandXdgPopupPrivate::get(xdgPopup); + if (!m_xdgPopups.remove(xdgPopupPrivate->resource()->client(), xdgPopup)) + qWarning("%s Unexpected state. Can't find registered xdg popup\n", Q_FUNC_INFO); +} + +bool QWaylandXdgShellPrivate::isValidPopupParent(QWaylandSurface *parentSurface) const +{ + QWaylandXdgPopup *topmostPopup = topmostPopupForClient(parentSurface->client()->client()); + if (topmostPopup && topmostPopup->surface() != parentSurface) { + return false; + } + + QWaylandSurfaceRole *parentRole = parentSurface->role(); + if (parentRole != QWaylandXdgSurface::role() && parentRole != QWaylandXdgPopup::role()) { + return false; + } + + return true; +} + +QWaylandXdgPopup *QWaylandXdgShellPrivate::topmostPopupForClient(wl_client *client) const +{ + QList<QWaylandXdgPopup *> clientPopups = m_xdgPopups.values(client); + return clientPopups.empty() ? nullptr : clientPopups.last(); +} + +QWaylandXdgSurface *QWaylandXdgShellPrivate::xdgSurfaceFromSurface(QWaylandSurface *surface) +{ + Q_FOREACH (QWaylandXdgSurface *xdgSurface, m_xdgSurfaces) { + if (surface == xdgSurface->surface()) + return xdgSurface; + } + return nullptr; +} + +void QWaylandXdgShellPrivate::xdg_shell_destroy(Resource *resource) +{ + if (!m_xdgSurfaces.values(resource->client()).empty()) + wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_DEFUNCT_SURFACES, + "xdg_shell was destroyed before children"); + + wl_resource_destroy(resource->handle); +} + +void QWaylandXdgShellPrivate::xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, + wl_resource *surface_res) +{ + Q_Q(QWaylandXdgShell); + QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res); + + if (xdgSurfaceFromSurface(surface)) { + wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_ROLE, + "An active xdg_surface already exists for wl_surface@%d", + wl_resource_get_id(surface->resource())); + return; + } + + if (!surface->setRole(QWaylandXdgSurface::role(), resource->handle, XDG_SHELL_ERROR_ROLE)) + return; + + QWaylandResource xdgSurfaceResource(wl_resource_create(resource->client(), &xdg_surface_interface, + wl_resource_get_version(resource->handle), id)); + + emit q->createXdgSurface(surface, xdgSurfaceResource); + + QWaylandXdgSurface *xdgSurface = QWaylandXdgSurface::fromResource(xdgSurfaceResource.resource()); + if (!xdgSurface) { + // A QWaylandXdgSurface was not created in response to the createXdgSurface signal, so we + // create one as fallback here instead. + xdgSurface = new QWaylandXdgSurface(q, surface, xdgSurfaceResource); + } + + registerSurface(xdgSurface); + emit q->xdgSurfaceCreated(xdgSurface); +} + +void QWaylandXdgShellPrivate::xdg_shell_use_unstable_version(Resource *resource, int32_t version) +{ + if (xdg_shell::version_current != version) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, + "incompatible version, server is %d, but client wants %d", + xdg_shell::version_current, version); + } +} + +void QWaylandXdgShellPrivate::xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, + wl_resource *surface_res, wl_resource *parent, + wl_resource *seat, uint32_t serial, + int32_t x, int32_t y) +{ + Q_UNUSED(serial); + Q_Q(QWaylandXdgShell); + QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res); + QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent); + + if (!isValidPopupParent(parentSurface)) { + wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_INVALID_POPUP_PARENT, + "the client specified an invalid popup parent surface"); + return; + } + + if (!surface->setRole(QWaylandXdgPopup::role(), resource->handle, XDG_SHELL_ERROR_ROLE)) { + return; + } + + QWaylandResource xdgPopupResource (wl_resource_create(resource->client(), &xdg_popup_interface, + wl_resource_get_version(resource->handle), id)); + QWaylandInputDevice *inputDevice = QWaylandInputDevice::fromSeatResource(seat); + QPoint position(x, y); + emit q->createXdgPopup(surface, parentSurface, inputDevice, position, xdgPopupResource); + + QWaylandXdgPopup *xdgPopup = QWaylandXdgPopup::fromResource(xdgPopupResource.resource()); + if (!xdgPopup) { + // A QWaylandXdgPopup was not created in response to the createXdgPopup signal, so we + // create one as fallback here instead. + xdgPopup = new QWaylandXdgPopup(q, surface, parentSurface, xdgPopupResource); + } + + registerXdgPopup(xdgPopup); + emit q->xdgPopupCreated(xdgPopup); +} + +void QWaylandXdgShellPrivate::xdg_shell_pong(Resource *resource, uint32_t serial) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgShell); + if (m_pings.remove(serial)) + emit q->pong(serial); + else + qWarning("Received an unexpected pong!"); +} + +QWaylandXdgSurfacePrivate::QWaylandXdgSurfacePrivate() + : QWaylandCompositorExtensionPrivate() + , xdg_surface() + , m_surface(nullptr) + , m_parentSurface(nullptr) + , m_unsetWindowGeometry(true) + , m_lastAckedConfigure({{}, QSize(0, 0), 0}) +{ +} + +void QWaylandXdgSurfacePrivate::handleFocusLost() +{ + Q_Q(QWaylandXdgSurface); + QWaylandXdgSurfacePrivate::ConfigureEvent current = lastSentConfigure(); + current.states.removeOne(QWaylandXdgSurface::State::ActivatedState); + q->sendConfigure(current.size, current.states); +} + +void QWaylandXdgSurfacePrivate::handleFocusReceived() +{ + Q_Q(QWaylandXdgSurface); + + QWaylandXdgSurfacePrivate::ConfigureEvent current = lastSentConfigure(); + if (!current.states.contains(QWaylandXdgSurface::State::ActivatedState)) { + current.states.push_back(QWaylandXdgSurface::State::ActivatedState); + } + + q->sendConfigure(current.size, current.states); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurface); + QWaylandXdgShellPrivate::get(m_xdgShell)->unregisterXdgSurface(q); + delete q; +} + +void QWaylandXdgSurfacePrivate::xdg_surface_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_move(Resource *resource, wl_resource *seat, uint32_t serial) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + + Q_Q(QWaylandXdgSurface); + QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat); + emit q->startMove(input_device); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_resize(Resource *resource, wl_resource *seat, + uint32_t serial, uint32_t edges) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + + Q_Q(QWaylandXdgSurface); + QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat); + emit q->startResize(input_device, QWaylandXdgSurface::ResizeEdge(edges)); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_set_maximized(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurface); + emit q->setMaximized(); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_unset_maximized(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurface); + emit q->unsetMaximized(); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_set_fullscreen(Resource *resource, wl_resource *output_res) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurface); + QWaylandOutput *output = output_res ? QWaylandOutput::fromResource(output_res) : nullptr; + emit q->setFullscreen(output); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_unset_fullscreen(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurface); + emit q->unsetFullscreen(); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_set_minimized(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurface); + emit q->setMinimized(); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_set_parent(Resource *resource, wl_resource *parent) +{ + Q_UNUSED(resource); + QWaylandXdgSurface *parentSurface = nullptr; + if (parent) { + parentSurface = static_cast<QWaylandXdgSurfacePrivate *>( + QWaylandXdgSurfacePrivate::Resource::fromResource(parent)->xdg_surface_object)->q_func(); + } + + if (m_parentSurface == parentSurface) + return; + + Q_Q(QWaylandXdgSurface); + m_parentSurface = parentSurface; + emit q->parentSurfaceChanged(); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_set_app_id(Resource *resource, const QString &app_id) +{ + Q_UNUSED(resource); + if (app_id == m_appId) + return; + Q_Q(QWaylandXdgSurface); + m_appId = app_id; + emit q->appIdChanged(); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_show_window_menu(Resource *resource, wl_resource *seat, + uint32_t serial, int32_t x, int32_t y) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + QPoint position(x, y); + auto inputDevice = QWaylandInputDevice::fromSeatResource(seat); + Q_Q(QWaylandXdgSurface); + emit q->showWindowMenu(inputDevice, position); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_ack_configure(Resource *resource, uint32_t serial) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurface); + + ConfigureEvent config; + Q_FOREVER { + if (m_pendingConfigures.empty()) { + qWarning("Received an unexpected ack_configure!"); + return; + } + + config = m_pendingConfigures.takeFirst(); + + if (config.serial == serial) + break; + } + + QVector<uint> changedStates; + std::set_symmetric_difference( + m_lastAckedConfigure.states.begin(), m_lastAckedConfigure.states.end(), + config.states.begin(), config.states.end(), + std::back_inserter(changedStates)); + + m_lastAckedConfigure = config; + + if (!changedStates.empty()) { + Q_FOREACH (uint state, changedStates) { + switch (state) { + case QWaylandXdgSurface::State::MaximizedState: + emit q->maximizedChanged(); + break; + case QWaylandXdgSurface::State::FullscreenState: + emit q->fullscreenChanged(); + break; + case QWaylandXdgSurface::State::ResizingState: + emit q->resizingChanged(); + break; + case QWaylandXdgSurface::State::ActivatedState: + emit q->activatedChanged(); + break; + } + } + emit q->statesChanged(); + } + + emit q->ackConfigure(serial); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_set_title(Resource *resource, const QString &title) +{ + Q_UNUSED(resource); + if (title == m_title) + return; + Q_Q(QWaylandXdgSurface); + m_title = title; + emit q->titleChanged(); +} + +void QWaylandXdgSurfacePrivate::xdg_surface_set_window_geometry(Resource *resource, + int32_t x, int32_t y, + int32_t width, int32_t height) +{ + Q_UNUSED(resource); + + if (width <= 0 || height <= 0) { + qWarning() << "Invalid (non-positive) dimensions received in set_window_geometry"; + return; + } + + m_unsetWindowGeometry = false; + + QRect geometry(x, y, width, height); + + Q_Q(QWaylandXdgSurface); + if ((q->maximized() || q->fullscreen()) && m_lastAckedConfigure.size != geometry.size()) + qWarning() << "Client window geometry did not obey last acked configure"; + + if (geometry == m_windowGeometry) + return; + + m_windowGeometry = geometry; + emit q->windowGeometryChanged(); +} + +QWaylandXdgPopupPrivate::QWaylandXdgPopupPrivate() + : QWaylandCompositorExtensionPrivate() + , xdg_popup() + , m_surface(nullptr) + , m_parentSurface(nullptr) + , m_xdgShell(nullptr) +{ +} + +void QWaylandXdgPopupPrivate::xdg_popup_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgPopup); + QWaylandXdgShellPrivate::get(m_xdgShell)->unregisterXdgPopup(q); + delete q; +} + +void QWaylandXdgPopupPrivate::xdg_popup_destroy(Resource *resource) +{ + //TODO: post error if not topmost popup + wl_resource_destroy(resource->handle); +} + +/*! + * Constructs a QWaylandXdgShell object. + */ +QWaylandXdgShell::QWaylandXdgShell() + : QWaylandCompositorExtensionTemplate<QWaylandXdgShell>(*new QWaylandXdgShellPrivate()) +{ } + +/*! + * Constructs a QWaylandXdgShell object for the provided \a compositor. + */ +QWaylandXdgShell::QWaylandXdgShell(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate<QWaylandXdgShell>(compositor, *new QWaylandXdgShellPrivate()) +{ } + +/*! + * Initializes the shell extension. + */ +void QWaylandXdgShell::initialize() +{ + Q_D(QWaylandXdgShell); + QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandXdgShell"; + return; + } + d->init(compositor->display(), 1); + + handleDefaultInputDeviceChanged(compositor->defaultInputDevice(), nullptr); + + connect(compositor, &QWaylandCompositor::defaultInputDeviceChanged, + this, &QWaylandXdgShell::handleDefaultInputDeviceChanged); +} + +/*! + * Returns the Wayland interface for the QWaylandXdgShell. + */ +const struct wl_interface *QWaylandXdgShell::interface() +{ + return QWaylandXdgShellPrivate::interface(); +} + +QByteArray QWaylandXdgShell::interfaceName() +{ + return QWaylandXdgShellPrivate::interfaceName(); +} + +/*! + * \qmlmethod void QtWaylandCompositor::XdgSurface::ping() + * + * Sends a ping event to the client. If the client replies to the event the + * \a pong signal will be emitted. + */ + +/*! + * Sends a ping event to the client. If the client replies to the event the + * \a pong signal will be emitted. + */ +uint QWaylandXdgShell::ping(QWaylandClient *client) +{ + Q_D(QWaylandXdgShell); + + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); + Q_ASSERT(compositor); + + uint32_t serial = compositor->nextSerial(); + + QWaylandXdgShellPrivate::Resource *clientResource = d->resourceMap().value(client->client(), nullptr); + Q_ASSERT(clientResource); + + d->ping(clientResource, serial); + return serial; +} + +void QWaylandXdgShell::closeAllPopups() +{ + Q_D(QWaylandXdgShell); + Q_FOREACH (struct wl_client *client, d->m_xdgPopups.keys()) { + QList<QWaylandXdgPopup *> popups = d->m_xdgPopups.values(client); + std::reverse(popups.begin(), popups.end()); + Q_FOREACH (QWaylandXdgPopup *currentTopmostPopup, popups) { + currentTopmostPopup->sendPopupDone(); + } + } +} + +void QWaylandXdgShell::handleDefaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice) +{ + if (oldDevice != nullptr) { + disconnect(oldDevice, &QWaylandInputDevice::keyboardFocusChanged, + this, &QWaylandXdgShell::handleFocusChanged); + } + + if (newDevice != nullptr) { + connect(newDevice, &QWaylandInputDevice::keyboardFocusChanged, + this, &QWaylandXdgShell::handleFocusChanged); + } +} + +void QWaylandXdgShell::handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) +{ + Q_D(QWaylandXdgShell); + + QWaylandXdgSurface *newXdgSurface = d->xdgSurfaceFromSurface(newSurface); + QWaylandXdgSurface *oldXdgSurface = d->xdgSurfaceFromSurface(oldSurface); + + if (newXdgSurface) + QWaylandXdgSurfacePrivate::get(newXdgSurface)->handleFocusReceived(); + + if (oldXdgSurface) + QWaylandXdgSurfacePrivate::get(oldXdgSurface)->handleFocusLost(); +} + +/*! + * \class QWaylandXdgSurface + * \inmodule QtWaylandCompositor + * \preliminary + * \brief An xdg surface providing desktop-style compositor-specific features to a surface. + * + * This class is part of the QWaylandXdgShell extension and provides a way to + * extend the functionality of an existing QWaylandSurface with features + * specific to desktop-style compositors, such as resizing and moving the + * surface. + * + * It corresponds to the Wayland interface xdg_surface. + */ + +/*! + * Constructs a QWaylandXdgSurface. + */ +QWaylandXdgSurface::QWaylandXdgSurface() + : QWaylandShellSurfaceTemplate<QWaylandXdgSurface>(*new QWaylandXdgSurfacePrivate) +{ +} + +/*! + * Constructs a QWaylandXdgSurface for \a surface and initializes it with the + * given \a xdgShell, \a surface and \a resource. + */ +QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, const QWaylandResource &res) + : QWaylandShellSurfaceTemplate<QWaylandXdgSurface>(*new QWaylandXdgSurfacePrivate) +{ + initialize(xdgShell, surface, res); +} + +/*! + * \qmlmethod void QtWaylandCompositor::XdgSurface::initialize(object surface, object client, int id) + * + * Initializes the XdgSurface, associating it with the given \a surface, + * \a client, and \a id. + */ + +/*! + * Initializes the QWaylandXdgSurface, associating it with the given \a xdgShell, \a surface + * and \a resource. + */ +void QWaylandXdgSurface::initialize(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, const QWaylandResource &resource) +{ + Q_D(QWaylandXdgSurface); + d->m_xdgShell = xdgShell; + d->m_surface = surface; + d->init(resource.resource()); + setExtensionContainer(surface); + d->m_windowGeometry = QRect(QPoint(0,0), surface->size()); + connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurface::handleSurfaceSizeChanged); + emit surfaceChanged(); + emit windowGeometryChanged(); + QWaylandCompositorExtension::initialize(); +} + +/*! + * \internal + */ +void QWaylandXdgSurface::initialize() +{ + QWaylandCompositorExtension::initialize(); +} + +QList<int> QWaylandXdgSurface::statesAsInts() const +{ + QList<int> list; + Q_FOREACH (uint state, states()) { + list << static_cast<int>(state); + } + return list; +} + +void QWaylandXdgSurface::handleSurfaceSizeChanged() +{ + Q_D(QWaylandXdgSurface); + if (d->m_unsetWindowGeometry && d->m_windowGeometry.size() != surface()->size()) { + // TODO: The unset window geometry should include subsurfaces as well, so this solution + // won't work too well on those kinds of clients. + d->m_windowGeometry.setSize(surface()->size()); + emit windowGeometryChanged(); + } +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgSurface::surface + * + * This property holds the surface associated with this XdgSurface. + */ + +/*! + * \property QWaylandXdgSurface::surface + * + * This property holds the surface associated with this QWaylandXdgSurface. + */ +QWaylandSurface *QWaylandXdgSurface::surface() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_surface; +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgSurface::parentSurface + * + * This property holds the XdgSurface parent of this XdgSurface. + */ + +/*! + * \property QWaylandXdgSurface::surface + * + * This property holds the XdgSurface parent of this XdgSurface. + */ +QWaylandXdgSurface *QWaylandXdgSurface::parentSurface() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_parentSurface; +} + +/*! + * \qmlproperty string QtWaylandCompositor::XdgSurface::title + * + * This property holds the title of the XdgSurface. + */ + +/*! + * \property QWaylandXdgSurface::title + * + * This property holds the title of the QWaylandXdgSurface. + */ +QString QWaylandXdgSurface::title() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_title; +} + +/*! + * \property QWaylandXdgSurface::appId + * + * This property holds the app id of the QWaylandXdgSurface. + */ +QString QWaylandXdgSurface::appId() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_appId; +} + +/*! + * \property QWaylandXdgSurface::windowGeometry + * + * This property holds the window geometry of the QWaylandXdgSurface. The window + * geometry describes the window's visible bounds from the user's perspective. + * The geometry includes title bars and borders if drawn by the client, but + * excludes drop shadows. It is meant to be used for aligning and tiling + * windows. + */ +QRect QWaylandXdgSurface::windowGeometry() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_windowGeometry; +} + +/*! + * \property QWaylandXdgSurface::states + * + * This property holds the last states the client acknowledged for this QWaylandXdgSurface. + */ +QVector<uint> QWaylandXdgSurface::states() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_lastAckedConfigure.states; +} + +bool QWaylandXdgSurface::maximized() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::MaximizedState); +} + +bool QWaylandXdgSurface::fullscreen() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::FullscreenState); +} + +bool QWaylandXdgSurface::resizing() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::ResizingState); +} + +bool QWaylandXdgSurface::activated() const +{ + Q_D(const QWaylandXdgSurface); + return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::ActivatedState); +} + +/*! + * Returns the Wayland interface for the QWaylandXdgSurface. + */ +const wl_interface *QWaylandXdgSurface::interface() +{ + return QWaylandXdgSurfacePrivate::interface(); +} + +QByteArray QWaylandXdgSurface::interfaceName() +{ + return QWaylandXdgSurfacePrivate::interfaceName(); +} + +/*! + * Returns the surface role for the QWaylandXdgSurface. + */ +QWaylandSurfaceRole *QWaylandXdgSurface::role() +{ + return &QWaylandXdgSurfacePrivate::s_role; +} + +/*! + * Returns the QWaylandXdgSurface corresponding to the \a resource. + */ +QWaylandXdgSurface *QWaylandXdgSurface::fromResource(wl_resource *resource) +{ + auto xsResource = QWaylandXdgSurfacePrivate::Resource::fromResource(resource); + if (!xsResource) + return nullptr; + return static_cast<QWaylandXdgSurfacePrivate *>(xsResource->xdg_surface_object)->q_func(); +} + +QSize QWaylandXdgSurface::sizeForResize(const QSizeF &size, const QPointF &delta, + QWaylandXdgSurface::ResizeEdge edge) +{ + qreal width = size.width(); + qreal height = size.height(); + if (edge & LeftEdge) + width -= delta.x(); + else if (edge & RightEdge) + width += delta.x(); + + if (edge & TopEdge) + height -= delta.y(); + else if (edge & BottomEdge) + height += delta.y(); + + return QSizeF(width, height).toSize(); +} + +/*! + * \qmlmethod int QtWaylandCompositor::XdgSurface::sendConfigure(size size, List<uint>) + * + * Sends a configure event to the client. Known states are enumerated in XdgSurface::State + */ + +/*! + * Sends a configure event to the client. Known states are enumerated in QWaylandXdgSurface::State + */ +uint QWaylandXdgSurface::sendConfigure(const QSize &size, const QVector<uint> &states) +{ + Q_D(QWaylandXdgSurface); + auto statesBytes = QByteArray::fromRawData((char *)states.data(), states.size() * sizeof(State)); + QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer()); + Q_ASSERT(compositor); + uint32_t serial = compositor->nextSerial(); + d->m_pendingConfigures.append(QWaylandXdgSurfacePrivate::ConfigureEvent{states, size, serial}); + d->send_configure(size.width(), size.height(), statesBytes, serial); + return serial; +} + +uint QWaylandXdgSurface::sendConfigure(const QSize &size, const QVector<QWaylandXdgSurface::State> &states) +{ + QVector<uint> asUints; + Q_FOREACH (QWaylandXdgSurface::State state, states) { + asUints << state; + } + return sendConfigure(size, asUints); +} + +/*! + * \qmlmethod void QtWaylandCompositor::XdgSurface::sendClose() + * + * Sends a close event to the client. + */ + +/*! + * Sends a close event to the client. + */ +void QWaylandXdgSurface::sendClose() +{ + Q_D(QWaylandXdgSurface); + d->send_close(); +} + +uint QWaylandXdgSurface::requestMaximized(const QSize &size) +{ + Q_D(QWaylandXdgSurface); + QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); + + if (!conf.states.contains(QWaylandXdgSurface::State::MaximizedState)) + conf.states.append(QWaylandXdgSurface::State::MaximizedState); + conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState); + conf.states.removeOne(QWaylandXdgSurface::State::ResizingState); + + return sendConfigure(size, conf.states); +} + +uint QWaylandXdgSurface::requestUnMaximized(const QSize &size) +{ + Q_D(QWaylandXdgSurface); + QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); + + conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState); + conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState); + conf.states.removeOne(QWaylandXdgSurface::State::ResizingState); + + return sendConfigure(size, conf.states); +} + +uint QWaylandXdgSurface::requestFullscreen(const QSize &size) +{ + Q_D(QWaylandXdgSurface); + QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); + + if (!conf.states.contains(QWaylandXdgSurface::State::FullscreenState)) + conf.states.append(QWaylandXdgSurface::State::FullscreenState); + conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState); + conf.states.removeOne(QWaylandXdgSurface::State::ResizingState); + + return sendConfigure(size, conf.states); +} + +uint QWaylandXdgSurface::requestResizing(const QSize &maxSize) +{ + Q_D(QWaylandXdgSurface); + QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); + + if (!conf.states.contains(QWaylandXdgSurface::State::ResizingState)) + conf.states.append(QWaylandXdgSurface::State::ResizingState); + conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState); + conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState); + + return sendConfigure(maxSize, conf.states); +} + +QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) +{ + return new QtWayland::XdgShellIntegration(item); +} + +/*! + * \class QWaylandXdgPopup + * \inmodule QtWaylandCompositor + * \preliminary + * \brief An xdg popup providing menus for an xdg surface + * + * This class is part of the QWaylandXdgShell extension and provides a way to + * extend the functionality of an existing QWaylandSurface with features + * specific to desktop-style menus for an xdg surface. + * + * It corresponds to the Wayland interface xdg_popup. + */ + +/*! + * Constructs a QWaylandXdgPopup. + */ +QWaylandXdgPopup::QWaylandXdgPopup() + : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) +{ +} + +/*! + * Constructs a QWaylandXdgPopup for \a surface and initializes it with the + * given \a parentSurface and \a resource. + */ +QWaylandXdgPopup::QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, + QWaylandSurface *parentSurface, const QWaylandResource &resource) + : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate) +{ + initialize(xdgShell, surface, parentSurface, resource); +} + +/*! + * \qmlmethod void QtWaylandCompositor::XdgPopup::initialize(object surface, object parentSurface, object resource) + * + * Initializes the xdg popup, associating it with the given \a shell, \a surface, + * \a parentSurface and \a resource. + */ + +/*! + * Initializes the QWaylandXdgPopup, associating it with the given \a shell \a surface, + * \a parentSurface and \a resource. + */ +void QWaylandXdgPopup::initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, + QWaylandSurface *parentSurface, const QWaylandResource &resource) +{ + Q_D(QWaylandXdgPopup); + d->m_surface = surface; + d->m_parentSurface = parentSurface; + d->m_xdgShell = shell; + d->init(resource.resource()); + setExtensionContainer(surface); + emit surfaceChanged(); + emit parentSurfaceChanged(); + QWaylandCompositorExtension::initialize(); +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::surface + * + * This property holds the surface associated with this XdgPopup. + */ + +/*! + * \property QWaylandXdgPopup::surface + * + * This property holds the surface associated with this QWaylandXdgPopup. + */ +QWaylandSurface *QWaylandXdgPopup::surface() const +{ + Q_D(const QWaylandXdgPopup); + return d->m_surface; +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::parentSurface + * + * This property holds the surface associated with the parent of this XdgPopup. + */ + +/*! + * \property QWaylandXdgPopup::parentSurface + * + * This property holds the surface associated with the parent of this + * QWaylandXdgPopup. + */ +QWaylandSurface *QWaylandXdgPopup::parentSurface() const +{ + Q_D(const QWaylandXdgPopup); + return d->m_parentSurface; +} + +/*! + * \internal + */ +void QWaylandXdgPopup::initialize() +{ + QWaylandCompositorExtensionTemplate::initialize(); +} + +/*! + * Returns the Wayland interface for the QWaylandXdgPopup. + */ +const wl_interface *QWaylandXdgPopup::interface() +{ + return QWaylandXdgPopupPrivate::interface(); +} + +QByteArray QWaylandXdgPopup::interfaceName() +{ + return QWaylandXdgPopupPrivate::interfaceName(); +} + +/*! + * Returns the surface role for the QWaylandXdgPopup. + */ +QWaylandSurfaceRole *QWaylandXdgPopup::role() +{ + return &QWaylandXdgPopupPrivate::s_role; +} + +QWaylandXdgPopup *QWaylandXdgPopup::fromResource(wl_resource *resource) +{ + auto popupResource = QWaylandXdgPopupPrivate::Resource::fromResource(resource); + if (!popupResource) + return nullptr; + return static_cast<QWaylandXdgPopupPrivate *>(popupResource->xdg_popup_object)->q_func(); +} + +void QWaylandXdgPopup::sendPopupDone() +{ + Q_D(QWaylandXdgPopup); + d->send_popup_done(); +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshell.h new file mode 100644 index 000000000..c11ca1f3a --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshell.h @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXDGSHELL_H +#define QWAYLANDXDGSHELL_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> +#include <QtWaylandCompositor/QWaylandResource> +#include <QtWaylandCompositor/QWaylandShellSurface> + +#include <QtCore/QRect> + +struct wl_resource; + +QT_BEGIN_NAMESPACE + +class QWaylandXdgShellPrivate; +class QWaylandXdgSurface; +class QWaylandXdgSurfacePrivate; +class QWaylandXdgPopup; +class QWaylandXdgPopupPrivate; + +class QWaylandSurface; +class QWaylandSurfaceRole; +class QWaylandInputDevice; +class QWaylandOutput; +class QWaylandClient; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShell : public QWaylandCompositorExtensionTemplate<QWaylandXdgShell> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandXdgShell) +public: + QWaylandXdgShell(); + QWaylandXdgShell(QWaylandCompositor *compositor); + + void initialize() Q_DECL_OVERRIDE; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + +public Q_SLOTS: + uint ping(QWaylandClient *client); + void closeAllPopups(); + +Q_SIGNALS: + void createXdgSurface(QWaylandSurface *surface, const QWaylandResource &resource); + void xdgSurfaceCreated(QWaylandXdgSurface *xdgSurface); + void xdgPopupCreated(QWaylandXdgPopup *xdgPopup); + void createXdgPopup(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandInputDevice *seat, const QPoint &position, const QWaylandResource &resource); + void pong(uint serial); + +private Q_SLOTS: + void handleDefaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice); + void handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); + +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurface : public QWaylandShellSurfaceTemplate<QWaylandXdgSurface> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandXdgSurface) + Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) + Q_PROPERTY(QWaylandXdgSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) + Q_PROPERTY(QString title READ title NOTIFY titleChanged) + Q_PROPERTY(QString appId READ appId NOTIFY appIdChanged) + Q_PROPERTY(QRect windowGeometry READ windowGeometry NOTIFY windowGeometryChanged) + + Q_PROPERTY(QList<int> states READ statesAsInts NOTIFY statesChanged) + Q_PROPERTY(bool maximized READ maximized NOTIFY maximizedChanged) + Q_PROPERTY(bool fullscreen READ fullscreen NOTIFY fullscreenChanged) + Q_PROPERTY(bool resizing READ resizing NOTIFY resizingChanged) + Q_PROPERTY(bool activated READ activated NOTIFY activatedChanged) + +public: + enum State : uint { + MaximizedState = 1, + FullscreenState = 2, + ResizingState = 3, + ActivatedState = 4 + }; + Q_ENUM(State) + + enum ResizeEdge : uint { + NoneEdge = 0, + TopEdge = 1, + BottomEdge = 2, + LeftEdge = 4, + TopLeftEdge = 5, + BottomLeftEdge = 6, + RightEdge = 8, + TopRightEdge = 9, + BottomRightEdge = 10 + }; + Q_ENUM(ResizeEdge) + + QWaylandXdgSurface(); + QWaylandXdgSurface(QWaylandXdgShell* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource); + + Q_INVOKABLE void initialize(QWaylandXdgShell* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource); + + QString title() const; + QString appId() const; + QRect windowGeometry() const; + QVector<uint> states() const; + bool maximized() const; + bool fullscreen() const; + bool resizing() const; + bool activated() const; + + QWaylandSurface *surface() const; + QWaylandXdgSurface *parentSurface() const; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + static QWaylandSurfaceRole *role(); + static QWaylandXdgSurface *fromResource(::wl_resource *resource); + + Q_INVOKABLE QSize sizeForResize(const QSizeF &size, const QPointF &delta, ResizeEdge edge); + Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector<uint> &states); + Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector<State> &states); + Q_INVOKABLE void sendClose(); + + Q_INVOKABLE uint requestMaximized(const QSize &size); + Q_INVOKABLE uint requestUnMaximized(const QSize &size = QSize(0, 0)); + Q_INVOKABLE uint requestFullscreen(const QSize &size); + Q_INVOKABLE uint requestResizing(const QSize &maxSize); + + QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; + +Q_SIGNALS: + void surfaceChanged(); + void titleChanged(); + void windowGeometryChanged(); + void appIdChanged(); + void parentSurfaceChanged(); + + void statesChanged(); + void maximizedChanged(); + void fullscreenChanged(); + void resizingChanged(); + void activatedChanged(); + + void showWindowMenu(QWaylandInputDevice *inputDevice, const QPoint &localSurfacePosition); + void startMove(QWaylandInputDevice *inputDevice); + void startResize(QWaylandInputDevice *inputDevice, ResizeEdge edges); + void setMaximized(); + void unsetMaximized(); + void setFullscreen(QWaylandOutput *output); + void unsetFullscreen(); + void setMinimized(); + void ackConfigure(uint serial); + +private: + void initialize() override; + QList<int> statesAsInts() const; + +private Q_SLOTS: + void handleSurfaceSizeChanged(); +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandCompositorExtensionTemplate<QWaylandXdgPopup> +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandXdgPopup) + Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) + Q_PROPERTY(QWaylandSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) + +public: + QWaylandXdgPopup(); + QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, const QWaylandResource &resource); + + Q_INVOKABLE void initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, + QWaylandSurface *parentSurface, const QWaylandResource &resource); + + QWaylandSurface *surface() const; + QWaylandSurface *parentSurface() const; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + static QWaylandSurfaceRole *role(); + static QWaylandXdgPopup *fromResource(::wl_resource *resource); + + Q_INVOKABLE void sendPopupDone(); + +Q_SIGNALS: + void surfaceChanged(); + void parentSurfaceChanged(); + +private: + void initialize() override; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDXDGSHELL_H*/ diff --git a/src/compositor/extensions/qwaylandxdgshell_p.h b/src/compositor/extensions/qwaylandxdgshell_p.h new file mode 100644 index 000000000..3165eb7ca --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshell_p.h @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXDGSHELL_P_H +#define QWAYLANDXDGSHELL_P_H + +#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h> +#include <QtWaylandCompositor/private/qwayland-server-xdg-shell.h> + +#include <QtWaylandCompositor/QWaylandXdgShell> + +#include <QtCore/QSet> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShellPrivate + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::xdg_shell +{ + Q_DECLARE_PUBLIC(QWaylandXdgShell) +public: + QWaylandXdgShellPrivate(); + void ping(Resource *resource, uint32_t serial); + void registerSurface(QWaylandXdgSurface *xdgSurface); + void unregisterXdgSurface(QWaylandXdgSurface *xdgSurface); + void registerXdgPopup(QWaylandXdgPopup *xdgPopup); + void unregisterXdgPopup(QWaylandXdgPopup *xdgPopup); + static QWaylandXdgShellPrivate *get(QWaylandXdgShell *xdgShell) { return xdgShell->d_func(); } + bool isValidPopupParent(QWaylandSurface *parentSurface) const; + QWaylandXdgPopup *topmostPopupForClient(struct wl_client* client) const; + +private: + QSet<uint32_t> m_pings; + QMultiMap<struct wl_client *, QWaylandXdgSurface *> m_xdgSurfaces; + QMultiMap<struct wl_client *, QWaylandXdgPopup *> m_xdgPopups; + + QWaylandXdgSurface *xdgSurfaceFromSurface(QWaylandSurface *surface); + + void xdg_shell_destroy(Resource *resource) Q_DECL_OVERRIDE; + void xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, + struct ::wl_resource *surface) Q_DECL_OVERRIDE; + void xdg_shell_use_unstable_version(Resource *resource, int32_t version) Q_DECL_OVERRIDE; + void xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, struct ::wl_resource *surface, + struct ::wl_resource *parent, struct ::wl_resource *seat, + uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; + void xdg_shell_pong(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurfacePrivate + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::xdg_surface +{ + Q_DECLARE_PUBLIC(QWaylandXdgSurface) +public: + QWaylandXdgSurfacePrivate(); + static QWaylandXdgSurfacePrivate *get(QWaylandXdgSurface *xdgSurface) { return xdgSurface->d_func(); } + + struct ConfigureEvent { + QVector<uint> states; + QSize size; + uint serial; + }; + + void handleFocusLost(); + void handleFocusReceived(); + +private: + QWaylandXdgShell *m_xdgShell; + QWaylandSurface *m_surface; + QWaylandXdgSurface *m_parentSurface; + + QString m_title; + QString m_appId; + QRect m_windowGeometry; + bool m_unsetWindowGeometry; + + QList<ConfigureEvent> m_pendingConfigures; + ConfigureEvent m_lastAckedConfigure; + ConfigureEvent lastSentConfigure() const { return m_pendingConfigures.empty() ? m_lastAckedConfigure : m_pendingConfigures.first(); } + + void xdg_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void xdg_surface_destroy(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_move(Resource *resource, struct ::wl_resource *seat, + uint32_t serial) Q_DECL_OVERRIDE; + void xdg_surface_resize(Resource *resource, struct ::wl_resource *seat, uint32_t serial, + uint32_t edges) Q_DECL_OVERRIDE; + void xdg_surface_set_maximized(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_unset_maximized(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_set_fullscreen(Resource *resource, + struct ::wl_resource *output) Q_DECL_OVERRIDE; + void xdg_surface_unset_fullscreen(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_set_minimized(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_set_parent(Resource *resource, struct ::wl_resource *parent) Q_DECL_OVERRIDE; + void xdg_surface_set_app_id(Resource *resource, const QString &app_id) Q_DECL_OVERRIDE; + void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seat, + uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; + void xdg_surface_ack_configure(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; + void xdg_surface_set_title(Resource *resource, const QString &title) Q_DECL_OVERRIDE; + void xdg_surface_set_window_geometry(Resource *resource, int32_t x, int32_t y, + int32_t width, int32_t height) Q_DECL_OVERRIDE; + + static QWaylandSurfaceRole s_role; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopupPrivate + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::xdg_popup +{ + Q_DECLARE_PUBLIC(QWaylandXdgPopup) + +public: + QWaylandXdgPopupPrivate(); + static QWaylandXdgPopupPrivate *get(QWaylandXdgPopup *xdgPopup) { return xdgPopup->d_func(); } + +private: + QWaylandSurface *m_surface; + QWaylandSurface *m_parentSurface; + QWaylandXdgShell *m_xdgShell; + + void xdg_popup_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void xdg_popup_destroy(xdg_popup::Resource *resource) Q_DECL_OVERRIDE; + + static QWaylandSurfaceRole s_role; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDXDGSHELL_P_H diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp new file mode 100644 index 000000000..ab10011e6 --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshellintegration.cpp @@ -0,0 +1,172 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandxdgshellintegration_p.h" + +#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem> +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandInputDevice> +#include <QMouseEvent> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +XdgShellIntegration::XdgShellIntegration(QWaylandQuickShellSurfaceItem *item) + : QWaylandQuickShellIntegration(item) + , m_item(item) + , m_xdgSurface(qobject_cast<QWaylandXdgSurface *>(item->shellSurface())) + , grabberState(GrabberState::Default) +{ + m_item->setSurface(m_xdgSurface->surface()); + connect(m_xdgSurface, &QWaylandXdgSurface::startMove, this, &XdgShellIntegration::handleStartMove); + connect(m_xdgSurface, &QWaylandXdgSurface::startResize, this, &XdgShellIntegration::handleStartResize); + connect(m_xdgSurface, &QWaylandXdgSurface::setMaximized, this, &XdgShellIntegration::handleSetMaximized); + connect(m_xdgSurface, &QWaylandXdgSurface::unsetMaximized, this, &XdgShellIntegration::handleUnsetMaximized); + connect(m_xdgSurface, &QWaylandXdgSurface::maximizedChanged, this, &XdgShellIntegration::handleMaximizedChanged); + connect(m_xdgSurface, &QWaylandXdgSurface::activatedChanged, this, &XdgShellIntegration::handleActivatedChanged); + connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgShellIntegration::handleSurfaceSizeChanged); +} + +bool XdgShellIntegration::mouseMoveEvent(QMouseEvent *event) +{ + if (grabberState == GrabberState::Resize) { + Q_ASSERT(resizeState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + if (!resizeState.initialized) { + resizeState.initialMousePos = event->windowPos(); + resizeState.initialized = true; + return true; + } + float scaleFactor = m_item->view()->output()->scaleFactor(); + QPointF delta = (event->windowPos() - resizeState.initialMousePos) / scaleFactor; + QSize newSize = m_xdgSurface->sizeForResize(resizeState.initialWindowSize, delta, resizeState.resizeEdges); + m_xdgSurface->requestResizing(newSize); + } else if (grabberState == GrabberState::Move) { + Q_ASSERT(moveState.inputDevice == m_item->compositor()->inputDeviceFor(event)); + QQuickItem *moveItem = m_item->moveItem(); + if (!moveState.initialized) { + moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos()); + moveState.initialized = true; + return true; + } + if (!moveItem->parentItem()) + return true; + QPointF parentPos = moveItem->parentItem()->mapFromItem(nullptr, event->windowPos()); + moveItem->setPosition(parentPos - moveState.initialOffset); + } + return false; +} + +bool XdgShellIntegration::mouseReleaseEvent(QMouseEvent *event) +{ + Q_UNUSED(event); + + if (grabberState == GrabberState::Resize) { + m_xdgSurface->requestUnMaximized(); + grabberState = GrabberState::Default; + return true; + } else if (grabberState == GrabberState::Move) { + grabberState = GrabberState::Default; + return true; + } + return false; +} + +void XdgShellIntegration::handleStartMove(QWaylandInputDevice *inputDevice) +{ + grabberState = GrabberState::Move; + moveState.inputDevice = inputDevice; + moveState.initialized = false; +} + +void XdgShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QWaylandXdgSurface::ResizeEdge edges) +{ + grabberState = GrabberState::Resize; + resizeState.inputDevice = inputDevice; + resizeState.resizeEdges = edges; + resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); + resizeState.initialPosition = m_item->position(); + resizeState.initialSurfaceSize = m_item->surface()->size(); + resizeState.initialized = false; +} + +void XdgShellIntegration::handleSetMaximized() +{ + maximizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); + maximizeState.initialPosition = m_item->position(); + + QWaylandOutput *output = m_item->compositor()->outputs().first(); + m_xdgSurface->requestMaximized(output->geometry().size() / output->scaleFactor()); +} + +void XdgShellIntegration::handleUnsetMaximized() +{ + m_xdgSurface->requestUnMaximized(maximizeState.initialWindowSize); +} + +void XdgShellIntegration::handleMaximizedChanged() +{ + if (m_xdgSurface->maximized()) { + QWaylandOutput *output = m_item->compositor()->outputs().first(); + m_item->setPosition(output->geometry().topLeft()); + } else { + m_item->setPosition(maximizeState.initialPosition); + } +} + +void XdgShellIntegration::handleActivatedChanged() +{ + if (m_xdgSurface->activated()) + m_item->raise(); +} + +void XdgShellIntegration::handleSurfaceSizeChanged() +{ + if (grabberState == GrabberState::Resize) { + qreal x = resizeState.initialPosition.x(); + qreal y = resizeState.initialPosition.y(); + if (resizeState.resizeEdges & QWaylandXdgSurface::ResizeEdge::TopEdge) + y += resizeState.initialSurfaceSize.height() - m_item->surface()->size().height(); + + if (resizeState.resizeEdges & QWaylandXdgSurface::ResizeEdge::LeftEdge) + x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width(); + m_item->setPosition(QPointF(x, y)); + } +} + +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshellintegration_p.h b/src/compositor/extensions/qwaylandxdgshellintegration_p.h new file mode 100644 index 000000000..df2fa8b8d --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshellintegration_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXDGSHELLINTEGRATION_H +#define QWAYLANDXDGSHELLINTEGRATION_H + +#include <QtWaylandCompositor/private/qwaylandquickshellsurfaceitem_p.h> +#include <QtWaylandCompositor/QWaylandXdgSurface> + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace QtWayland { + +class XdgShellIntegration : public QWaylandQuickShellIntegration +{ + Q_OBJECT +public: + XdgShellIntegration(QWaylandQuickShellSurfaceItem *item); + bool mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void handleStartMove(QWaylandInputDevice *inputDevice); + void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandXdgSurface::ResizeEdge edges); + void handleSetMaximized(); + void handleUnsetMaximized(); + void handleMaximizedChanged(); + void handleActivatedChanged(); + void handleSurfaceSizeChanged(); + +private: + enum class GrabberState { + Default, + Resize, + Move + }; + QWaylandQuickShellSurfaceItem *m_item; + QWaylandXdgSurface *m_xdgSurface; + + GrabberState grabberState; + struct { + QWaylandInputDevice *inputDevice; + QPointF initialOffset; + bool initialized; + } moveState; + + struct { + QWaylandInputDevice *inputDevice; + QWaylandXdgSurface::ResizeEdge resizeEdges; + QSizeF initialWindowSize; + QPointF initialMousePos; + QPointF initialPosition; + QSize initialSurfaceSize; + bool initialized; + } resizeState; + + struct { + QSize initialWindowSize; + QPointF initialPosition; + } maximizeState; +}; + +} + +QT_END_NAMESPACE + +#endif // QWAYLANDXDGSHELLINTEGRATION_H diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp b/src/compositor/extensions/qwlextendedsurface.cpp index 50cc5bb7e..fb89ebf3b 100644 --- a/src/compositor/wayland_wrapper/qwlextendedsurface.cpp +++ b/src/compositor/extensions/qwlextendedsurface.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -40,15 +36,15 @@ #include "qwlextendedsurface_p.h" -#include "qwlcompositor_p.h" -#include "qwlsurface_p.h" +#include <QtWaylandCompositor/QWaylandCompositor> QT_BEGIN_NAMESPACE namespace QtWayland { -SurfaceExtensionGlobal::SurfaceExtensionGlobal(Compositor *compositor) - : QtWaylandServer::qt_surface_extension(compositor->wl_display(), 1) +SurfaceExtensionGlobal::SurfaceExtensionGlobal(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate(compositor) + , QtWaylandServer::qt_surface_extension(compositor->display(), 1) { } @@ -56,24 +52,21 @@ void SurfaceExtensionGlobal::surface_extension_get_extended_surface(Resource *re uint32_t id, struct wl_resource *surface_resource) { - Surface *surface = Surface::fromResource(surface_resource); - new ExtendedSurface(resource->client(),id, wl_resource_get_version(resource->handle), surface); + QWaylandSurface *surface = QWaylandSurface::fromResource(surface_resource); + ExtendedSurface *extSurface = new ExtendedSurface(resource->client(),id, wl_resource_get_version(resource->handle), surface); + emit extendedSurfaceReady(extSurface, surface); } -ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, int version, Surface *surface) - : QWaylandSurfaceInterface(surface->waylandSurface()) +ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, int version, QWaylandSurface *surface) + : QWaylandCompositorExtensionTemplate(surface) , QtWaylandServer::qt_extended_surface(client, id, version) , m_surface(surface) , m_windowFlags(0) { - Q_ASSERT(surface->extendedSurface() == 0); - surface->setExtendedSurface(this); } ExtendedSurface::~ExtendedSurface() { - if (m_surface) - m_surface->setExtendedSurface(0); } void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &variant) @@ -85,30 +78,19 @@ void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &v } -void ExtendedSurface::setVisibility(QWindow::Visibility visibility) +void ExtendedSurface::sendOnScreenVisibilityChange(bool onScreen) { - // If this change came from the client, we shouldn't update it - send_onscreen_visibility(visibility); + setVisibility(onScreen ? QWindow::AutomaticVisibility : QWindow::Hidden); } -void ExtendedSurface::setParentSurface(Surface *surface) +void ExtendedSurface::setVisibility(QWindow::Visibility visibility) { - m_surface = surface; + send_onscreen_visibility(visibility); } -bool ExtendedSurface::runOperation(QWaylandSurfaceOp *op) +void ExtendedSurface::setParentSurface(QWaylandSurface *surface) { - switch (op->type()) { - case QWaylandSurfaceOp::Close: - send_close(); - return true; - case QWaylandSurfaceOp::SetVisibility: - setVisibility(static_cast<QWaylandSurfaceSetVisibilityOp *>(op)->visibility()); - return true; - default: - break; - } - return false; + m_surface = surface; } void ExtendedSurface::extended_surface_update_generic_property(Resource *resource, @@ -120,7 +102,7 @@ void ExtendedSurface::extended_surface_update_generic_property(Resource *resourc QByteArray byteValue((const char*)value->data, value->size); QDataStream ds(&byteValue, QIODevice::ReadOnly); ds >> variantValue; - setWindowProperty(name,variantValue,false); + setWindowPropertyImpl(name,variantValue); } Qt::ScreenOrientations ExtendedSurface::contentOrientationMask() const @@ -146,8 +128,8 @@ void ExtendedSurface::extended_surface_set_content_orientation_mask(Resource *re Qt::ScreenOrientations oldMask = m_contentOrientationMask; m_contentOrientationMask = mask; - if (m_surface && mask != oldMask) - emit m_surface->waylandSurface()->orientationUpdateMaskChanged(); + if (mask != oldMask) + emit contentOrientationMaskChanged(); } QVariantMap ExtendedSurface::windowProperties() const @@ -161,22 +143,26 @@ QVariant ExtendedSurface::windowProperty(const QString &propertyName) const return props.value(propertyName); } -void ExtendedSurface::setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient) +void ExtendedSurface::setWindowProperty(const QString &name, const QVariant &value) +{ + setWindowPropertyImpl(name,value); + sendGenericProperty(name, value); +} + +void ExtendedSurface::setWindowPropertyImpl(const QString &name, const QVariant &value) { m_windowProperties.insert(name, value); - m_surface->waylandSurface()->windowPropertyChanged(name,value); - if (writeUpdateToClient) - sendGenericProperty(name, value); + emit windowPropertyChanged(name,value); } void ExtendedSurface::extended_surface_set_window_flags(Resource *resource, int32_t flags) { Q_UNUSED(resource); - QWaylandSurface::WindowFlags windowFlags(flags); - if (!m_surface || windowFlags == m_windowFlags) + WindowFlags windowFlags(flags); + if (windowFlags == m_windowFlags) return; m_windowFlags = windowFlags; - emit m_surface->waylandSurface()->windowFlagsChanged(windowFlags); + emit windowFlagsChanged(); } void ExtendedSurface::extended_surface_destroy_resource(Resource *) @@ -186,14 +172,12 @@ void ExtendedSurface::extended_surface_destroy_resource(Resource *) void ExtendedSurface::extended_surface_raise(Resource *) { - if (m_surface) - emit m_surface->waylandSurface()->raiseRequested(); + emit raiseRequested(); } void ExtendedSurface::extended_surface_lower(Resource *) { - if (m_surface) - emit m_surface->waylandSurface()->lowerRequested(); + emit lowerRequested(); } } diff --git a/src/compositor/extensions/qwlextendedsurface_p.h b/src/compositor/extensions/qwlextendedsurface_p.h new file mode 100644 index 000000000..a868cd831 --- /dev/null +++ b/src/compositor/extensions/qwlextendedsurface_p.h @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WLEXTENDEDSURFACE_H +#define WLEXTENDEDSURFACE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <wayland-server.h> + +#include <QtWaylandCompositor/private/qwayland-server-surface-extension.h> +#include <QtWaylandCompositor/qwaylandsurface.h> +#include <QtWaylandCompositor/qwaylandcompositorextension.h> + +#include <QtCore/QVariant> +#include <QtCore/QLinkedList> +#include <QtGui/QWindow> + +QT_BEGIN_NAMESPACE + +class QWaylandCompositor; +class QWaylandSurface; + +namespace QtWayland { + +class ExtendedSurface; + +class Q_WAYLAND_COMPOSITOR_EXPORT SurfaceExtensionGlobal : public QWaylandCompositorExtensionTemplate<SurfaceExtensionGlobal>, public QtWaylandServer::qt_surface_extension +{ + Q_OBJECT +public: + SurfaceExtensionGlobal(QWaylandCompositor *compositor); + +Q_SIGNALS: + void extendedSurfaceReady(ExtendedSurface *extSurface, QWaylandSurface *surface); + +private: + void surface_extension_get_extended_surface(Resource *resource, + uint32_t id, + struct wl_resource *surface); + +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT ExtendedSurface : public QWaylandCompositorExtensionTemplate<ExtendedSurface>, public QtWaylandServer::qt_extended_surface +{ + Q_OBJECT + Q_PROPERTY(Qt::ScreenOrientations contentOrientationMask READ contentOrientationMask NOTIFY contentOrientationMaskChanged) + Q_PROPERTY(WindowFlags windowFlags READ windowFlags NOTIFY windowFlagsChanged) + Q_FLAGS(WindowFlag WindowFlags) +public: + enum WindowFlag { + OverridesSystemGestures = 0x0001, + StaysOnTop = 0x0002, + BypassWindowManager = 0x0004 + }; + Q_DECLARE_FLAGS(WindowFlags, WindowFlag) + + ExtendedSurface(struct wl_client *client, uint32_t id, int version, QWaylandSurface *surface); + ~ExtendedSurface(); + + void sendGenericProperty(const QString &name, const QVariant &variant); + + void sendOnScreenVisibilityChange(bool onScreen); + void setVisibility(QWindow::Visibility visibility); + + void setParentSurface(QWaylandSurface *s); + + Qt::ScreenOrientations contentOrientationMask() const; + + WindowFlags windowFlags() const { return m_windowFlags; } + + QVariantMap windowProperties() const; + QVariant windowProperty(const QString &propertyName) const; + void setWindowProperty(const QString &name, const QVariant &value); + +Q_SIGNALS: + void contentOrientationMaskChanged(); + void windowFlagsChanged(); + void windowPropertyChanged(const QString &name, const QVariant &value); + void raiseRequested(); + void lowerRequested(); + +private: + void setWindowPropertyImpl(const QString &name, const QVariant &value); + + QWaylandSurface *m_surface; + + Qt::ScreenOrientations m_contentOrientationMask; + + WindowFlags m_windowFlags; + + QByteArray m_authenticationToken; + QVariantMap m_windowProperties; + + void extended_surface_update_generic_property(Resource *resource, + const QString &name, + struct wl_array *value) Q_DECL_OVERRIDE; + + void extended_surface_set_content_orientation_mask(Resource *resource, + int32_t orientation) Q_DECL_OVERRIDE; + + void extended_surface_set_window_flags(Resource *resource, + int32_t flags) Q_DECL_OVERRIDE; + + void extended_surface_destroy_resource(Resource *) Q_DECL_OVERRIDE; + void extended_surface_raise(Resource *) Q_DECL_OVERRIDE; + void extended_surface_lower(Resource *) Q_DECL_OVERRIDE; +}; + +} + +QT_END_NAMESPACE + +#endif // WLEXTENDEDSURFACE_H diff --git a/src/compositor/extensions/qwlqtkey.cpp b/src/compositor/extensions/qwlqtkey.cpp new file mode 100644 index 000000000..da8c19d75 --- /dev/null +++ b/src/compositor/extensions/qwlqtkey.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwlqtkey_p.h" +#include <QtWaylandCompositor/QWaylandSurface> +#include <QKeyEvent> +#include <QWindow> + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +QtKeyExtensionGlobal::QtKeyExtensionGlobal(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate(compositor) + , QtWaylandServer::qt_key_extension(compositor->display(), 2) + , m_compositor(compositor) +{ +} + +bool QtKeyExtensionGlobal::postQtKeyEvent(QKeyEvent *event, QWaylandSurface *surface) +{ + uint32_t time = m_compositor->currentTimeMsecs(); + + Resource *target = surface ? resourceMap().value(surface->waylandClient()) : 0; + + if (target) { + send_qtkey(target->handle, + surface ? surface->resource() : 0, + time, event->type(), event->key(), event->modifiers(), + event->nativeScanCode(), + event->nativeVirtualKey(), + event->nativeModifiers(), + event->text(), + event->isAutoRepeat(), + event->count()); + + return true; + } + + return false; +} + +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwlqtkey_p.h b/src/compositor/extensions/qwlqtkey_p.h new file mode 100644 index 000000000..1b9c7391e --- /dev/null +++ b/src/compositor/extensions/qwlqtkey_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WLQTKEY_H +#define WLQTKEY_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "wayland-util.h" + +#include <QtWaylandCompositor/QWaylandCompositorExtensionTemplate> +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/private/qwayland-server-qtkey-extension.h> + +QT_BEGIN_NAMESPACE + +class QWaylandSurface; +class QKeyEvent; + +namespace QtWayland { + +class QtKeyExtensionGlobal : public QWaylandCompositorExtensionTemplate<QtKeyExtensionGlobal>, public QtWaylandServer::qt_key_extension +{ + Q_OBJECT +public: + QtKeyExtensionGlobal(QWaylandCompositor *compositor); + + bool postQtKeyEvent(QKeyEvent *event, QWaylandSurface *surface); + +private: + QWaylandCompositor *m_compositor; +}; + +} + +QT_END_NAMESPACE + +#endif // WLQTKEY_H diff --git a/src/compositor/wayland_wrapper/qwlqttouch.cpp b/src/compositor/extensions/qwlqttouch.cpp index 9d4dfdcdd..17246b397 100644 --- a/src/compositor/wayland_wrapper/qwlqttouch.cpp +++ b/src/compositor/extensions/qwlqttouch.cpp @@ -3,44 +3,39 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qwlqttouch_p.h" -#include "qwlsurface_p.h" -#include "qwaylandsurfaceview.h" +#include "qwaylandview.h" #include <QTouchEvent> #include <QWindow> @@ -50,8 +45,9 @@ namespace QtWayland { static const int maxRawPos = 24; -TouchExtensionGlobal::TouchExtensionGlobal(Compositor *compositor) - : QtWaylandServer::qt_touch_extension(compositor->wl_display(), 1) +TouchExtensionGlobal::TouchExtensionGlobal(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate(compositor) + , QtWaylandServer::qt_touch_extension(compositor->display(), 1) , m_compositor(compositor) , m_flags(0) , m_resources() @@ -68,15 +64,14 @@ static inline int toFixed(qreal f) return int(f * 10000); } -bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandSurfaceView *view) +bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandView *view) { const QList<QTouchEvent::TouchPoint> points = event->touchPoints(); const int pointCount = points.count(); if (!pointCount) return false; - QPointF surfacePos = view->pos(); - wl_client *surfaceClient = view->surface()->handle()->resource()->client(); + wl_client *surfaceClient = view->surface()->client()->client(); uint32_t time = m_compositor->currentTimeMsecs(); const int rescount = m_resources.count(); @@ -104,9 +99,8 @@ bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandSurfaceVie uint32_t state = (tp.state() & 0xFFFF) | (sentPointCount << 16); uint32_t flags = (tp.flags() & 0xFFFF) | (int(event->device()->capabilities()) << 16); - QPointF p = tp.pos() - surfacePos; // surface-relative - int x = toFixed(p.x()); - int y = toFixed(p.y()); + int x = toFixed(tp.pos().x()); + int y = toFixed(tp.pos().y()); int nx = toFixed(tp.normalizedPos().x()); int ny = toFixed(tp.normalizedPos().y()); int w = toFixed(tp.rect().width()); @@ -145,6 +139,15 @@ bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandSurfaceVie return false; } +void TouchExtensionGlobal::setBehviorFlags(BehaviorFlags flags) +{ + if (m_flags == flags) + return; + + m_flags = flags; + behaviorFlagsChanged(); +} + void TouchExtensionGlobal::touch_extension_bind_resource(Resource *resource) { m_resources.append(resource); diff --git a/src/compositor/extensions/qwlqttouch_p.h b/src/compositor/extensions/qwlqttouch_p.h new file mode 100644 index 000000000..32d7658f0 --- /dev/null +++ b/src/compositor/extensions/qwlqttouch_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WLTOUCH_H +#define WLTOUCH_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtWaylandCompositor/private/qwayland-server-touch-extension.h> +#include <QtWaylandCompositor/QWaylandCompositor> +#include <QtWaylandCompositor/QWaylandCompositorExtensionTemplate> +#include "wayland-util.h" + +QT_BEGIN_NAMESPACE + +class Surface; +class QTouchEvent; +class QWaylandView; + +namespace QtWayland { + +class TouchExtensionGlobal : public QWaylandCompositorExtensionTemplate<TouchExtensionGlobal>, public QtWaylandServer::qt_touch_extension +{ + Q_OBJECT + Q_PROPERTY(BehaviorFlags behaviorFlags READ behaviorFlags WRITE setBehviorFlags NOTIFY behaviorFlagsChanged) +public: + + enum BehaviorFlag{ + None = 0x00, + MouseFromTouch = 0x01 + }; + Q_DECLARE_FLAGS(BehaviorFlags, BehaviorFlag) + + TouchExtensionGlobal(QWaylandCompositor *compositor); + ~TouchExtensionGlobal(); + + bool postTouchEvent(QTouchEvent *event, QWaylandView *view); + + void setBehviorFlags(BehaviorFlags flags); + BehaviorFlags behaviorFlags() const { return m_flags; } + +Q_SIGNALS: + void behaviorFlagsChanged(); + +protected: + void touch_extension_bind_resource(Resource *resource) Q_DECL_OVERRIDE; + void touch_extension_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + +private: + QWaylandCompositor *m_compositor; + BehaviorFlags m_flags; + QList<Resource *> m_resources; + QVector<float> m_posData; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(TouchExtensionGlobal::BehaviorFlags) + +} + +QT_END_NAMESPACE + +#endif // WLTOUCH_H diff --git a/src/compositor/global/global.pri b/src/compositor/global/global.pri index fdb2049cd..e48b8a8c2 100644 --- a/src/compositor/global/global.pri +++ b/src/compositor/global/global.pri @@ -1,5 +1,11 @@ INCLUDEPATH += global/ HEADERS += \ - global/qwaylandexport.h + global/qwaylandexport.h \ + global/qwaylandcompositorextension.h \ + global/qwaylandcompositorextension_p.h \ + global/qwaylandquickextension.h \ + +SOURCES += \ + global/qwaylandcompositorextension.cpp diff --git a/src/compositor/global/qwaylandcompositorextension.cpp b/src/compositor/global/qwaylandcompositorextension.cpp new file mode 100644 index 000000000..ddfd25837 --- /dev/null +++ b/src/compositor/global/qwaylandcompositorextension.cpp @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qwaylandcompositorextension.h" +#include "qwaylandcompositorextension_p.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/QDebug> + +#include <wayland-server.h> + +QT_BEGIN_NAMESPACE + +QWaylandCompositorExtension::QWaylandCompositorExtension() + : QWaylandObject(*new QWaylandCompositorExtensionPrivate()) +{ +} + +QWaylandCompositorExtension::QWaylandCompositorExtension(QWaylandObject *container) + : QWaylandObject(*new QWaylandCompositorExtensionPrivate()) +{ + d_func()->extension_container = container; + QCoreApplication::postEvent(this, new QEvent(QEvent::Polish)); +} + +QWaylandCompositorExtension::QWaylandCompositorExtension(QWaylandCompositorExtensionPrivate &dd) + : QWaylandObject(dd) +{ +} + +QWaylandCompositorExtension::QWaylandCompositorExtension(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd) + : QWaylandObject(dd) +{ + d_func()->extension_container = container; + QCoreApplication::postEvent(this, new QEvent(QEvent::Polish)); +} + +QWaylandCompositorExtension::~QWaylandCompositorExtension() +{ + Q_D(QWaylandCompositorExtension); + if (d->extension_container) + d->extension_container->removeExtension(this); +} + +QWaylandObject *QWaylandCompositorExtension::extensionContainer() const +{ + Q_D(const QWaylandCompositorExtension); + return d->extension_container; +} + +void QWaylandCompositorExtension::setExtensionContainer(QWaylandObject *container) +{ + Q_D(QWaylandCompositorExtension); + d->extension_container = container; +} + +void QWaylandCompositorExtension::initialize() +{ + Q_D(QWaylandCompositorExtension); + if (d->initialized) { + qWarning() << "QWaylandCompositorExtension:" << extensionInterface()->name << "is already initialized"; + return; + } + + if (!d->extension_container) { + qWarning() << "QWaylandCompositorExtension:" << extensionInterface()->name << "requests to initialize with no extension container set"; + return; + } + + d->extension_container->addExtension(this); + d->initialized = true; +} + +bool QWaylandCompositorExtension::isInitialized() const +{ + Q_D(const QWaylandCompositorExtension); + return d->initialized; +} + +bool QWaylandCompositorExtension::event(QEvent *event) +{ + switch(event->type()) { + case QEvent::Polish: + initialize(); + break; + default: + break; + } + return QWaylandObject::event(event); +} + +QWaylandObject::QWaylandObject(QObject *parent) + :QObject(parent) +{ +} + +QWaylandObject::QWaylandObject(QObjectPrivate &d, QObject *parent) + :QObject(d, parent) +{ +} + + +QWaylandObject::~QWaylandObject() +{ + foreach (QWaylandCompositorExtension *extension, extension_vector) + QWaylandCompositorExtensionPrivate::get(extension)->extension_container = Q_NULLPTR; +} + +QWaylandCompositorExtension *QWaylandObject::extension(const QByteArray &name) +{ + for (int i = 0; i < extension_vector.size(); i++) { + if (extension_vector.at(i)->extensionInterface()->name == name) + return extension_vector.at(i); + } + return Q_NULLPTR; +} + +QWaylandCompositorExtension *QWaylandObject::extension(const wl_interface *interface) +{ + for (int i = 0; i < extension_vector.size(); i++) { + if (extension_vector.at(i)->extensionInterface() == interface) + return extension_vector.at(i); + } + return Q_NULLPTR; +} + +QList<QWaylandCompositorExtension *> QWaylandObject::extensions() const +{ + return extension_vector; +} + +void QWaylandObject::addExtension(QWaylandCompositorExtension *extension) +{ + Q_ASSERT(!extension_vector.contains(extension)); + extension_vector.append(extension); +} + +void QWaylandObject::removeExtension(QWaylandCompositorExtension *extension) +{ + Q_ASSERT(extension_vector.contains(extension)); + extension_vector.removeOne(extension); +} + +QT_END_NAMESPACE diff --git a/src/compositor/global/qwaylandcompositorextension.h b/src/compositor/global/qwaylandcompositorextension.h new file mode 100644 index 000000000..0ba54c882 --- /dev/null +++ b/src/compositor/global/qwaylandcompositorextension.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDEXTENSION_H +#define QWAYLANDEXTENSION_H + +#include <QtWaylandCompositor/qwaylandexport.h> + +#include <QtCore/QObject> +#include <QtCore/QVector> + +struct wl_interface; + +QT_BEGIN_NAMESPACE + +class QWaylandCompositor; +class QWaylandCompositorExtension; +class QWaylandCompositorExtensionPrivate; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandObject : public QObject +{ +public: + virtual ~QWaylandObject(); + + QWaylandCompositorExtension *extension(const QByteArray &name); + QWaylandCompositorExtension *extension(const wl_interface *interface); + QList<QWaylandCompositorExtension *> extensions() const; + void addExtension(QWaylandCompositorExtension *extension); + void removeExtension(QWaylandCompositorExtension *extension); + +protected: + QWaylandObject(QObject *parent = nullptr); + QWaylandObject(QObjectPrivate &d, QObject *parent = nullptr); + QList<QWaylandCompositorExtension *> extension_vector; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositorExtension : public QWaylandObject +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandCompositorExtension) +public: + QWaylandCompositorExtension(); + QWaylandCompositorExtension(QWaylandObject *container); + virtual ~QWaylandCompositorExtension(); + + QWaylandObject *extensionContainer() const; + void setExtensionContainer(QWaylandObject *container); + + virtual void initialize(); + bool isInitialized() const; + + virtual const struct wl_interface *extensionInterface() const = 0; + +protected: + QWaylandCompositorExtension(QWaylandCompositorExtensionPrivate &dd); + QWaylandCompositorExtension(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd); + + bool event(QEvent *event) Q_DECL_OVERRIDE; +}; + +template <typename T> +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositorExtensionTemplate : public QWaylandCompositorExtension +{ +public: + QWaylandCompositorExtensionTemplate() + : QWaylandCompositorExtension() + { } + + QWaylandCompositorExtensionTemplate(QWaylandObject *container) + : QWaylandCompositorExtension(container) + { } + + const struct wl_interface *extensionInterface() const Q_DECL_OVERRIDE + { + return T::interface(); + } + + static T *findIn(QWaylandObject *container) + { + if (!container) return Q_NULLPTR; + return qobject_cast<T *>(container->extension(T::interfaceName())); + } + +protected: + QWaylandCompositorExtensionTemplate(QWaylandCompositorExtensionPrivate &dd) + : QWaylandCompositorExtension(dd) + { } + + QWaylandCompositorExtensionTemplate(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd) + : QWaylandCompositorExtension(container,dd) + { } +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/compositor/global/qwaylandcompositorextension_p.h b/src/compositor/global/qwaylandcompositorextension_p.h new file mode 100644 index 000000000..a9a670d66 --- /dev/null +++ b/src/compositor/global/qwaylandcompositorextension_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDEXTENSION_P_H +#define QWAYLANDEXTENSION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qwaylandcompositorextension.h" +#include <QtCore/private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositorExtensionPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QWaylandCompositorExtension) + +public: + QWaylandCompositorExtensionPrivate() + : QObjectPrivate() + , extension_container(Q_NULLPTR) + , initialized(false) + { + } + + static QWaylandCompositorExtensionPrivate *get(QWaylandCompositorExtension *extension) { return extension->d_func(); } + + QWaylandObject *extension_container; + bool initialized; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDEXTENSION_P_H*/ diff --git a/src/compositor/global/qwaylandexport.h b/src/compositor/global/qwaylandexport.h index 579794afa..ddfa6aa77 100644 --- a/src/compositor/global/qwaylandexport.h +++ b/src/compositor/global/qwaylandexport.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -45,13 +41,13 @@ QT_BEGIN_NAMESPACE -#if !defined(Q_COMPOSITOR_EXPORT) +#if !defined(Q_WAYLAND_COMPOSITOR_EXPORT) # if defined(QT_SHARED) && defined(QT_BUILD_COMPOSITOR_LIB) -# define Q_COMPOSITOR_EXPORT Q_DECL_EXPORT +# define Q_WAYLAND_COMPOSITOR_EXPORT Q_DECL_EXPORT # elif defined(QT_SHARED) -# define Q_COMPOSITOR_EXPORT Q_DECL_IMPORT +# define Q_WAYLAND_COMPOSITOR_EXPORT Q_DECL_IMPORT # else -# define Q_COMPOSITOR_EXPORT +# define Q_WAYLAND_COMPOSITOR_EXPORT # endif #endif diff --git a/src/compositor/global/qwaylandquickextension.h b/src/compositor/global/qwaylandquickextension.h new file mode 100644 index 000000000..32f4e6527 --- /dev/null +++ b/src/compositor/global/qwaylandquickextension.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDQUICKEXTENSION_H +#define QWAYLANDQUICKEXTENSION_H + +#include <QtWaylandCompositor/QWaylandCompositorExtension> +#include <QtQml/QQmlParserStatus> +#include <QtQml/QQmlListProperty> + +QT_BEGIN_NAMESPACE + +#define Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(className) \ + class Q_WAYLAND_COMPOSITOR_EXPORT className##QuickExtension : public className, public QQmlParserStatus \ + { \ +/* qmake ignore Q_OBJECT */ \ + Q_OBJECT \ + Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) \ + Q_CLASSINFO("DefaultProperty", "data") \ + public: \ + QQmlListProperty<QObject> data() \ + { \ + return QQmlListProperty<QObject>(this, m_objects); \ + } \ + void classBegin() Q_DECL_OVERRIDE {} \ + void componentComplete() Q_DECL_OVERRIDE { initialize(); } \ + private: \ + QList<QObject *> m_objects; \ + }; + +#define Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CONTAINER_CLASS(className) \ + class Q_WAYLAND_COMPOSITOR_EXPORT className##QuickExtensionContainer : public className \ + { \ +/* qmake ignore Q_OBJECT */ \ + Q_OBJECT \ + Q_PROPERTY(QQmlListProperty<QWaylandCompositorExtension> extensions READ extensions) \ + Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) \ + Q_CLASSINFO("DefaultProperty", "data") \ + public: \ + QQmlListProperty<QObject> data() \ + { \ + return QQmlListProperty<QObject>(this, m_objects); \ + } \ + QQmlListProperty<QWaylandCompositorExtension> extensions() \ + { \ + return QQmlListProperty<QWaylandCompositorExtension>(this, this, \ + &className##QuickExtensionContainer::append_extension, \ + &className##QuickExtensionContainer::countFunction, \ + &className##QuickExtensionContainer::atFunction, \ + &className##QuickExtensionContainer::clearFunction); \ + } \ + static int countFunction(QQmlListProperty<QWaylandCompositorExtension> *list) \ + { \ + return static_cast<className##QuickExtensionContainer *>(list->data)->extension_vector.size(); \ + } \ + static QWaylandCompositorExtension *atFunction(QQmlListProperty<QWaylandCompositorExtension> *list, int index) \ + { \ + return static_cast<className##QuickExtensionContainer *>(list->data)->extension_vector.at(index); \ + } \ + static void append_extension(QQmlListProperty<QWaylandCompositorExtension> *list, QWaylandCompositorExtension *extension) \ + { \ + className##QuickExtensionContainer *quickExtObj = static_cast<className##QuickExtensionContainer *>(list->data); \ + extension->setExtensionContainer(quickExtObj); \ + } \ + static void clearFunction(QQmlListProperty<QWaylandCompositorExtension> *list) \ + { \ + static_cast<className##QuickExtensionContainer *>(list->data)->extension_vector.clear(); \ + } \ + private: \ + QList<QObject *> m_objects; \ + }; + +QT_END_NAMESPACE + +#endif /*QWAYLANDQUICKEXTENSION_H*/ diff --git a/src/compositor/hardware_integration/hardware_integration.pri b/src/compositor/hardware_integration/hardware_integration.pri index 39843b3f5..2737a6f07 100644 --- a/src/compositor/hardware_integration/hardware_integration.pri +++ b/src/compositor/hardware_integration/hardware_integration.pri @@ -4,7 +4,7 @@ isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) CONFIG += wayland-scanner WAYLANDSERVERSOURCES += \ ../extensions/server-buffer-extension.xml \ - ../extensions/hardware-integration.xml + ../extensions/hardware-integration.xml \ HEADERS += \ hardware_integration/qwlclientbufferintegration_p.h \ @@ -13,7 +13,7 @@ isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) hardware_integration/qwlserverbufferintegration_p.h \ hardware_integration/qwlserverbufferintegrationfactory_p.h \ hardware_integration/qwlserverbufferintegrationplugin_p.h \ - hardware_integration/qwlhwintegration_p.h + hardware_integration/qwlhwintegration_p.h \ SOURCES += \ hardware_integration/qwlclientbufferintegration.cpp \ @@ -22,7 +22,7 @@ isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG) hardware_integration/qwlserverbufferintegration.cpp \ hardware_integration/qwlserverbufferintegrationfactory.cpp \ hardware_integration/qwlserverbufferintegrationplugin.cpp \ - hardware_integration/qwlhwintegration.cpp + hardware_integration/qwlhwintegration.cpp \ DEFINES += QT_COMPOSITOR_WAYLAND_GL } else { diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration.cpp b/src/compositor/hardware_integration/qwlclientbufferintegration.cpp index 36591a9dd..ef0f98d1f 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegration.cpp +++ b/src/compositor/hardware_integration/qwlclientbufferintegration.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h index c19b90309..90762437b 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h +++ b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -52,10 +48,10 @@ // We mean it. // -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandsurface.h> +#include <QtWaylandCompositor/qwaylandbufferref.h> #include <QtCore/QSize> -#include <QtGui/qopengl.h> -#include <QtGui/QOpenGLContext> #include <wayland-server.h> QT_BEGIN_NAMESPACE @@ -65,7 +61,7 @@ class QWaylandCompositor; namespace QtWayland { class Display; -class Q_COMPOSITOR_EXPORT ClientBufferIntegration +class Q_WAYLAND_COMPOSITOR_EXPORT ClientBufferIntegration { public: ClientBufferIntegration(); @@ -73,32 +69,16 @@ public: void setCompositor(QWaylandCompositor *compositor) { m_compositor = compositor; } - virtual void initializeHardware(QtWayland::Display *waylandDisplay) = 0; - - virtual void initialize(struct ::wl_resource *buffer) { Q_UNUSED(buffer); } - - virtual GLenum textureTargetForBuffer(struct ::wl_resource *buffer) const { Q_UNUSED(buffer); return GL_TEXTURE_2D; } + virtual void initializeHardware(struct ::wl_display *display) = 0; - virtual GLuint textureForBuffer(struct ::wl_resource *buffer) { - Q_UNUSED(buffer); - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - return texture; - } + virtual void initializeBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); } + virtual QWaylandBufferRef::BufferFormatEgl bufferFormat(struct ::wl_resource *buffer) { Q_UNUSED(buffer); return QWaylandBufferRef::BufferFormatEgl_RGBA; } + virtual uint textureForBuffer(struct ::wl_resource *buffer, int plane) { Q_UNUSED(buffer); Q_UNUSED(plane); return 0; } - virtual void destroyTextureForBuffer(struct ::wl_resource *buffer, GLuint texture) - { - Q_UNUSED(buffer); - glDeleteTextures(1, &texture); - } - - // Called with the texture bound. virtual void bindTextureToBuffer(struct ::wl_resource *buffer) = 0; - virtual void updateTextureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); } - virtual bool isYInverted(struct ::wl_resource *) const { return true; } + virtual QWaylandSurface::Origin origin(struct ::wl_resource *) const { return QWaylandSurface::OriginBottomLeft; } virtual void *lockNativeBuffer(struct ::wl_resource *) const { return 0; } virtual void unlockNativeBuffer(void *) const { return; } diff --git a/src/compositor/hardware_integration/qwlclientbufferintegrationfactory.cpp b/src/compositor/hardware_integration/qwlclientbufferintegrationfactory.cpp index f56b2ec23..36ac56cf2 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegrationfactory.cpp +++ b/src/compositor/hardware_integration/qwlclientbufferintegrationfactory.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/compositor/hardware_integration/qwlclientbufferintegrationfactory_p.h b/src/compositor/hardware_integration/qwlclientbufferintegrationfactory_p.h index 0d064db26..3c1d856c7 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegrationfactory_p.h +++ b/src/compositor/hardware_integration/qwlclientbufferintegrationfactory_p.h @@ -3,9 +3,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -45,7 +48,7 @@ // We mean it. // -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> #include <QtCore/QStringList> QT_BEGIN_NAMESPACE @@ -54,7 +57,7 @@ namespace QtWayland { class ClientBufferIntegration; -class Q_COMPOSITOR_EXPORT ClientBufferIntegrationFactory +class Q_WAYLAND_COMPOSITOR_EXPORT ClientBufferIntegrationFactory { public: static QStringList keys(const QString &pluginPath = QString()); diff --git a/src/compositor/hardware_integration/qwlclientbufferintegrationplugin.cpp b/src/compositor/hardware_integration/qwlclientbufferintegrationplugin.cpp index db22d8085..8885f288a 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegrationplugin.cpp +++ b/src/compositor/hardware_integration/qwlclientbufferintegrationplugin.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/compositor/hardware_integration/qwlclientbufferintegrationplugin_p.h b/src/compositor/hardware_integration/qwlclientbufferintegrationplugin_p.h index 2b3604480..d8bc33fbe 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegrationplugin_p.h +++ b/src/compositor/hardware_integration/qwlclientbufferintegrationplugin_p.h @@ -3,9 +3,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -45,7 +48,7 @@ // We mean it. // -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> #include <QtCore/qplugin.h> #include <QtCore/qfactoryinterface.h> @@ -56,9 +59,9 @@ namespace QtWayland { class ClientBufferIntegration; -#define QtWaylandClientBufferIntegrationFactoryInterface_iid "org.qt-project.Qt.Compositor.QtWaylandClientBufferIntegrationFactoryInterface.5.3" +#define QtWaylandClientBufferIntegrationFactoryInterface_iid "org.qt-project.Qt.WaylandCompositor.QtWaylandClientBufferIntegrationFactoryInterface.5.3" -class Q_COMPOSITOR_EXPORT ClientBufferIntegrationPlugin : public QObject +class Q_WAYLAND_COMPOSITOR_EXPORT ClientBufferIntegrationPlugin : public QObject { Q_OBJECT public: diff --git a/src/compositor/hardware_integration/qwlhwintegration.cpp b/src/compositor/hardware_integration/qwlhwintegration.cpp index d02e72371..7fb2c8b58 100644 --- a/src/compositor/hardware_integration/qwlhwintegration.cpp +++ b/src/compositor/hardware_integration/qwlhwintegration.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -40,16 +36,18 @@ #include "qwlhwintegration_p.h" -#include "qwlcompositor_p.h" +#include <QtWaylandCompositor/QWaylandCompositor> QT_BEGIN_NAMESPACE namespace QtWayland { -HardwareIntegration::HardwareIntegration(Compositor *compositor) - : qt_hardware_integration(compositor->wl_display(), 1) +HardwareIntegration::HardwareIntegration(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate<HardwareIntegration>(compositor) + , qt_hardware_integration(compositor->display(), 1) { } + void HardwareIntegration::setClientBufferIntegration(const QString &name) { m_client_buffer_integration = name; diff --git a/src/compositor/hardware_integration/qwlhwintegration_p.h b/src/compositor/hardware_integration/qwlhwintegration_p.h index ed5c56ba1..2cd368bc2 100644 --- a/src/compositor/hardware_integration/qwlhwintegration_p.h +++ b/src/compositor/hardware_integration/qwlhwintegration_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -52,20 +48,22 @@ // We mean it. // -#include <QtCompositor/private/qwayland-server-hardware-integration.h> +#include <QtWaylandCompositor/private/qwayland-server-hardware-integration.h> + +#include <QtWaylandCompositor/QWaylandCompositorExtension> #include <QtCore/QString> QT_BEGIN_NAMESPACE -namespace QtWayland { +class QWaylandCompositor; -class Compositor; +namespace QtWayland { -class HardwareIntegration : public QtWaylandServer::qt_hardware_integration +class HardwareIntegration : public QWaylandCompositorExtensionTemplate<HardwareIntegration>, public QtWaylandServer::qt_hardware_integration { public: - HardwareIntegration(Compositor *compositor); + HardwareIntegration(QWaylandCompositor *compositor); void setClientBufferIntegration(const QString &name); void setServerBufferIntegration(const QString &name); diff --git a/src/compositor/hardware_integration/qwlserverbufferintegration.cpp b/src/compositor/hardware_integration/qwlserverbufferintegration.cpp index 2d99dc850..f10fb9916 100644 --- a/src/compositor/hardware_integration/qwlserverbufferintegration.cpp +++ b/src/compositor/hardware_integration/qwlserverbufferintegration.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/compositor/hardware_integration/qwlserverbufferintegration_p.h b/src/compositor/hardware_integration/qwlserverbufferintegration_p.h index 0eef5d1f0..3a71f18f7 100644 --- a/src/compositor/hardware_integration/qwlserverbufferintegration_p.h +++ b/src/compositor/hardware_integration/qwlserverbufferintegration_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -56,7 +52,7 @@ #include <QtCore/QSize> #include <QtGui/qopengl.h> -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> struct wl_client; struct wl_resource; @@ -69,7 +65,7 @@ class QOpenGLContext; namespace QtWayland { class Display; -class Q_COMPOSITOR_EXPORT ServerBuffer +class Q_WAYLAND_COMPOSITOR_EXPORT ServerBuffer { public: enum Format { @@ -93,7 +89,7 @@ protected: Format m_format; }; -class Q_COMPOSITOR_EXPORT ServerBufferIntegration +class Q_WAYLAND_COMPOSITOR_EXPORT ServerBufferIntegration { public: ServerBufferIntegration(); diff --git a/src/compositor/hardware_integration/qwlserverbufferintegrationfactory.cpp b/src/compositor/hardware_integration/qwlserverbufferintegrationfactory.cpp index 12a7903d6..05f16e525 100644 --- a/src/compositor/hardware_integration/qwlserverbufferintegrationfactory.cpp +++ b/src/compositor/hardware_integration/qwlserverbufferintegrationfactory.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/compositor/hardware_integration/qwlserverbufferintegrationfactory_p.h b/src/compositor/hardware_integration/qwlserverbufferintegrationfactory_p.h index 4d07df96f..b29ddd041 100644 --- a/src/compositor/hardware_integration/qwlserverbufferintegrationfactory_p.h +++ b/src/compositor/hardware_integration/qwlserverbufferintegrationfactory_p.h @@ -3,9 +3,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -45,7 +48,7 @@ // We mean it. // -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> #include <QtCore/QStringList> QT_BEGIN_NAMESPACE @@ -54,7 +57,7 @@ namespace QtWayland { class ServerBufferIntegration; -class Q_COMPOSITOR_EXPORT ServerBufferIntegrationFactory +class Q_WAYLAND_COMPOSITOR_EXPORT ServerBufferIntegrationFactory { public: static QStringList keys(const QString &pluginPath = QString()); diff --git a/src/compositor/hardware_integration/qwlserverbufferintegrationplugin.cpp b/src/compositor/hardware_integration/qwlserverbufferintegrationplugin.cpp index f633c1c18..ca03c49b4 100644 --- a/src/compositor/hardware_integration/qwlserverbufferintegrationplugin.cpp +++ b/src/compositor/hardware_integration/qwlserverbufferintegrationplugin.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/compositor/hardware_integration/qwlserverbufferintegrationplugin_p.h b/src/compositor/hardware_integration/qwlserverbufferintegrationplugin_p.h index 2530ac3db..fc8c3bf1e 100644 --- a/src/compositor/hardware_integration/qwlserverbufferintegrationplugin_p.h +++ b/src/compositor/hardware_integration/qwlserverbufferintegrationplugin_p.h @@ -3,9 +3,9 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -16,16 +16,19 @@ ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company 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 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -45,7 +48,7 @@ // We mean it. // -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> #include <QtCore/qplugin.h> #include <QtCore/qfactoryinterface.h> @@ -58,7 +61,7 @@ class ServerBufferIntegration; #define QtWaylandServerBufferIntegrationFactoryInterface_iid "org.qt-project.Qt.Compositor.QtWaylandServerBufferIntegrationFactoryInterface.5.3" -class Q_COMPOSITOR_EXPORT ServerBufferIntegrationPlugin : public QObject +class Q_WAYLAND_COMPOSITOR_EXPORT ServerBufferIntegrationPlugin : public QObject { Q_OBJECT public: diff --git a/src/compositor/shaders/surface.vert b/src/compositor/shaders/surface.vert new file mode 100644 index 000000000..848b334f3 --- /dev/null +++ b/src/compositor/shaders/surface.vert @@ -0,0 +1,9 @@ +uniform highp mat4 qt_Matrix; +attribute highp vec2 qt_VertexPosition; +attribute highp vec2 qt_VertexTexCoord; +varying highp vec2 v_texcoord; + +void main() { + gl_Position = qt_Matrix * vec4(qt_VertexPosition, 0.0, 1.0); + v_texcoord = qt_VertexTexCoord; +} diff --git a/src/compositor/shaders/surface_oes_external.frag b/src/compositor/shaders/surface_oes_external.frag new file mode 100644 index 000000000..724d06a85 --- /dev/null +++ b/src/compositor/shaders/surface_oes_external.frag @@ -0,0 +1,8 @@ +#extension GL_OES_EGL_image_external : require +varying highp vec2 v_texcoord; +uniform highp samplerExternalOES tex0; +uniform lowp float qt_Opacity; + +void main() { + gl_FragColor = qt_Opacity * texture2D(tex0, v_texcoord); +} diff --git a/src/compositor/shaders/surface_rgba.frag b/src/compositor/shaders/surface_rgba.frag new file mode 100644 index 000000000..f896051ba --- /dev/null +++ b/src/compositor/shaders/surface_rgba.frag @@ -0,0 +1,7 @@ +varying highp vec2 v_texcoord; +uniform highp sampler2D tex0; +uniform lowp float qt_Opacity; + +void main() { + gl_FragColor = qt_Opacity * texture2D(tex0, v_texcoord); +} diff --git a/src/compositor/shaders/surface_rgbx.frag b/src/compositor/shaders/surface_rgbx.frag new file mode 100644 index 000000000..8fb78498c --- /dev/null +++ b/src/compositor/shaders/surface_rgbx.frag @@ -0,0 +1,8 @@ +varying highp vec2 v_texcoord; +uniform highp sampler2D tex0; +uniform lowp float qt_Opacity; + +void main() { + gl_FragColor.rgb = qt_Opacity * texture2D(tex0, v_texcoord).rgb; + gl_FragColor.a = qt_Opacity; +} diff --git a/src/compositor/shaders/surface_y_u_v.frag b/src/compositor/shaders/surface_y_u_v.frag new file mode 100644 index 000000000..e739f6fff --- /dev/null +++ b/src/compositor/shaders/surface_y_u_v.frag @@ -0,0 +1,18 @@ +uniform highp sampler2D tex0; +uniform highp sampler2D tex1; +uniform highp sampler2D tex2; +varying highp vec2 v_texcoord; +uniform lowp float qt_Opacity; + +void main() { + float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625); + float u = texture2D(tex1, v_texcoord).x - 0.5; + float v = texture2D(tex2, v_texcoord).x - 0.5; + y *= qt_Opacity; + u *= qt_Opacity; + v *= qt_Opacity; + gl_FragColor.r = y + 1.59602678 * v; + gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v; + gl_FragColor.b = y + 2.01723214 * u; + gl_FragColor.a = qt_Opacity; +} diff --git a/src/compositor/shaders/surface_y_uv.frag b/src/compositor/shaders/surface_y_uv.frag new file mode 100644 index 000000000..e3fbcdf8d --- /dev/null +++ b/src/compositor/shaders/surface_y_uv.frag @@ -0,0 +1,17 @@ +uniform highp sampler2D tex0; +uniform highp sampler2D tex1; +varying highp vec2 v_texcoord; +uniform lowp float qt_Opacity; + +void main() { + float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625); + float u = texture2D(tex1, v_texcoord).r - 0.5; + float v = texture2D(tex1, v_texcoord).g - 0.5; + y *= qt_Opacity; + u *= qt_Opacity; + v *= qt_Opacity; + gl_FragColor.r = y + 1.59602678 * v; + gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v; + gl_FragColor.b = y + 2.01723214 * u; + gl_FragColor.a = qt_Opacity; +} diff --git a/src/compositor/shaders/surface_y_xuxv.frag b/src/compositor/shaders/surface_y_xuxv.frag new file mode 100644 index 000000000..79f8600e8 --- /dev/null +++ b/src/compositor/shaders/surface_y_xuxv.frag @@ -0,0 +1,17 @@ +uniform highp sampler2D tex0; +uniform highp sampler2D tex1; +varying highp vec2 v_texcoord; +uniform lowp float qt_Opacity; + +void main() { + float y = 1.16438356 * (texture2D(tex0, v_texcoord).x - 0.0625); + float u = texture2D(tex1, v_texcoord).g - 0.5; + float v = texture2D(tex1, v_texcoord).a - 0.5; + y *= qt_Opacity; + u *= qt_Opacity; + v *= qt_Opacity; + gl_FragColor.r = y + 1.59602678 * v; + gl_FragColor.g = y - 0.39176229 * u - 0.81296764 * v; + gl_FragColor.b = y + 2.01723214 * u; + gl_FragColor.a = qt_Opacity; +} diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp deleted file mode 100644 index f8c8bdc1f..000000000 --- a/src/compositor/wayland_wrapper/qwlcompositor.cpp +++ /dev/null @@ -1,594 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlcompositor_p.h" - -#include "qwaylandinput.h" -#include "qwldisplay_p.h" -#include "qwloutput_p.h" -#include "qwlsurface_p.h" -#include "qwaylandclient.h" -#include "qwaylandcompositor.h" -#include "qwldatadevicemanager_p.h" -#include "qwldatadevice_p.h" -#include "qwlextendedsurface_p.h" -#include "qwlsubsurface_p.h" -#include "qwlshellsurface_p.h" -#include "qwlqttouch_p.h" -#include "qwlqtkey_p.h" -#include "qwlinputdevice_p.h" -#include "qwlinputpanel_p.h" -#include "qwlregion_p.h" -#include "qwlpointer_p.h" -#include "qwltextinputmanager_p.h" -#include "qwaylandglobalinterface.h" -#include "qwaylandsurfaceview.h" -#include "qwaylandshmformathelper.h" -#include "qwaylandoutput.h" -#include "qwlkeyboard_p.h" - -#include <QWindow> -#include <QSocketNotifier> -#include <QScreen> -#include <qpa/qplatformscreen.h> -#include <QGuiApplication> -#include <QDebug> - -#include <QtCore/QAbstractEventDispatcher> -#include <QtGui/private/qguiapplication_p.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stddef.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> - -#include <sys/mman.h> -#include <sys/select.h> -#include <sys/time.h> - -#include <wayland-server.h> - -#if defined (QT_COMPOSITOR_WAYLAND_GL) -#include "hardware_integration/qwlhwintegration_p.h" -#include "hardware_integration/qwlclientbufferintegration_p.h" -#include "hardware_integration/qwlserverbufferintegration_p.h" -#endif -#include "windowmanagerprotocol/waylandwindowmanagerintegration_p.h" - -#include "hardware_integration/qwlclientbufferintegrationfactory_p.h" -#include "hardware_integration/qwlserverbufferintegrationfactory_p.h" - -#include "../shared/qwaylandxkb.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -static Compositor *compositor; - -class WindowSystemEventHandler : public QWindowSystemEventHandler -{ -public: - WindowSystemEventHandler(Compositor *c) : compositor(c) {} - bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) Q_DECL_OVERRIDE - { - if (e->type == QWindowSystemInterfacePrivate::Key) { - QWindowSystemInterfacePrivate::KeyEvent *ke = static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e); - Keyboard *keyb = compositor->defaultInputDevice()->keyboardDevice(); - - uint32_t code = ke->nativeScanCode; - bool isDown = ke->keyType == QEvent::KeyPress; - -#ifndef QT_NO_WAYLAND_XKB - QString text; - Qt::KeyboardModifiers modifiers = QWaylandXkb::modifiers(keyb->xkbState()); - - const xkb_keysym_t sym = xkb_state_key_get_one_sym(keyb->xkbState(), code); - uint utf32 = xkb_keysym_to_utf32(sym); - if (utf32) - text = QString::fromUcs4(&utf32, 1); - int qtkey = QWaylandXkb::keysymToQtKey(sym, modifiers, text); - - ke->key = qtkey; - ke->modifiers = modifiers; - ke->nativeVirtualKey = sym; - ke->nativeModifiers = keyb->xkbModsMask(); - ke->unicode = text; -#endif - if (!ke->repeat) - keyb->keyEvent(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED); - - QWindowSystemEventHandler::sendEvent(e); - - if (!ke->repeat) { - keyb->updateKeymap(); - keyb->updateModifierState(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED); - } - } else { - QWindowSystemEventHandler::sendEvent(e); - } - return true; - } - - Compositor *compositor; -}; - -Compositor *Compositor::instance() -{ - return compositor; -} - -Compositor::Compositor(QWaylandCompositor *qt_compositor, QWaylandCompositor::ExtensionFlags extensions) - : m_extensions(extensions) - , m_display(new Display) - , m_current_frame(0) - , m_last_queued_buf(-1) - , m_qt_compositor(qt_compositor) - , m_orientation(Qt::PrimaryOrientation) -#if defined (QT_COMPOSITOR_WAYLAND_GL) - , m_hw_integration(0) - , m_client_buffer_integration(0) - , m_server_buffer_integration(0) -#endif - , m_windowManagerIntegration(0) - , m_surfaceExtension(0) - , m_subSurfaceExtension(0) - , m_touchExtension(0) - , m_qtkeyExtension(0) - , m_textInputManager() - , m_inputPanel() - , m_eventHandler(new WindowSystemEventHandler(this)) - , m_retainSelection(false) -{ - m_timer.start(); - compositor = this; - - QWindowSystemInterfacePrivate::installWindowSystemEventHandler(m_eventHandler.data()); -} - -void Compositor::init() -{ - QStringList arguments = QCoreApplication::instance()->arguments(); - - int socketArg = arguments.indexOf(QLatin1String("--wayland-socket-name")); - if (socketArg != -1 && socketArg + 1 < arguments.size()) - m_socket_name = arguments.at(socketArg + 1).toLocal8Bit(); - - wl_compositor::init(m_display->handle(), 3); - - m_data_device_manager = new DataDeviceManager(this); - - wl_display_init_shm(m_display->handle()); - QVector<wl_shm_format> formats = QWaylandShmFormatHelper::supportedWaylandFormats(); - foreach (wl_shm_format format, formats) - wl_display_add_shm_format(m_display->handle(), format); - - if (wl_display_add_socket(m_display->handle(), m_qt_compositor->socketName())) { - fprintf(stderr, "Fatal: Failed to open server socket\n"); - exit(EXIT_FAILURE); - } - - m_loop = wl_display_get_event_loop(m_display->handle()); - - int fd = wl_event_loop_get_fd(m_loop); - - QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, this); - connect(sockNot, SIGNAL(activated(int)), this, SLOT(processWaylandEvents())); - - QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher; - connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processWaylandEvents())); - - qRegisterMetaType<SurfaceBuffer*>("SurfaceBuffer*"); - qRegisterMetaType<QWaylandClient*>("WaylandClient*"); - qRegisterMetaType<QWaylandSurface*>("WaylandSurface*"); - qRegisterMetaType<QWaylandSurfaceView*>("WaylandSurfaceView*"); - //initialize distancefieldglyphcache here - - initializeHardwareIntegration(); - initializeExtensions(); - initializeDefaultInputDevice(); -} - -Compositor::~Compositor() -{ - if (!m_destroyed_surfaces.isEmpty()) - qWarning("QWaylandCompositor::cleanupGraphicsResources() must be called manually"); - qDeleteAll(m_clients); - - qDeleteAll(m_outputs); - - delete m_surfaceExtension; - delete m_subSurfaceExtension; - delete m_touchExtension; - delete m_qtkeyExtension; - - removeInputDevice(m_default_wayland_input_device); - delete m_default_wayland_input_device; - delete m_data_device_manager; - - delete m_display; -} - -void Compositor::sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces) -{ - foreach (QWaylandSurface *surface, visibleSurfaces) { - surface->handle()->sendFrameCallback(); - } - wl_display_flush_clients(m_display->handle()); -} - -uint Compositor::currentTimeMsecs() const -{ - return m_timer.elapsed(); -} - -QList<QWaylandOutput *> Compositor::outputs() const -{ - return m_outputs; -} - -QWaylandOutput *Compositor::output(QWindow *window) const -{ - Q_FOREACH (QWaylandOutput *output, m_outputs) { - if (output->window() == window) - return output; - } - - return Q_NULLPTR; -} - -void Compositor::addOutput(QWaylandOutput *output) -{ - Q_ASSERT(output->handle()); - - if (m_outputs.contains(output)) - return; - - m_outputs.append(output); -} - -void Compositor::removeOutput(QWaylandOutput *output) -{ - Q_ASSERT(output->handle()); - - m_outputs.removeOne(output); -} - -QWaylandOutput *Compositor::primaryOutput() const -{ - if (m_outputs.size() == 0) - return Q_NULLPTR; - return m_outputs.at(0); -} - -void Compositor::setPrimaryOutput(QWaylandOutput *output) -{ - Q_ASSERT(output->handle()); - - int i = m_outputs.indexOf(output); - if (i <= 0) - return; - - m_outputs.removeAt(i); - m_outputs.prepend(output); -} - -void Compositor::processWaylandEvents() -{ - int ret = wl_event_loop_dispatch(m_loop, 0); - if (ret) - fprintf(stderr, "wl_event_loop_dispatch error: %d\n", ret); - wl_display_flush_clients(m_display->handle()); -} - -void Compositor::destroySurface(Surface *surface) -{ - m_surfaces.removeOne(surface); - - waylandCompositor()->surfaceAboutToBeDestroyed(surface->waylandSurface()); - - surface->releaseSurfaces(); - m_destroyed_surfaces << surface->waylandSurface(); -} - -void Compositor::resetInputDevice(Surface *surface) -{ - foreach (QWaylandInputDevice *dev, m_inputDevices) { - if (dev->keyboardFocus() == surface->waylandSurface()) - dev->setKeyboardFocus(0); - if (dev->mouseFocus() && dev->mouseFocus()->surface() == surface->waylandSurface()) - dev->setMouseFocus(0, QPointF(), QPointF()); - } -} - -void Compositor::cleanupGraphicsResources() -{ - qDeleteAll(m_destroyed_surfaces); - m_destroyed_surfaces.clear(); -} - -void Compositor::compositor_create_surface(Resource *resource, uint32_t id) -{ - QWaylandSurface *surface = new QWaylandSurface(resource->client(), id, resource->version(), m_qt_compositor); - m_surfaces << surface->handle(); - surface->handle()->addToOutput(primaryOutput()->handle()); - //BUG: This may not be an on-screen window surface though - m_qt_compositor->surfaceCreated(surface); -} - -void Compositor::compositor_create_region(Resource *resource, uint32_t id) -{ - Q_UNUSED(compositor); - new Region(resource->client(), id); -} - -void Compositor::destroyClient(QWaylandClient *client) -{ - if (!client) - return; - - if (m_windowManagerIntegration) - m_windowManagerIntegration->sendQuitMessage(client->client()); - - wl_client_destroy(client->client()); -} - -ClientBufferIntegration * Compositor::clientBufferIntegration() const -{ -#ifdef QT_COMPOSITOR_WAYLAND_GL - return m_client_buffer_integration.data(); -#else - return 0; -#endif -} - -ServerBufferIntegration * Compositor::serverBufferIntegration() const -{ -#ifdef QT_COMPOSITOR_WAYLAND_GL - return m_server_buffer_integration.data(); -#else - return 0; -#endif -} - -void Compositor::initializeHardwareIntegration() -{ -#ifdef QT_COMPOSITOR_WAYLAND_GL - if (m_extensions & QWaylandCompositor::HardwareIntegrationExtension) - m_hw_integration.reset(new HardwareIntegration(this)); - - loadClientBufferIntegration(); - loadServerBufferIntegration(); - - if (m_client_buffer_integration) - m_client_buffer_integration->initializeHardware(m_display); - if (m_server_buffer_integration) - m_server_buffer_integration->initializeHardware(m_qt_compositor); -#endif -} - -void Compositor::initializeExtensions() -{ - if (m_extensions & QWaylandCompositor::SurfaceExtension) - m_surfaceExtension = new SurfaceExtensionGlobal(this); - if (m_extensions & QWaylandCompositor::SubSurfaceExtension) - m_subSurfaceExtension = new SubSurfaceExtensionGlobal(this); - if (m_extensions & QWaylandCompositor::TouchExtension) - m_touchExtension = new TouchExtensionGlobal(this); - if (m_extensions & QWaylandCompositor::QtKeyExtension) - m_qtkeyExtension = new QtKeyExtensionGlobal(this); - if (m_extensions & QWaylandCompositor::TextInputExtension) { - m_textInputManager.reset(new TextInputManager(this)); - m_inputPanel.reset(new InputPanel(this)); - } - if (m_extensions & QWaylandCompositor::WindowManagerExtension) { - m_windowManagerIntegration = new WindowManagerServerIntegration(m_qt_compositor, this); - m_windowManagerIntegration->initialize(m_display); - } -} - -void Compositor::initializeDefaultInputDevice() -{ - m_default_wayland_input_device = new QWaylandInputDevice(m_qt_compositor); - registerInputDevice(m_default_wayland_input_device); -} - -QList<QWaylandClient *> Compositor::clients() const -{ - return m_clients; -} - -void Compositor::setClientFullScreenHint(bool value) -{ - if (m_windowManagerIntegration) - m_windowManagerIntegration->setShowIsFullScreen(value); -} - -QWaylandCompositor::ExtensionFlags Compositor::extensions() const -{ - return m_extensions; -} - -InputDevice* Compositor::defaultInputDevice() -{ - // The list gets prepended so that default is the last element - return m_inputDevices.last()->handle(); -} - -void Compositor::configureTouchExtension(int flags) -{ - if (m_touchExtension) - m_touchExtension->setFlags(flags); -} - -InputPanel *Compositor::inputPanel() const -{ - return m_inputPanel.data(); -} - -DataDeviceManager *Compositor::dataDeviceManager() const -{ - return m_data_device_manager; -} - -void Compositor::setRetainedSelectionEnabled(bool enabled) -{ - m_retainSelection = enabled; -} - -bool Compositor::retainedSelectionEnabled() const -{ - return m_retainSelection; -} - -void Compositor::feedRetainedSelectionData(QMimeData *data) -{ - if (m_retainSelection) - m_qt_compositor->retainedSelectionReceived(data); -} - -void Compositor::overrideSelection(const QMimeData *data) -{ - m_data_device_manager->overrideSelection(*data); -} - -bool Compositor::isDragging() const -{ - return false; -} - -void Compositor::sendDragMoveEvent(const QPoint &global, const QPoint &local, - Surface *surface) -{ - Q_UNUSED(global); - Q_UNUSED(local); - Q_UNUSED(surface); -// Drag::instance()->dragMove(global, local, surface); -} - -void Compositor::sendDragEndEvent() -{ -// Drag::instance()->dragEnd(); -} - -void Compositor::bindGlobal(wl_client *client, void *data, uint32_t version, uint32_t id) -{ - QWaylandGlobalInterface *iface = static_cast<QWaylandGlobalInterface *>(data); - iface->bind(client, qMin(iface->version(), version), id); -}; - -void Compositor::loadClientBufferIntegration() -{ -#ifdef QT_COMPOSITOR_WAYLAND_GL - QStringList keys = ClientBufferIntegrationFactory::keys(); - QString targetKey; - QByteArray clientBufferIntegration = qgetenv("QT_WAYLAND_HARDWARE_INTEGRATION"); - if (clientBufferIntegration.isEmpty()) - clientBufferIntegration = qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"); - if (keys.contains(QString::fromLocal8Bit(clientBufferIntegration.constData()))) { - targetKey = QString::fromLocal8Bit(clientBufferIntegration.constData()); - } else if (keys.contains(QString::fromLatin1("wayland-egl"))) { - targetKey = QString::fromLatin1("wayland-egl"); - } else if (!keys.isEmpty()) { - targetKey = keys.first(); - } - - if (!targetKey.isEmpty()) { - m_client_buffer_integration.reset(ClientBufferIntegrationFactory::create(targetKey, QStringList())); - if (m_client_buffer_integration) { - m_client_buffer_integration->setCompositor(m_qt_compositor); - if (m_hw_integration) - m_hw_integration->setClientBufferIntegration(targetKey); - } - } - //BUG: if there is no client buffer integration, bad things will happen when opengl is used -#endif -} - -void Compositor::loadServerBufferIntegration() -{ -#ifdef QT_COMPOSITOR_WAYLAND_GL - QStringList keys = ServerBufferIntegrationFactory::keys(); - QString targetKey; - QByteArray serverBufferIntegration = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"); - if (keys.contains(QString::fromLocal8Bit(serverBufferIntegration.constData()))) { - targetKey = QString::fromLocal8Bit(serverBufferIntegration.constData()); - } - if (!targetKey.isEmpty()) { - m_server_buffer_integration.reset(ServerBufferIntegrationFactory::create(targetKey, QStringList())); - if (m_hw_integration) - m_hw_integration->setServerBufferIntegration(targetKey); - } -#endif -} - -void Compositor::registerInputDevice(QWaylandInputDevice *device) -{ - // The devices get prepended as the first input device that gets added - // is assumed to be the default and it will claim to accept all the input - // events if asked - m_inputDevices.prepend(device); -} - -void Compositor::removeInputDevice(QWaylandInputDevice *device) -{ - m_inputDevices.removeOne(device); -} - -QWaylandInputDevice *Compositor::inputDeviceFor(QInputEvent *inputEvent) -{ - QWaylandInputDevice *dev = NULL; - for (int i = 0; i < m_inputDevices.size(); i++) { - QWaylandInputDevice *candidate = m_inputDevices.at(i); - if (candidate->isOwner(inputEvent)) { - dev = candidate; - break; - } - } - return dev; -} - -} // namespace Wayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h deleted file mode 100644 index 0ba30eb20..000000000 --- a/src/compositor/wayland_wrapper/qwlcompositor_p.h +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WL_COMPOSITOR_H -#define WL_COMPOSITOR_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/qwaylandcompositor.h> - -#include <QtCompositor/private/qwayland-server-wayland.h> - -#include <QtCore/QElapsedTimer> -#include <QtCore/QSet> - -#include <private/qwldisplay_p.h> - -#include <wayland-server.h> - -QT_BEGIN_NAMESPACE - -class QWaylandClient; -class QWaylandClientPrivate; -class QInputEvent; - -class QWaylandCompositor; -class QWaylandInputDevice; -class WindowManagerServerIntegration; -class QMimeData; -class QPlatformScreenBuffer; -class QWaylandSurface; -class QWindowSystemEventHandler; - -namespace QtWayland { - -class Surface; -class SurfaceBuffer; -class InputDevice; -class DataDeviceManager; -class OutputGlobal; -class SurfaceExtensionGlobal; -class SubSurfaceExtensionGlobal; -class TouchExtensionGlobal; -class QtKeyExtensionGlobal; -class TextInputManager; -class InputPanel; -class HardwareIntegration; -class ClientBufferIntegration; -class ServerBufferIntegration; - -class Q_COMPOSITOR_EXPORT Compositor : public QObject, public QtWaylandServer::wl_compositor -{ - Q_OBJECT - -public: - Compositor(QWaylandCompositor *qt_compositor, QWaylandCompositor::ExtensionFlags extensions); - ~Compositor(); - - void init(); - void sendFrameCallbacks(QList<QWaylandSurface *> visibleSurfaces); - - InputDevice *defaultInputDevice(); - - void registerInputDevice(QWaylandInputDevice *device); - QList<QWaylandInputDevice *> inputDevices() const { return m_inputDevices; } - QWaylandInputDevice *inputDeviceFor(QInputEvent *inputEvent); - void removeInputDevice(QWaylandInputDevice *device); - - void destroySurface(Surface *surface); - - void destroyClient(QWaylandClient *client); - - uint currentTimeMsecs() const; - - QList<QWaylandOutput *> outputs() const; - QWaylandOutput *output(QWindow *window) const; - - void addOutput(QWaylandOutput *output); - void removeOutput(QWaylandOutput *output); - - QWaylandOutput *primaryOutput() const; - void setPrimaryOutput(QWaylandOutput *output); - - ClientBufferIntegration *clientBufferIntegration() const; - ServerBufferIntegration *serverBufferIntegration() const; - void initializeHardwareIntegration(); - void initializeExtensions(); - void initializeDefaultInputDevice(); - void initializeWindowManagerProtocol(); - - QList<Surface *> surfaces() const { return m_surfaces; } - - QWaylandCompositor *waylandCompositor() const { return m_qt_compositor; } - - struct wl_display *wl_display() const { return m_display->handle(); } - Display *display() const { return m_display; } - - static Compositor *instance(); - - QList<QWaylandClient *> clients() const; - - WindowManagerServerIntegration *windowManagerIntegration() const { return m_windowManagerIntegration; } - - void setClientFullScreenHint(bool value); - - QWaylandCompositor::ExtensionFlags extensions() const; - - TouchExtensionGlobal *touchExtension() { return m_touchExtension; } - void configureTouchExtension(int flags); - - QtKeyExtensionGlobal *qtkeyExtension() { return m_qtkeyExtension; } - - InputPanel *inputPanel() const; - - DataDeviceManager *dataDeviceManager() const; - - bool isDragging() const; - void sendDragMoveEvent(const QPoint &global, const QPoint &local, Surface *surface); - void sendDragEndEvent(); - - void setRetainedSelectionEnabled(bool enabled); - bool retainedSelectionEnabled() const; - void overrideSelection(const QMimeData *data); - void feedRetainedSelectionData(QMimeData *data); - - static void bindGlobal(wl_client *client, void *data, uint32_t version, uint32_t id); - void resetInputDevice(Surface *surface); - -public slots: - void cleanupGraphicsResources(); - -protected: - void compositor_create_surface(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; - void compositor_create_region(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; -private slots: - void processWaylandEvents(); - -protected: - void loadClientBufferIntegration(); - void loadServerBufferIntegration(); - - QWaylandCompositor::ExtensionFlags m_extensions; - - Display *m_display; - QByteArray m_socket_name; - - /* Input */ - QWaylandInputDevice *m_default_wayland_input_device; - - QList<QWaylandInputDevice *> m_inputDevices; - - /* Output */ - QList<QWaylandOutput *> m_outputs; - - DataDeviceManager *m_data_device_manager; - - QElapsedTimer m_timer; - QList<Surface *> m_surfaces; - QSet<QWaylandSurface *> m_destroyed_surfaces; - - /* Render state */ - uint32_t m_current_frame; - int m_last_queued_buf; - - wl_event_loop *m_loop; - - QWaylandCompositor *m_qt_compositor; - Qt::ScreenOrientation m_orientation; - QList<QWaylandClient *> m_clients; - -#ifdef QT_COMPOSITOR_WAYLAND_GL - QScopedPointer<HardwareIntegration> m_hw_integration; - QScopedPointer<ClientBufferIntegration> m_client_buffer_integration; - QScopedPointer<ServerBufferIntegration> m_server_buffer_integration; -#endif - - //extensions - WindowManagerServerIntegration *m_windowManagerIntegration; - - SurfaceExtensionGlobal *m_surfaceExtension; - SubSurfaceExtensionGlobal *m_subSurfaceExtension; - TouchExtensionGlobal *m_touchExtension; - QtKeyExtensionGlobal *m_qtkeyExtension; - QScopedPointer<TextInputManager> m_textInputManager; - QScopedPointer<InputPanel> m_inputPanel; - QList<QWaylandGlobalInterface *> m_globals; - QScopedPointer<QWindowSystemEventHandler> m_eventHandler; - - static void bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - - bool m_retainSelection; - - friend class QT_PREPEND_NAMESPACE(QWaylandCompositor); - friend class QT_PREPEND_NAMESPACE(QWaylandClient); - friend class QT_PREPEND_NAMESPACE(QWaylandClientPrivate); -}; - -} - -QT_END_NAMESPACE - -#endif //WL_COMPOSITOR_H diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp index d97592bd7..dea72bdcd 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -40,26 +36,26 @@ #include "qwldatadevice_p.h" -#include "qwlcompositor_p.h" #include "qwldatasource_p.h" #include "qwldataoffer_p.h" -#include "qwlinputdevice_p.h" -#include "qwlkeyboard_p.h" -#include "qwlpointer_p.h" -#include "qwlsurface_p.h" -#include "qwltouch_p.h" +#include "qwaylandsurface_p.h" #include "qwldatadevicemanager_p.h" #include "qwaylanddrag.h" -#include "qwaylandsurfaceview.h" +#include "qwaylandview.h" +#include <QtWaylandCompositor/QWaylandClient> +#include <QtWaylandCompositor/private/qwaylandcompositor_p.h> +#include <QtWaylandCompositor/private/qwaylandinput_p.h> +#include <QtWaylandCompositor/private/qwaylandpointer_p.h> +#include <QtCore/QPointF> #include <QDebug> QT_BEGIN_NAMESPACE namespace QtWayland { -DataDevice::DataDevice(InputDevice *inputDevice) +DataDevice::DataDevice(QWaylandInputDevice *inputDevice) : wl_data_device() , m_compositor(inputDevice->compositor()) , m_inputDevice(inputDevice) @@ -72,12 +68,12 @@ DataDevice::DataDevice(InputDevice *inputDevice) { } -void DataDevice::setFocus(QtWaylandServer::wl_keyboard::Resource *focusResource) +void DataDevice::setFocus(QWaylandClient *focusClient) { - if (!focusResource) + if (!focusClient) return; - Resource *resource = resourceMap().value(focusResource->client()); + Resource *resource = resourceMap().value(focusClient->client()); if (!resource) return; @@ -88,7 +84,7 @@ void DataDevice::setFocus(QtWaylandServer::wl_keyboard::Resource *focusResource) } } -void DataDevice::setDragFocus(QWaylandSurfaceView *focus, const QPointF &localPosition) +void DataDevice::setDragFocus(QWaylandSurface *focus, const QPointF &localPosition) { if (m_dragFocusResource) { send_leave(m_dragFocusResource->handle); @@ -99,22 +95,22 @@ void DataDevice::setDragFocus(QWaylandSurfaceView *focus, const QPointF &localPo if (!focus) return; - if (!m_dragDataSource && m_dragClient != focus->surface()->handle()->resource()->client()) + if (!m_dragDataSource && m_dragClient != focus->waylandClient()) return; - Resource *resource = resourceMap().value(focus->surface()->handle()->resource()->client()); + Resource *resource = resourceMap().value(focus->waylandClient()); if (!resource) return; - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); + uint32_t serial = m_compositor->nextSerial(); DataOffer *offer = m_dragDataSource ? new DataOffer(m_dragDataSource, resource) : 0; if (m_dragDataSource && !offer) return; - send_enter(resource->handle, serial, focus->surface()->handle()->resource()->handle, + send_enter(resource->handle, serial, focus->resource(), wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()), offer->resource()->handle); @@ -122,7 +118,7 @@ void DataDevice::setDragFocus(QWaylandSurfaceView *focus, const QPointF &localPo m_dragFocusResource = resource; } -QWaylandSurfaceView *DataDevice::dragIcon() const +QWaylandSurface *DataDevice::dragIcon() const { return m_dragIcon; } @@ -133,65 +129,43 @@ void DataDevice::sourceDestroyed(DataSource *source) m_selectionSource = 0; } -void DataDevice::focus() +void DataDevice::dragMove(QWaylandSurface *target, const QPointF &pos) { - QWaylandSurfaceView *focus = m_compositor->waylandCompositor()->pickView(m_pointer->currentPosition()); - - if (focus != m_dragFocus) - setDragFocus(focus, m_compositor->waylandCompositor()->mapToView(focus, m_pointer->currentPosition())); + if (target != m_dragFocus) + setDragFocus(target, pos); + if (!target) + return; + uint time = m_compositor->currentTimeMsecs(); //### should be serial + send_motion(m_dragFocusResource->handle, time, + wl_fixed_from_double(pos.x()), wl_fixed_from_double(pos.y())); } -void DataDevice::motion(uint32_t time) +void DataDevice::drop() { - if (m_dragIcon) { - m_dragIcon->setPos(m_pointer->currentPosition()); - } - - if (m_dragFocusResource && m_dragFocus) { - const QPointF &surfacePoint = m_compositor->waylandCompositor()->mapToView(m_dragFocus, m_pointer->currentPosition()); - qDebug() << Q_FUNC_INFO << m_pointer->currentPosition() << surfacePoint; - send_motion(m_dragFocusResource->handle, time, - wl_fixed_from_double(surfacePoint.x()), wl_fixed_from_double(surfacePoint.y())); + if (m_dragFocusResource) { + send_drop(m_dragFocusResource->handle); + setDragFocus(nullptr, QPoint()); + } else { + m_dragDataSource->cancel(); } + setDragIcon(nullptr); } -void DataDevice::button(uint32_t time, Qt::MouseButton button, uint32_t state) +void DataDevice::cancelDrag() { - Q_UNUSED(time); - - if (m_dragFocusResource && - m_pointer->grabButton() == button && - state == Pointer::button_state_released) - send_drop(m_dragFocusResource->handle); - - if (!m_pointer->buttonPressed() && - state == Pointer::button_state_released) { - - if (m_dragIcon) { - m_dragIcon = 0; - Q_EMIT m_inputDevice->dragHandle()->iconChanged(); - } - - setDragFocus(0, QPointF()); - m_pointer->endGrab(); - } + setDragFocus(nullptr, QPoint()); } - + void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial) { - if (m_inputDevice->pointerDevice()->grabSerial() == serial) { - if (!m_inputDevice->pointerDevice()->buttonPressed() || - m_inputDevice->pointerDevice()->focusSurface()->surface()->handle() != Surface::fromResource(origin)) - return; - - m_dragClient = resource->client(); - m_dragDataSource = source != 0 ? DataSource::fromResource(source) : 0; - m_dragIcon = icon != 0 ? m_compositor->waylandCompositor()->createView(Surface::fromResource(icon)->waylandSurface()) : 0; - Q_EMIT m_inputDevice->dragHandle()->iconChanged(); - - m_inputDevice->pointerDevice()->setFocus(0, QPointF()); - m_inputDevice->pointerDevice()->startGrab(this); - } + m_dragClient = resource->client(); + m_dragDataSource = source ? DataSource::fromResource(source) : 0; + setDragIcon(icon ? QWaylandSurface::fromResource(icon) : nullptr); + Q_EMIT m_inputDevice->drag()->dragStarted(); + + Q_UNUSED(serial); + Q_UNUSED(origin); + //### need to verify that we have an implicit grab with this serial } void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *source, uint32_t serial) @@ -204,12 +178,12 @@ void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *sou m_selectionSource->cancel(); m_selectionSource = dataSource; - m_compositor->dataDeviceManager()->setCurrentSelectionSource(m_selectionSource); + QWaylandCompositorPrivate::get(m_compositor)->dataDeviceManager()->setCurrentSelectionSource(m_selectionSource); if (m_selectionSource) m_selectionSource->setDevice(this); - QtWaylandServer::wl_keyboard::Resource *focusResource = m_inputDevice->keyboardDevice()->focusResource(); - Resource *resource = focusResource ? resourceMap().value(focusResource->client()) : 0; + QWaylandClient *focusClient = m_inputDevice->keyboard()->focusClient(); + Resource *resource = focusClient ? resourceMap().value(focusClient->client()) : 0; if (resource && m_selectionSource) { DataOffer *offer = new DataOffer(m_selectionSource, resource); @@ -219,6 +193,14 @@ void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *sou } } +void DataDevice::setDragIcon(QWaylandSurface *icon) +{ + if (icon == m_dragIcon) + return; + m_dragIcon = icon; + Q_EMIT m_inputDevice->drag()->iconChanged(); +} + } QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwldatadevice_p.h b/src/compositor/wayland_wrapper/qwldatadevice_p.h index 17e605f19..2127603a8 100644 --- a/src/compositor/wayland_wrapper/qwldatadevice_p.h +++ b/src/compositor/wayland_wrapper/qwldatadevice_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -52,13 +48,11 @@ // We mean it. // -#include <QtCompositor/private/qwayland-server-wayland.h> -#include <qwlpointer_p.h> +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> +#include <QtWaylandCompositor/QWaylandInputDevice> QT_BEGIN_NAMESPACE -class QWaylandSurfaceView; - namespace QtWayland { class Compositor; @@ -66,39 +60,42 @@ class DataSource; class InputDevice; class Surface; -class DataDevice : public QtWaylandServer::wl_data_device, public PointerGrabber +class DataDevice : public QtWaylandServer::wl_data_device { public: - DataDevice(InputDevice *inputDevice); + DataDevice(QWaylandInputDevice *inputDevice); - void setFocus(QtWaylandServer::wl_keyboard::Resource *focusResource); + void setFocus(QWaylandClient *client); - void setDragFocus(QWaylandSurfaceView *focus, const QPointF &localPosition); + void setDragFocus(QWaylandSurface *focus, const QPointF &localPosition); - QWaylandSurfaceView *dragIcon() const; + QWaylandSurface *dragIcon() const; void sourceDestroyed(DataSource *source); - void focus() Q_DECL_OVERRIDE; - void motion(uint32_t time) Q_DECL_OVERRIDE; - void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; + void dragMove(QWaylandSurface *target, const QPointF &pos); + void drop(); + void cancelDrag(); + protected: void data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial) Q_DECL_OVERRIDE; void data_device_set_selection(Resource *resource, struct ::wl_resource *source, uint32_t serial) Q_DECL_OVERRIDE; private: - Compositor *m_compositor; - InputDevice *m_inputDevice; + void setDragIcon(QWaylandSurface *icon); + + QWaylandCompositor *m_compositor; + QWaylandInputDevice *m_inputDevice; DataSource *m_selectionSource; struct ::wl_client *m_dragClient; DataSource *m_dragDataSource; - QWaylandSurfaceView *m_dragFocus; + QWaylandSurface *m_dragFocus; Resource *m_dragFocusResource; - QWaylandSurfaceView *m_dragIcon; + QWaylandSurface *m_dragIcon; }; } diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp index 2fe7ff4d7..2f40b0e43 100644 --- a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp +++ b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -40,13 +36,14 @@ #include "qwldatadevicemanager_p.h" +#include <QtWaylandCompositor/QWaylandCompositor> + +#include <QtWaylandCompositor/private/qwaylandcompositor_p.h> +#include <QtWaylandCompositor/private/qwaylandinput_p.h> #include "qwldatadevice_p.h" #include "qwldatasource_p.h" -#include "qwlinputdevice_p.h" -#include "qwlcompositor_p.h" #include "qwldataoffer_p.h" -#include "qwlsurface_p.h" -#include "qwaylandmimehelper.h" +#include "qwaylandmimehelper_p.h" #include <QtCore/QDebug> #include <QtCore/QSocketNotifier> @@ -58,9 +55,9 @@ QT_BEGIN_NAMESPACE namespace QtWayland { -DataDeviceManager::DataDeviceManager(Compositor *compositor) +DataDeviceManager::DataDeviceManager(QWaylandCompositor *compositor) : QObject(0) - , wl_data_device_manager(compositor->wl_display(), 1) + , wl_data_device_manager(compositor->display(), 1) , m_compositor(compositor) , m_current_selection_source(0) , m_retainedReadNotifier(0) @@ -108,7 +105,7 @@ void DataDeviceManager::retain() QList<QString> offers = m_current_selection_source->mimeTypes(); finishReadFromClient(); if (m_retainedReadIndex >= offers.count()) { - m_compositor->feedRetainedSelectionData(&m_retainedData); + QWaylandCompositorPrivate::get(m_compositor)->feedRetainedSelectionData(&m_retainedData); return; } QString mimeType = offers.at(m_retainedReadIndex); @@ -185,7 +182,7 @@ DataSource *DataDeviceManager::currentSelectionSource() struct wl_display *DataDeviceManager::display() const { - return m_compositor->wl_display(); + return m_compositor->display(); } void DataDeviceManager::overrideSelection(const QMimeData &mimeData) @@ -198,15 +195,15 @@ void DataDeviceManager::overrideSelection(const QMimeData &mimeData) foreach (const QString &format, formats) m_retainedData.setData(format, mimeData.data(format)); - m_compositor->feedRetainedSelectionData(&m_retainedData); + QWaylandCompositorPrivate::get(m_compositor)->feedRetainedSelectionData(&m_retainedData); m_compositorOwnsSelection = true; - InputDevice *dev = m_compositor->defaultInputDevice(); - Surface *focusSurface = dev->keyboardFocus(); + QWaylandInputDevice *dev = m_compositor->defaultInputDevice(); + QWaylandSurface *focusSurface = dev->keyboardFocus(); if (focusSurface) offerFromCompositorToClient( - dev->dataDevice()->resourceMap().value(focusSurface->resource()->client())->handle); + QWaylandInputDevicePrivate::get(dev)->dataDevice()->resourceMap().value(focusSurface->waylandClient())->handle); } bool DataDeviceManager::offerFromCompositorToClient(wl_resource *clientDataDeviceResource) @@ -246,8 +243,8 @@ void DataDeviceManager::data_device_manager_create_data_source(Resource *resourc void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) { - InputDevice *input_device = InputDevice::fromSeatResource(seat); - input_device->clientRequestedDataDevice(this, resource->client(), id); + QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat); + QWaylandInputDevicePrivate::get(input_device)->clientRequestedDataDevice(this, resource->client(), id); } void DataDeviceManager::comp_accept(wl_client *, wl_resource *, uint32_t, const char *) diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h b/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h index 90d226d77..8408db977 100644 --- a/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h +++ b/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -52,14 +48,14 @@ // We mean it. // -#include <private/qwlcompositor_p.h> - #include <QtCore/QList> #include <QtCore/QMap> #include <QtGui/QClipboard> #include <QtCore/QMimeData> -#include <QtCompositor/private/qwayland-server-wayland.h> +#include <QtWaylandCompositor/QWaylandCompositor> + +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE @@ -67,8 +63,6 @@ class QSocketNotifier; namespace QtWayland { -class Compositor; - class DataDevice; class DataSource; @@ -77,7 +71,7 @@ class DataDeviceManager : public QObject, public QtWaylandServer::wl_data_device Q_OBJECT public: - DataDeviceManager(Compositor *compositor); + DataDeviceManager(QWaylandCompositor *compositor); void setCurrentSelectionSource(DataSource *source); DataSource *currentSelectionSource(); @@ -94,14 +88,14 @@ protected: void data_device_manager_create_data_source(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; void data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE; -private slots: +private Q_SLOTS: void readFromClient(int fd); private: void retain(); void finishReadFromClient(bool exhausted = false); - Compositor *m_compositor; + QWaylandCompositor *m_compositor; QList<DataDevice *> m_data_device_list; DataSource *m_current_selection_source; diff --git a/src/compositor/wayland_wrapper/qwldataoffer.cpp b/src/compositor/wayland_wrapper/qwldataoffer.cpp index 028e0bf86..c654b8a2f 100644 --- a/src/compositor/wayland_wrapper/qwldataoffer.cpp +++ b/src/compositor/wayland_wrapper/qwldataoffer.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** diff --git a/src/compositor/wayland_wrapper/qwldataoffer_p.h b/src/compositor/wayland_wrapper/qwldataoffer_p.h index cc0faa34d..09ca87650 100644 --- a/src/compositor/wayland_wrapper/qwldataoffer_p.h +++ b/src/compositor/wayland_wrapper/qwldataoffer_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -53,7 +49,7 @@ // #include <QPointer> -#include <QtCompositor/private/qwayland-server-wayland.h> +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwldatasource.cpp b/src/compositor/wayland_wrapper/qwldatasource.cpp index 0350ff649..aa2af1604 100644 --- a/src/compositor/wayland_wrapper/qwldatasource.cpp +++ b/src/compositor/wayland_wrapper/qwldatasource.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -42,10 +38,9 @@ #include "qwldataoffer_p.h" #include "qwldatadevice_p.h" #include "qwldatadevicemanager_p.h" -#include "qwlcompositor_p.h" #include <unistd.h> -#include <QtCompositor/private/wayland-wayland-server-protocol.h> +#include <QtWaylandCompositor/private/wayland-wayland-server-protocol.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwldatasource_p.h b/src/compositor/wayland_wrapper/qwldatasource_p.h index d4d10768b..4389b40fb 100644 --- a/src/compositor/wayland_wrapper/qwldatasource_p.h +++ b/src/compositor/wayland_wrapper/qwldatasource_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -52,7 +48,7 @@ // We mean it. // -#include <QtCompositor/private/qwayland-server-wayland.h> +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> #include <QObject> #include <QtCore/QList> diff --git a/src/compositor/wayland_wrapper/qwldisplay.cpp b/src/compositor/wayland_wrapper/qwldisplay.cpp deleted file mode 100644 index fafde3f73..000000000 --- a/src/compositor/wayland_wrapper/qwldisplay.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwldisplay_p.h" - -#include <QtCore/QDebug> - -#include <QtCompositor/private/wayland-wayland-server-protocol.h> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -Display::Display() -{ - m_display = wl_display_create(); - - Q_ASSERT(m_display); -} - -Display::~Display() -{ - wl_display_destroy(m_display); -} - -} - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwldisplay_p.h b/src/compositor/wayland_wrapper/qwldisplay_p.h deleted file mode 100644 index c89bb0509..000000000 --- a/src/compositor/wayland_wrapper/qwldisplay_p.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WL_DISPLAY_H -#define WL_DISPLAY_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <wayland-server.h> -#include <QtCompositor/qwaylandexport.h> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -class Display -{ -public: - Display(); - ~Display(); - - struct wl_display *handle() const { return m_display; } - struct wl_display *handle() { return m_display; } - -private: - struct wl_display *m_display; -}; - -} - -QT_END_NAMESPACE - -#endif //WL_DISPLAY_H diff --git a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h b/src/compositor/wayland_wrapper/qwlextendedsurface_p.h deleted file mode 100644 index 88c801067..000000000 --- a/src/compositor/wayland_wrapper/qwlextendedsurface_p.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WLEXTENDEDSURFACE_H -#define WLEXTENDEDSURFACE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <wayland-server.h> - -#include <QtCompositor/private/qwayland-server-surface-extension.h> -#include <private/qwlsurface_p.h> -#include <QtCompositor/qwaylandsurface.h> -#include <QtCompositor/qwaylandsurfaceinterface.h> - -#include <QtCore/QVariant> -#include <QtCore/QLinkedList> -#include <QtGui/QWindow> - -QT_BEGIN_NAMESPACE - -class QWaylandSurface; - -namespace QtWayland { - -class Compositor; - -class SurfaceExtensionGlobal : public QtWaylandServer::qt_surface_extension -{ -public: - SurfaceExtensionGlobal(Compositor *compositor); - -private: - void surface_extension_get_extended_surface(Resource *resource, - uint32_t id, - struct wl_resource *surface); - -}; - -class ExtendedSurface : public QWaylandSurfaceInterface, public QtWaylandServer::qt_extended_surface -{ -public: - ExtendedSurface(struct wl_client *client, uint32_t id, int version, Surface *surface); - ~ExtendedSurface(); - - void sendGenericProperty(const QString &name, const QVariant &variant); - - void setVisibility(QWindow::Visibility visibility); - - void setSubSurface(ExtendedSurface *subSurface,int x, int y); - void removeSubSurface(ExtendedSurface *subSurfaces); - ExtendedSurface *parent() const; - void setParent(ExtendedSurface *parent); - QLinkedList<QWaylandSurface *> subSurfaces() const; - void setParentSurface(Surface *s); - - Qt::ScreenOrientations contentOrientationMask() const; - - QWaylandSurface::WindowFlags windowFlags() const { return m_windowFlags; } - - QVariantMap windowProperties() const; - QVariant windowProperty(const QString &propertyName) const; - void setWindowProperty(const QString &name, const QVariant &value, bool writeUpdateToClient = true); - -protected: - bool runOperation(QWaylandSurfaceOp *op) Q_DECL_OVERRIDE; - -private: - Surface *m_surface; - - Qt::ScreenOrientations m_contentOrientationMask; - - QWaylandSurface::WindowFlags m_windowFlags; - - QByteArray m_authenticationToken; - QVariantMap m_windowProperties; - - void extended_surface_update_generic_property(Resource *resource, - const QString &name, - struct wl_array *value) Q_DECL_OVERRIDE; - - void extended_surface_set_content_orientation_mask(Resource *resource, - int32_t orientation) Q_DECL_OVERRIDE; - - void extended_surface_set_window_flags(Resource *resource, - int32_t flags) Q_DECL_OVERRIDE; - - void extended_surface_destroy_resource(Resource *) Q_DECL_OVERRIDE; - void extended_surface_raise(Resource *) Q_DECL_OVERRIDE; - void extended_surface_lower(Resource *) Q_DECL_OVERRIDE; -}; - -} - -QT_END_NAMESPACE - -#endif // WLEXTENDEDSURFACE_H diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp deleted file mode 100644 index ea127ee74..000000000 --- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlinputdevice_p.h" - -#include "qwlcompositor_p.h" -#include "qwldatadevice_p.h" -#include "qwlinputmethod_p.h" -#include "qwlsurface_p.h" -#include "qwlqttouch_p.h" -#include "qwlqtkey_p.h" -#include "qwaylandcompositor.h" -#include "qwaylanddrag.h" -#include "qwlpointer_p.h" -#include "qwlkeyboard_p.h" -#include "qwltouch_p.h" -#include "qwaylandsurfaceview.h" - -#include <QtGui/QTouchEvent> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -InputDevice::InputDevice(QWaylandInputDevice *handle, Compositor *compositor, QWaylandInputDevice::CapabilityFlags caps) - : QtWaylandServer::wl_seat(compositor->wl_display(), 3) - , m_handle(handle) - , m_dragHandle(new QWaylandDrag(this)) - , m_compositor(compositor) - , m_capabilities(caps) - , m_pointer(m_capabilities & QWaylandInputDevice::Pointer ? new Pointer(m_compositor, this) : 0) - , m_keyboard(m_capabilities & QWaylandInputDevice::Keyboard ? new Keyboard(m_compositor, this) : 0) - , m_touch(m_capabilities & QWaylandInputDevice::Touch ? new Touch(m_compositor) : 0) - , m_inputMethod(m_compositor->extensions() & QWaylandCompositor::TextInputExtension ? new InputMethod(m_compositor, this) : 0) - , m_data_device() -{ -} - -InputDevice::~InputDevice() -{ -} - -Pointer *InputDevice::pointerDevice() -{ - return m_pointer.data(); -} - -Keyboard *InputDevice::keyboardDevice() -{ - return m_keyboard.data(); -} - -Touch *InputDevice::touchDevice() -{ - return m_touch.data(); -} - -InputMethod *InputDevice::inputMethod() -{ - return m_inputMethod.data(); -} - -const Pointer *InputDevice::pointerDevice() const -{ - return m_pointer.data(); -} - -const Keyboard *InputDevice::keyboardDevice() const -{ - return m_keyboard.data(); -} - -const Touch *InputDevice::touchDevice() const -{ - return m_touch.data(); -} - -void InputDevice::seat_destroy_resource(wl_seat::Resource *) -{ -// cleanupDataDeviceForClient(resource->client(), true); -} - -void InputDevice::seat_bind_resource(wl_seat::Resource *resource) -{ - // The order of m_capabilities matches the order defined in the wayland protocol - wl_seat::send_capabilities(resource->handle, (uint32_t)m_capabilities); -} - -void InputDevice::setCapabilities(QWaylandInputDevice::CapabilityFlags caps) -{ - if (m_capabilities != caps) { - QWaylandInputDevice::CapabilityFlags changed = caps ^ m_capabilities; - - if (changed & QWaylandInputDevice::Pointer) { - m_pointer.reset(m_pointer.isNull() ? new Pointer(m_compositor, this) : 0); - } - - if (changed & QWaylandInputDevice::Keyboard) { - m_keyboard.reset(m_keyboard.isNull() ? new Keyboard(m_compositor, this) : 0); - } - - if (changed & QWaylandInputDevice::Touch) { - m_touch.reset(m_touch.isNull() ? new Touch(m_compositor) : 0); - } - - m_capabilities = caps; - QList<Resource *> resources = resourceMap().values(); - for (int i = 0; i < resources.size(); i++) { - wl_seat::send_capabilities(resources.at(i)->handle, (uint32_t)m_capabilities); - } - } -} - -void InputDevice::seat_get_pointer(wl_seat::Resource *resource, uint32_t id) -{ - if (!m_pointer.isNull()) { - m_pointer->add(resource->client(), id, resource->version()); - } -} - -void InputDevice::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id) -{ - if (!m_keyboard.isNull()) { - m_keyboard->add(resource->client(), id, resource->version()); - } -} - -void InputDevice::seat_get_touch(wl_seat::Resource *resource, uint32_t id) -{ - if (!m_touch.isNull()) { - m_touch->add(resource->client(), id, resource->version()); - } -} - -void InputDevice::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) -{ - pointerDevice()->sendMousePressEvent(button, localPos, globalPos); -} - -void InputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) -{ - pointerDevice()->sendMouseReleaseEvent(button, localPos, globalPos); -} - -void InputDevice::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos) -{ - pointerDevice()->sendMouseMoveEvent(localPos, globalPos); -} - -void InputDevice::sendMouseMoveEvent(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos) -{ - setMouseFocus(surface,localPos,globalPos); - sendMouseMoveEvent(localPos,globalPos); -} - -void InputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta) -{ - pointerDevice()->sendMouseWheelEvent(orientation, delta); -} - -void InputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state) -{ - if (m_touch.isNull()) { - return; - } - - switch (state) { - case Qt::TouchPointPressed: - m_touch->sendDown(id, QPointF(x, y)); - break; - case Qt::TouchPointMoved: - m_touch->sendMotion(id, QPointF(x, y)); - break; - case Qt::TouchPointReleased: - m_touch->sendUp(id); - break; - case Qt::TouchPointStationary: - // stationary points are not sent through wayland, the client must cache them - break; - default: - break; - } -} - -void InputDevice::sendTouchFrameEvent() -{ - if (!m_touch.isNull()) { - m_touch->sendFrame(); - } -} - -void InputDevice::sendTouchCancelEvent() -{ - if (!m_touch.isNull()) { - m_touch->sendCancel(); - } -} - -void InputDevice::sendFullKeyEvent(QKeyEvent *event) -{ - if (!keyboardFocus()) { - qWarning("Cannot send key event, no keyboard focus, fix the compositor"); - return; - } - - QtKeyExtensionGlobal *ext = m_compositor->qtkeyExtension(); - if (ext && ext->postQtKeyEvent(event, keyboardFocus())) - return; - - if (!m_keyboard.isNull() && !event->isAutoRepeat()) { - if (event->type() == QEvent::KeyPress) - m_keyboard->sendKeyPressEvent(event->nativeScanCode()); - else if (event->type() == QEvent::KeyRelease) - m_keyboard->sendKeyReleaseEvent(event->nativeScanCode()); - } -} - -void InputDevice::sendFullKeyEvent(Surface *surface, QKeyEvent *event) -{ - QtKeyExtensionGlobal *ext = m_compositor->qtkeyExtension(); - if (ext) - ext->postQtKeyEvent(event, surface); -} - -void InputDevice::sendFullTouchEvent(QTouchEvent *event) -{ - if (!mouseFocus()) { - qWarning("Cannot send touch event, no pointer focus, fix the compositor"); - return; - } - - if (event->type() == QEvent::TouchCancel) { - sendTouchCancelEvent(); - return; - } - - TouchExtensionGlobal *ext = m_compositor->touchExtension(); - if (ext && ext->postTouchEvent(event, mouseFocus())) - return; - - const QList<QTouchEvent::TouchPoint> points = event->touchPoints(); - if (points.isEmpty()) - return; - - const int pointCount = points.count(); - QPointF pos = mouseFocus()->pos(); - for (int i = 0; i < pointCount; ++i) { - const QTouchEvent::TouchPoint &tp(points.at(i)); - // Convert the local pos in the compositor window to surface-relative. - QPointF p = tp.pos() - pos; - sendTouchPointEvent(tp.id(), p.x(), p.y(), tp.state()); - } - sendTouchFrameEvent(); -} - -Surface *InputDevice::keyboardFocus() const -{ - return m_keyboard.isNull() ? 0 : m_keyboard->focus(); -} - -/*! - * \return True if the keyboard focus is changed successfully. False for inactive transient surfaces. - */ -bool InputDevice::setKeyboardFocus(Surface *surface) -{ - if (surface && (surface->transientInactive() || surface->isDestroyed())) - return false; - - if (!m_keyboard.isNull()) { - m_keyboard->setFocus(surface); - if (m_data_device) - m_data_device->setFocus(m_keyboard->focusResource()); - return true; - } - return false; -} - -QWaylandSurfaceView *InputDevice::mouseFocus() const -{ - return m_pointer.isNull() ? 0 : m_pointer->focusSurface(); -} - -void InputDevice::setMouseFocus(QWaylandSurfaceView *view, const QPointF &localPos, const QPointF &globalPos) -{ - if (view && view->surface()->handle()->isDestroyed()) - return; - - if (!m_pointer.isNull()) { - m_pointer->setMouseFocus(view, localPos, globalPos); - } - - if (!m_touch.isNull()) { - // We have no separate touch focus management so make it match the pointer focus always. - // No wl_touch_set_focus() is available so set it manually. - m_touch->setFocus(view); - } -} - -void InputDevice::clientRequestedDataDevice(DataDeviceManager *, struct wl_client *client, uint32_t id) -{ - if (!m_data_device) - m_data_device.reset(new DataDevice(this)); - m_data_device->add(client, id, 1); -} - -Compositor *InputDevice::compositor() const -{ - return m_compositor; -} - -QWaylandInputDevice *InputDevice::handle() const -{ - return m_handle; -} - -QWaylandDrag *InputDevice::dragHandle() const -{ - return m_dragHandle.data(); -} - -const DataDevice *InputDevice::dataDevice() const -{ - return m_data_device.data(); -} - -} - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlinputdevice_p.h b/src/compositor/wayland_wrapper/qwlinputdevice_p.h deleted file mode 100644 index f28946a9b..000000000 --- a/src/compositor/wayland_wrapper/qwlinputdevice_p.h +++ /dev/null @@ -1,168 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WLINPUTDEVICE_H -#define WLINPUTDEVICE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <stdint.h> - -#include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/qwaylandinput.h> - -#include <QtCore/QList> -#include <QtCore/QPoint> -#include <QtCore/QScopedPointer> - -#ifndef QT_NO_WAYLAND_XKB -#include <xkbcommon/xkbcommon.h> -#endif - -#include <QtCompositor/private/qwayland-server-wayland.h> - -QT_BEGIN_NAMESPACE - -class QKeyEvent; -class QTouchEvent; -class QWaylandInputDevice; -class QWaylandDrag; -class QWaylandSurfaceView; - -namespace QtWayland { - -class Compositor; -class DataDevice; -class Surface; -class DataDeviceManager; -class Pointer; -class Keyboard; -class Touch; -class InputMethod; - -class Q_COMPOSITOR_EXPORT InputDevice : public QtWaylandServer::wl_seat -{ -public: - InputDevice(QWaylandInputDevice *handle, Compositor *compositor, QWaylandInputDevice::CapabilityFlags caps); - ~InputDevice(); - - void sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos = QPointF()); - void sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos = QPointF()); - void sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos = QPointF()); - void sendMouseMoveEvent(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos = QPointF()); - void sendMouseWheelEvent(Qt::Orientation orientation, int delta); - - void sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state); - void sendTouchFrameEvent(); - void sendTouchCancelEvent(); - - void sendFullKeyEvent(QKeyEvent *event); - void sendFullKeyEvent(Surface *surface, QKeyEvent *event); - - void sendFullTouchEvent(QTouchEvent *event); - - Surface *keyboardFocus() const; - bool setKeyboardFocus(Surface *surface); - - QWaylandSurfaceView *mouseFocus() const; - void setMouseFocus(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos); - - void clientRequestedDataDevice(DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id); - const DataDevice *dataDevice() const; - - Compositor *compositor() const; - QWaylandInputDevice *handle() const; - QWaylandDrag *dragHandle() const; - - Pointer *pointerDevice(); - Keyboard *keyboardDevice(); - Touch *touchDevice(); - InputMethod *inputMethod(); - - const Pointer *pointerDevice() const; - const Keyboard *keyboardDevice() const; - const Touch *touchDevice() const; - - static InputDevice *fromSeatResource(struct ::wl_resource *resource) - { - return static_cast<InputDevice *>(wl_seat::Resource::fromResource(resource)->seat_object); - } - - QWaylandInputDevice::CapabilityFlags capabilities() { return m_capabilities; } - void setCapabilities(QWaylandInputDevice::CapabilityFlags caps); - -private: - QWaylandInputDevice *m_handle; - QScopedPointer<QWaylandDrag> m_dragHandle; - Compositor *m_compositor; - QWaylandInputDevice::CapabilityFlags m_capabilities; - - QScopedPointer<Pointer> m_pointer; - QScopedPointer<Keyboard> m_keyboard; - QScopedPointer<Touch> m_touch; - QScopedPointer<InputMethod> m_inputMethod; - QScopedPointer<DataDevice> m_data_device; - - void seat_bind_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE; - - void seat_get_pointer(wl_seat::Resource *resource, - uint32_t id) Q_DECL_OVERRIDE; - void seat_get_keyboard(wl_seat::Resource *resource, - uint32_t id) Q_DECL_OVERRIDE; - void seat_get_touch(wl_seat::Resource *resource, - uint32_t id) Q_DECL_OVERRIDE; - - void seat_destroy_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE; -}; - -} - -QT_END_NAMESPACE - -#endif // WLINPUTDEVICE_H diff --git a/src/compositor/wayland_wrapper/qwlinputmethod.cpp b/src/compositor/wayland_wrapper/qwlinputmethod.cpp deleted file mode 100644 index 5bafe7894..000000000 --- a/src/compositor/wayland_wrapper/qwlinputmethod.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlinputmethod_p.h" - -#include "qwlcompositor_p.h" -#include "qwlinputdevice_p.h" -#include "qwlinputmethodcontext_p.h" -#include "qwlinputpanel_p.h" -#include "qwlkeyboard_p.h" -#include "qwltextinput_p.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -InputMethod::InputMethod(Compositor *compositor, InputDevice *seat) - : QtWaylandServer::wl_input_method(seat->compositor()->wl_display(), 1) - , m_compositor(compositor) - , m_seat(seat) - , m_resource(0) - , m_textInput() - , m_context() -{ - connect(seat->keyboardDevice(), SIGNAL(focusChanged(Surface*)), this, SLOT(focusChanged(Surface*))); -} - -InputMethod::~InputMethod() -{ -} - -void InputMethod::activate(TextInput *textInput) -{ - if (!m_resource) { - qDebug("Cannot activate (no input method running)."); - return; - } - - if (m_textInput) { - Q_ASSERT(m_textInput != textInput); - m_textInput->deactivate(this); - } - m_textInput = textInput; - m_context = new InputMethodContext(m_resource->client(), textInput); - - send_activate(m_resource->handle, m_context->resource()->handle); - - m_compositor->inputPanel()->setFocus(textInput->focus()); - m_compositor->inputPanel()->setCursorRectangle(textInput->cursorRectangle()); - m_compositor->inputPanel()->setInputPanelVisible(textInput->inputPanelVisible()); -} - -void InputMethod::deactivate() -{ - if (!m_resource) { - qDebug("Cannot deactivate (no input method running)."); - return; - } - - send_deactivate(m_resource->handle, m_context->resource()->handle); - m_textInput = 0; - m_context = 0; - - m_compositor->inputPanel()->setFocus(0); - m_compositor->inputPanel()->setCursorRectangle(QRect()); - m_compositor->inputPanel()->setInputPanelVisible(false); -} - -void InputMethod::focusChanged(Surface *surface) -{ - if (!m_textInput) - return; - - if (!surface || m_textInput->focus() != surface) { - m_textInput->deactivate(this); - } -} - -bool InputMethod::isBound() const -{ - return m_resource != 0; -} - -InputMethodContext *InputMethod::context() const -{ - return m_context; -} - -TextInput *InputMethod::textInput() const -{ - return m_textInput; -} - -void InputMethod::input_method_bind_resource(Resource *resource) -{ - if (m_resource) { - wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "interface object already bound"); - wl_resource_destroy(resource->handle); - return; - } - - m_resource = resource; -} - -void InputMethod::input_method_destroy_resource(Resource *resource) -{ - Q_ASSERT(resource == m_resource); - m_resource = 0; -} - -} // namespace QtWayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlinputmethod_p.h b/src/compositor/wayland_wrapper/qwlinputmethod_p.h deleted file mode 100644 index f52208a9c..000000000 --- a/src/compositor/wayland_wrapper/qwlinputmethod_p.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLINPUTMETHOD_H -#define QTWAYLAND_QWLINPUTMETHOD_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/private/qwayland-server-input-method.h> - -#include <QObject> -#include <QScopedPointer> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -class Compositor; -class InputDevice; -class InputMethodContext; -class TextInput; -class Surface; - -class InputMethod : public QObject, public QtWaylandServer::wl_input_method -{ - Q_OBJECT - -public: - explicit InputMethod(Compositor *compositor, InputDevice *seat); - ~InputMethod(); - - void activate(TextInput *textInput); - void deactivate(); - - bool isBound() const; - - InputMethodContext *context() const; - TextInput *textInput() const; - -protected: - void input_method_bind_resource(Resource *resource); - void input_method_destroy_resource(Resource *resource); - -private slots: - void focusChanged(Surface *surface); - -private: - Compositor *m_compositor; - InputDevice *m_seat; - Resource *m_resource; - TextInput *m_textInput; - InputMethodContext *m_context; -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLINPUTMETHOD_H diff --git a/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp b/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp deleted file mode 100644 index caf75b2ae..000000000 --- a/src/compositor/wayland_wrapper/qwlinputmethodcontext.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlinputmethodcontext_p.h" - -#include "qwltextinput_p.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -InputMethodContext::InputMethodContext(wl_client *client, TextInput *textInput) - : QtWaylandServer::wl_input_method_context(client, 0, 1) - , m_textInput(textInput) -{ -} - -InputMethodContext::~InputMethodContext() -{ -} - -void InputMethodContext::input_method_context_destroy_resource(Resource *) -{ - delete this; -} - -void InputMethodContext::input_method_context_destroy(Resource *resource) -{ - wl_resource_destroy(resource->handle); -} - -void InputMethodContext::input_method_context_commit_string(Resource *, uint32_t serial, const QString &text) -{ - m_textInput->send_commit_string(serial, text); -} - -void InputMethodContext::input_method_context_cursor_position(Resource *, int32_t index, int32_t anchor) -{ - m_textInput->send_cursor_position(index, anchor); -} - -void InputMethodContext::input_method_context_delete_surrounding_text(Resource *, int32_t index, uint32_t length) -{ - m_textInput->send_delete_surrounding_text(index, length); -} - -void InputMethodContext::input_method_context_language(Resource *, uint32_t serial, const QString &language) -{ - m_textInput->send_language(serial, language); -} - -void InputMethodContext::input_method_context_keysym(Resource *, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers) -{ - m_textInput->send_keysym(serial, time, sym, state, modifiers); -} - -void InputMethodContext::input_method_context_modifiers_map(Resource *, wl_array *map) -{ - QByteArray modifiersArray(static_cast<char *>(map->data), map->size); - m_textInput->send_modifiers_map(modifiersArray); -} - -void InputMethodContext::input_method_context_preedit_cursor(Resource *, int32_t index) -{ - m_textInput->send_preedit_cursor(index); -} - -void InputMethodContext::input_method_context_preedit_string(Resource *, uint32_t serial, const QString &text, const QString &commit) -{ - m_textInput->send_preedit_string(serial, text, commit); -} - -void InputMethodContext::input_method_context_preedit_styling(Resource *, uint32_t index, uint32_t length, uint32_t style) -{ - m_textInput->send_preedit_styling(index, length, style); -} - -void InputMethodContext::input_method_context_grab_keyboard(Resource *, uint32_t keyboard) -{ - Q_UNUSED(keyboard); -} - -void InputMethodContext::input_method_context_key(Resource *, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -{ - Q_UNUSED(serial); - Q_UNUSED(time); - Q_UNUSED(key); - Q_UNUSED(state); -} - -void InputMethodContext::input_method_context_modifiers(Resource *, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) -{ - Q_UNUSED(serial); - Q_UNUSED(mods_depressed); - Q_UNUSED(mods_latched); - Q_UNUSED(mods_locked); - Q_UNUSED(group); -} - -} // namespace QtWayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlinputmethodcontext_p.h b/src/compositor/wayland_wrapper/qwlinputmethodcontext_p.h deleted file mode 100644 index ccf236e61..000000000 --- a/src/compositor/wayland_wrapper/qwlinputmethodcontext_p.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLINPUTMETHODCONTEXT_P_H -#define QTWAYLAND_QWLINPUTMETHODCONTEXT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/private/qwayland-server-input-method.h> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -class TextInput; - -class InputMethodContext : public QtWaylandServer::wl_input_method_context -{ -public: - explicit InputMethodContext(struct ::wl_client *client, TextInput *textInput); - ~InputMethodContext(); - -protected: - void input_method_context_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - void input_method_context_destroy(Resource *resource) Q_DECL_OVERRIDE; - - void input_method_context_commit_string(Resource *resource, uint32_t serial, const QString &text) Q_DECL_OVERRIDE; - void input_method_context_cursor_position(Resource *resource, int32_t index, int32_t anchor) Q_DECL_OVERRIDE; - void input_method_context_delete_surrounding_text(Resource *resource, int32_t index, uint32_t length) Q_DECL_OVERRIDE; - void input_method_context_language(Resource *resource, uint32_t serial, const QString &language) Q_DECL_OVERRIDE; - void input_method_context_keysym(Resource *resource, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers) Q_DECL_OVERRIDE; - void input_method_context_modifiers_map(Resource *resource, wl_array *map) Q_DECL_OVERRIDE; - void input_method_context_preedit_cursor(Resource *resource, int32_t index) Q_DECL_OVERRIDE; - void input_method_context_preedit_string(Resource *resource, uint32_t serial, const QString &text, const QString &commit) Q_DECL_OVERRIDE; - void input_method_context_preedit_styling(Resource *resource, uint32_t index, uint32_t length, uint32_t style) Q_DECL_OVERRIDE; - void input_method_context_grab_keyboard(Resource *resource, uint32_t keyboard) Q_DECL_OVERRIDE; - void input_method_context_key(Resource *resource, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) Q_DECL_OVERRIDE; - void input_method_context_modifiers(Resource *resource, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) Q_DECL_OVERRIDE; - -private: - TextInput *m_textInput; -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLINPUTMETHODCONTEXT_P_H diff --git a/src/compositor/wayland_wrapper/qwlinputpanel.cpp b/src/compositor/wayland_wrapper/qwlinputpanel.cpp deleted file mode 100644 index 2f11a9b3f..000000000 --- a/src/compositor/wayland_wrapper/qwlinputpanel.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlinputpanel_p.h" - -#include <QtCompositor/qwaylandinputpanel.h> - -#include "qwlcompositor_p.h" -#include "qwlinputdevice_p.h" -#include "qwlinputmethod_p.h" -#include "qwlinputpanelsurface_p.h" -#include "qwlsurface_p.h" -#include "qwltextinput_p.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -InputPanel::InputPanel(Compositor *compositor) - : QtWaylandServer::wl_input_panel(compositor->wl_display(), 1) - , m_compositor(compositor) - , m_handle(new QWaylandInputPanel(this)) - , m_focus() - , m_inputPanelVisible(false) - , m_cursorRectangle() -{ -} - -InputPanel::~InputPanel() -{ -} - -QWaylandInputPanel *InputPanel::handle() const -{ - return m_handle.data(); -} - -Surface *InputPanel::focus() const -{ - return m_focus; -} - -void InputPanel::setFocus(Surface *focus) -{ - if (m_focus == focus) - return; - - m_focus = focus; - - Q_EMIT handle()->focusChanged(); -} - -bool InputPanel::inputPanelVisible() const -{ - return m_inputPanelVisible; -} - -void InputPanel::setInputPanelVisible(bool inputPanelVisible) -{ - if (m_inputPanelVisible == inputPanelVisible) - return; - - m_inputPanelVisible = inputPanelVisible; - - Q_EMIT handle()->visibleChanged(); -} - -QRect InputPanel::cursorRectangle() const -{ - return m_cursorRectangle; -} - -void InputPanel::setCursorRectangle(const QRect &cursorRectangle) -{ - if (m_cursorRectangle == cursorRectangle) - return; - - m_cursorRectangle = cursorRectangle; - - Q_EMIT handle()->cursorRectangleChanged(); -} - -void InputPanel::input_panel_get_input_panel_surface(Resource *resource, uint32_t id, wl_resource *surface) -{ - new InputPanelSurface(resource->client(), id, Surface::fromResource(surface)); -} - -} // namespace QtWayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlinputpanel_p.h b/src/compositor/wayland_wrapper/qwlinputpanel_p.h deleted file mode 100644 index f8880ad4a..000000000 --- a/src/compositor/wayland_wrapper/qwlinputpanel_p.h +++ /dev/null @@ -1,105 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLINPUTPANEL_P_H -#define QTWAYLAND_QWLINPUTPANEL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> - -#include <QtCompositor/private/qwayland-server-input-method.h> - -#include <QRect> -#include <QScopedPointer> - -QT_BEGIN_NAMESPACE - -class QWaylandInputPanel; - -namespace QtWayland { - -class Compositor; -class Surface; -class TextInput; - -class Q_COMPOSITOR_EXPORT InputPanel : public QtWaylandServer::wl_input_panel -{ -public: - InputPanel(Compositor *compositor); - ~InputPanel(); - - QWaylandInputPanel *handle() const; - - Surface *focus() const; - void setFocus(Surface *focus); - - bool inputPanelVisible() const; - void setInputPanelVisible(bool inputPanelVisible); - - QRect cursorRectangle() const; - void setCursorRectangle(const QRect &cursorRectangle); - -protected: - void input_panel_get_input_panel_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; - -private: - Compositor *m_compositor; - QScopedPointer<QWaylandInputPanel> m_handle; - - Surface *m_focus; - bool m_inputPanelVisible; - QRect m_cursorRectangle; -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLINPUTPANEL_P_H diff --git a/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp b/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp deleted file mode 100644 index fdaf895ef..000000000 --- a/src/compositor/wayland_wrapper/qwlinputpanelsurface.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlinputpanelsurface_p.h" - -#include "qwloutput_p.h" -#include "qwlsurface_p.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -InputPanelSurface::InputPanelSurface(wl_client *client, int id, Surface *surface) - : QtWaylandServer::wl_input_panel_surface(client, id, 1) - , m_surface(surface) - , m_type(Invalid) - , m_output(0) - , m_position() -{ - surface->setInputPanelSurface(this); -} - -InputPanelSurface::Type InputPanelSurface::type() const -{ - return m_type; -} - -Output *InputPanelSurface::output() const -{ - return m_output; -} - -QtWaylandServer::wl_input_panel_surface::position InputPanelSurface::position() const -{ - return m_position; -} - -void InputPanelSurface::input_panel_surface_set_overlay_panel(Resource *) -{ - m_type = OverlayPanel; -} - -void InputPanelSurface::input_panel_surface_set_toplevel(Resource *, wl_resource *output_resource, uint32_t position) -{ - m_type = Toplevel; - OutputResource *output = static_cast<OutputResource *>(Output::Resource::fromResource(output_resource)); - m_output = static_cast<Output *>(output->output_object); - m_position = static_cast<wl_input_panel_surface::position>(position); -} - -QT_END_NAMESPACE - -} // namespace QtWayland diff --git a/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h b/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h deleted file mode 100644 index 37f2e0858..000000000 --- a/src/compositor/wayland_wrapper/qwlinputpanelsurface_p.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLINPUTPANELSURFACE_P_H -#define QTWAYLAND_QWLINPUTPANELSURFACE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/private/qwayland-server-input-method.h> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -class Output; -class Surface; - -class InputPanelSurface : public QtWaylandServer::wl_input_panel_surface -{ -public: - enum Type { - Invalid, - Toplevel, - OverlayPanel - }; - - InputPanelSurface(struct ::wl_client *client, int id, Surface *surface); - - Type type() const; - - Output *output() const; - wl_input_panel_surface::position position() const; - -protected: - void input_panel_surface_set_overlay_panel(Resource *resource) Q_DECL_OVERRIDE; - void input_panel_surface_set_toplevel(Resource *resource, wl_resource *output_resource, uint32_t position) Q_DECL_OVERRIDE; - -private: - Surface *m_surface; - - Type m_type; - - Output *m_output; - wl_input_panel_surface::position m_position; -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLINPUTPANELSURFACE_P_H diff --git a/src/compositor/wayland_wrapper/qwlkeyboard.cpp b/src/compositor/wayland_wrapper/qwlkeyboard.cpp deleted file mode 100644 index 7a5ed5f25..000000000 --- a/src/compositor/wayland_wrapper/qwlkeyboard.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlkeyboard_p.h" - -#include <QFile> -#include <QStandardPaths> - -#include "qwlcompositor_p.h" -#include "qwlsurface_p.h" - -#include <fcntl.h> -#include <unistd.h> -#ifndef QT_NO_WAYLAND_XKB -#include <sys/mman.h> -#include <sys/types.h> -#endif - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -Keyboard::Keyboard(Compositor *compositor, InputDevice *seat) - : QtWaylandServer::wl_keyboard() - , m_compositor(compositor) - , m_seat(seat) - , m_grab(this) - , m_focus() - , m_focusResource() - , m_keys() - , m_modsDepressed() - , m_modsLatched() - , m_modsLocked() - , m_group() - , m_pendingKeymap(false) -#ifndef QT_NO_WAYLAND_XKB - , m_keymap_fd(-1) - , m_state(0) -#endif -{ -#ifndef QT_NO_WAYLAND_XKB - initXKB(); -#endif - connect(&m_focusDestroyListener, &WlListener::fired, this, &Keyboard::focusDestroyed); -} - -Keyboard::~Keyboard() -{ -#ifndef QT_NO_WAYLAND_XKB - if (m_context) { - if (m_keymap_area) - munmap(m_keymap_area, m_keymap_size); - close(m_keymap_fd); - xkb_context_unref(m_context); - xkb_state_unref(m_state); - } -#endif -} - -KeyboardGrabber::~KeyboardGrabber() -{ -} - -void Keyboard::startGrab(KeyboardGrabber *grab) -{ - m_grab = grab; - m_grab->m_keyboard = this; - m_grab->focused(m_focus); -} - -void Keyboard::endGrab() -{ - m_grab = this; -} - -KeyboardGrabber *Keyboard::currentGrab() const -{ - return m_grab; -} - -void Keyboard::checkFocusResource(wl_keyboard::Resource *keyboardResource) -{ - if (!keyboardResource || !m_focus) - return; - - // this is already the current resource, do no send enter twice - if (m_focusResource == keyboardResource) - return; - - // check if new wl_keyboard resource is from the client owning the focus surface - struct ::wl_client *focusedClient = m_focus->resource()->client(); - if (focusedClient == keyboardResource->client()) { - sendEnter(m_focus, keyboardResource); - m_focusResource = keyboardResource; - } -} - -void Keyboard::sendEnter(Surface *surface, wl_keyboard::Resource *keyboardResource) -{ - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - send_modifiers(keyboardResource->handle, serial, m_modsDepressed, m_modsLatched, m_modsLocked, m_group); - send_enter(keyboardResource->handle, serial, surface->resource()->handle, QByteArray::fromRawData((char *)m_keys.data(), m_keys.size() * sizeof(uint32_t))); -} - -void Keyboard::focused(Surface *surface) -{ - if (m_focus != surface) { - if (m_focusResource) { - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - send_leave(m_focusResource->handle, serial, m_focus->resource()->handle); - } - m_focusDestroyListener.reset(); - if (surface) { - m_focusDestroyListener.listenForDestruction(surface->resource()->handle); - } - } - - Resource *resource = surface ? resourceMap().value(surface->resource()->client()) : 0; - - if (resource && (m_focus != surface || m_focusResource != resource)) { - sendEnter(surface, resource); - } - - m_focusResource = resource; - m_focus = surface; - Q_EMIT focusChanged(m_focus); -} - -void Keyboard::setFocus(Surface* surface) -{ - m_grab->focused(surface); -} - -void Keyboard::setKeymap(const QWaylandKeymap &keymap) -{ - m_keymap = keymap; - m_pendingKeymap = true; - - // If there is no key currently pressed, update right away the keymap - // Otherwise, delay the update when keys are released - // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html - if (m_keys.isEmpty()) { - updateKeymap(); - } -} - -void Keyboard::focusDestroyed(void *data) -{ - Q_UNUSED(data) - m_focusDestroyListener.reset(); - - m_focus = 0; - m_focusResource = 0; -} - -void Keyboard::sendKeyModifiers(wl_keyboard::Resource *resource, uint32_t serial) -{ - send_modifiers(resource->handle, serial, m_modsDepressed, m_modsLatched, m_modsLocked, m_group); -} - -void Keyboard::sendKeyPressEvent(uint code) -{ - sendKeyEvent(code, WL_KEYBOARD_KEY_STATE_PRESSED); -} - -void Keyboard::sendKeyReleaseEvent(uint code) -{ - sendKeyEvent(code, WL_KEYBOARD_KEY_STATE_RELEASED); -} - -Surface *Keyboard::focus() const -{ - return m_focus; -} - -QtWaylandServer::wl_keyboard::Resource *Keyboard::focusResource() const -{ - return m_focusResource; -} - -void Keyboard::keyboard_bind_resource(wl_keyboard::Resource *resource) -{ -#ifndef QT_NO_WAYLAND_XKB - if (m_context) { - send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - m_keymap_fd, m_keymap_size); - } - else -#endif - { - int null_fd = open("/dev/null", O_RDONLY); - send_keymap(resource->handle, 0 /* WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP */, - null_fd, 0); - close(null_fd); - } - - checkFocusResource(resource); -} - -void Keyboard::keyboard_destroy_resource(wl_keyboard::Resource *resource) -{ - if (m_focusResource == resource) - m_focusResource = 0; -} - -void Keyboard::keyboard_release(wl_keyboard::Resource *resource) -{ - wl_resource_destroy(resource->handle); -} - -void Keyboard::key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -{ - if (m_focusResource) { - send_key(m_focusResource->handle, serial, time, key, state); - } -} - -void Keyboard::keyEvent(uint code, uint32_t state) -{ - uint key = code - 8; - if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { - m_keys << key; - } else { - for (int i = 0; i < m_keys.size(); ++i) { - if (m_keys.at(i) == key) { - m_keys.remove(i); - } - } - } -} - -void Keyboard::sendKeyEvent(uint code, uint32_t state) -{ - uint32_t time = m_compositor->currentTimeMsecs(); - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - uint key = code - 8; - m_grab->key(serial, time, key, state); -} - -void Keyboard::modifiers(uint32_t serial, uint32_t mods_depressed, - uint32_t mods_latched, uint32_t mods_locked, uint32_t group) -{ - if (m_focusResource) { - send_modifiers(m_focusResource->handle, serial, mods_depressed, mods_latched, mods_locked, group); - } -} - -void Keyboard::updateModifierState(uint code, uint32_t state) -{ -#ifndef QT_NO_WAYLAND_XKB - if (!m_context) - return; - - xkb_state_update_key(m_state, code, state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); - - uint32_t modsDepressed = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_DEPRESSED); - uint32_t modsLatched = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_LATCHED); - uint32_t modsLocked = xkb_state_serialize_mods(m_state, (xkb_state_component)XKB_STATE_LOCKED); - uint32_t group = xkb_state_serialize_group(m_state, (xkb_state_component)XKB_STATE_EFFECTIVE); - - if (modsDepressed == m_modsDepressed - && modsLatched == m_modsLatched - && modsLocked == m_modsLocked - && group == m_group) - return; - - m_modsDepressed = modsDepressed; - m_modsLatched = modsLatched; - m_modsLocked = modsLocked; - m_group = group; - - m_grab->modifiers(wl_display_next_serial(m_compositor->wl_display()), m_modsDepressed, m_modsLatched, m_modsLocked, m_group); -#else - Q_UNUSED(code); - Q_UNUSED(state); -#endif -} - -void Keyboard::updateKeymap() -{ - // There must be no keys pressed when changing the keymap, - // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html - if (!m_pendingKeymap || !m_keys.isEmpty()) - return; - - m_pendingKeymap = false; -#ifndef QT_NO_WAYLAND_XKB - if (!m_context) - return; - - createXKBKeymap(); - foreach (Resource *res, resourceMap()) { - send_keymap(res->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, m_keymap_fd, m_keymap_size); - } - - xkb_state_update_mask(m_state, 0, m_modsLatched, m_modsLocked, 0, 0, 0); - if (m_focusResource) - sendKeyModifiers(m_focusResource, wl_display_next_serial(m_compositor->wl_display())); -#endif -} - -#ifndef QT_NO_WAYLAND_XKB -static int createAnonymousFile(size_t size) -{ - QString path = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); - if (path.isEmpty()) - return -1; - - QByteArray name = QFile::encodeName(path + QStringLiteral("/qtwayland-XXXXXX")); - - int fd = mkstemp(name.data()); - if (fd < 0) - return -1; - - long flags = fcntl(fd, F_GETFD); - if (flags == -1 || fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) { - close(fd); - fd = -1; - } - unlink(name.constData()); - - if (fd < 0) - return -1; - - if (ftruncate(fd, size) < 0) { - close(fd); - return -1; - } - - return fd; -} - -void Keyboard::initXKB() -{ - m_context = xkb_context_new(static_cast<xkb_context_flags>(0)); - if (!m_context) { - qWarning("Failed to create a XKB context: keymap will not be supported"); - return; - } - - createXKBKeymap(); -} - -void Keyboard::createXKBState(xkb_keymap *keymap) -{ - char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1); - if (!keymap_str) { - qWarning("Failed to compile global XKB keymap"); - return; - } - - m_keymap_size = strlen(keymap_str) + 1; - if (m_keymap_fd >= 0) - close(m_keymap_fd); - m_keymap_fd = createAnonymousFile(m_keymap_size); - if (m_keymap_fd < 0) { - qWarning("Failed to create anonymous file of size %lu", static_cast<unsigned long>(m_keymap_size)); - return; - } - - m_keymap_area = static_cast<char *>(mmap(0, m_keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_keymap_fd, 0)); - if (m_keymap_area == MAP_FAILED) { - close(m_keymap_fd); - m_keymap_fd = -1; - qWarning("Failed to map shared memory segment"); - return; - } - - strcpy(m_keymap_area, keymap_str); - free(keymap_str); - - if (m_state) - xkb_state_unref(m_state); - m_state = xkb_state_new(keymap); -} - -void Keyboard::createXKBKeymap() -{ - if (!m_context) - return; - - struct xkb_rule_names rule_names = { strdup(qPrintable(m_keymap.rules())), - strdup(qPrintable(m_keymap.model())), - strdup(qPrintable(m_keymap.layout())), - strdup(qPrintable(m_keymap.variant())), - strdup(qPrintable(m_keymap.options())) }; - struct xkb_keymap *keymap = xkb_keymap_new_from_names(m_context, &rule_names, static_cast<xkb_keymap_compile_flags>(0)); - - if (keymap) { - createXKBState(keymap); - xkb_keymap_unref(keymap); - } else { - qWarning("Failed to load the '%s' XKB keymap.", qPrintable(m_keymap.layout())); - } - - free((char *)rule_names.rules); - free((char *)rule_names.model); - free((char *)rule_names.layout); - free((char *)rule_names.variant); - free((char *)rule_names.options); -} -#endif - -} // namespace QtWayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlkeyboard_p.h b/src/compositor/wayland_wrapper/qwlkeyboard_p.h deleted file mode 100644 index 15185ed56..000000000 --- a/src/compositor/wayland_wrapper/qwlkeyboard_p.h +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLKEYBOARD_P_H -#define QTWAYLAND_QWLKEYBOARD_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/qwaylandinput.h> - -#include <QObject> -#include <QtCompositor/private/qwayland-server-wayland.h> - -#include <QtCore/QVector> - -#ifndef QT_NO_WAYLAND_XKB -#include <xkbcommon/xkbcommon.h> -#endif - -#include "qwllistener_p.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -class Compositor; -class InputDevice; -class Surface; -class Keyboard; - -class Q_COMPOSITOR_EXPORT KeyboardGrabber { - public: - virtual ~KeyboardGrabber(); - virtual void focused(Surface *surface) = 0; - virtual void key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state) = 0; - virtual void modifiers(uint32_t serial, uint32_t mods_depressed, - uint32_t mods_latched, uint32_t mods_locked, uint32_t group) = 0; - - Keyboard *m_keyboard; -}; - -class Q_COMPOSITOR_EXPORT Keyboard : public QObject, public QtWaylandServer::wl_keyboard, public KeyboardGrabber -{ - Q_OBJECT - -public: - Keyboard(Compositor *compositor, InputDevice *seat); - ~Keyboard(); - - void setFocus(Surface *surface); - void setKeymap(const QWaylandKeymap &keymap); - - void sendKeyModifiers(Resource *resource, uint32_t serial); - void sendKeyPressEvent(uint code); - void sendKeyReleaseEvent(uint code); - - Surface *focus() const; - Resource *focusResource() const; - - void focused(Surface* surface); - void key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state); - void modifiers(uint32_t serial, uint32_t mods_depressed, - uint32_t mods_latched, uint32_t mods_locked, uint32_t group); - - void keyEvent(uint code, uint32_t state); - void updateModifierState(uint code, uint32_t state); - void updateKeymap(); - - void startGrab(KeyboardGrabber *grab); - void endGrab(); - KeyboardGrabber *currentGrab() const; - -#ifndef QT_NO_WAYLAND_XKB - struct xkb_state *xkbState() const { return m_state; } - uint32_t xkbModsMask() const { return m_modsDepressed | m_modsLatched | m_modsLocked; } -#endif - -Q_SIGNALS: - void focusChanged(Surface *surface); - -protected: - void keyboard_bind_resource(Resource *resource); - void keyboard_destroy_resource(Resource *resource); - void keyboard_release(Resource *resource) Q_DECL_OVERRIDE; - -private: - void checkFocusResource(wl_keyboard::Resource *resource); - void sendEnter(Surface *surface, wl_keyboard::Resource *resource); - - void sendKeyEvent(uint code, uint32_t state); - void focusDestroyed(void *data); - -#ifndef QT_NO_WAYLAND_XKB - void initXKB(); - void createXKBKeymap(); - void createXKBState(xkb_keymap *keymap); -#endif - - Compositor *m_compositor; - InputDevice *m_seat; - - KeyboardGrabber* m_grab; - Surface *m_focus; - Resource *m_focusResource; - WlListener m_focusDestroyListener; - - QVector<uint32_t> m_keys; - uint32_t m_modsDepressed; - uint32_t m_modsLatched; - uint32_t m_modsLocked; - uint32_t m_group; - - QWaylandKeymap m_keymap; - bool m_pendingKeymap; -#ifndef QT_NO_WAYLAND_XKB - size_t m_keymap_size; - int m_keymap_fd; - char *m_keymap_area; - struct xkb_context *m_context; - struct xkb_state *m_state; -#endif -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLKEYBOARD_P_H diff --git a/src/compositor/wayland_wrapper/qwllistener.cpp b/src/compositor/wayland_wrapper/qwllistener.cpp deleted file mode 100644 index 5a3c0e576..000000000 --- a/src/compositor/wayland_wrapper/qwllistener.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwllistener_p.h" - -QT_BEGIN_NAMESPACE - -WlListener::WlListener() -{ - m_listener.parent = this; - m_listener.listener.notify = handler; - wl_list_init(&m_listener.listener.link); -} - -void WlListener::listenForDestruction(::wl_resource *resource) -{ - wl_resource_add_destroy_listener(resource, &m_listener.listener); -} - -void WlListener::reset() -{ - wl_list_remove(&m_listener.listener.link); - wl_list_init(&m_listener.listener.link); -} - -void WlListener::handler(wl_listener *listener, void *data) -{ - WlListener *that = reinterpret_cast<Listener *>(listener)->parent; - emit that->fired(data); -} - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwloutput.cpp b/src/compositor/wayland_wrapper/qwloutput.cpp deleted file mode 100644 index 0cbe166e2..000000000 --- a/src/compositor/wayland_wrapper/qwloutput.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwloutput_p.h" - -#include "qwlcompositor_p.h" -#include "qwlsurface_p.h" - -#include <QtGui/QWindow> -#include <QRect> -#include <QtCompositor/QWaylandSurface> -#include <QtCompositor/QWaylandOutput> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -static QtWaylandServer::wl_output::subpixel toWlSubpixel(const QWaylandOutput::Subpixel &value) -{ - switch (value) { - case QWaylandOutput::SubpixelUnknown: - return QtWaylandServer::wl_output::subpixel_unknown; - case QWaylandOutput::SubpixelNone: - return QtWaylandServer::wl_output::subpixel_none; - case QWaylandOutput::SubpixelHorizontalRgb: - return QtWaylandServer::wl_output::subpixel_horizontal_rgb; - case QWaylandOutput::SubpixelHorizontalBgr: - return QtWaylandServer::wl_output::subpixel_horizontal_bgr; - case QWaylandOutput::SubpixelVerticalRgb: - return QtWaylandServer::wl_output::subpixel_vertical_rgb; - case QWaylandOutput::SubpixelVerticalBgr: - return QtWaylandServer::wl_output::subpixel_vertical_bgr; - default: - break; - } - - return QtWaylandServer::wl_output::subpixel_unknown; -} - -static QtWaylandServer::wl_output::transform toWlTransform(const QWaylandOutput::Transform &value) -{ - switch (value) { - case QWaylandOutput::Transform90: - return QtWaylandServer::wl_output::transform_90; - case QWaylandOutput::Transform180: - return QtWaylandServer::wl_output::transform_180; - case QWaylandOutput::Transform270: - return QtWaylandServer::wl_output::transform_270; - case QWaylandOutput::TransformFlipped: - return QtWaylandServer::wl_output::transform_flipped; - case QWaylandOutput::TransformFlipped90: - return QtWaylandServer::wl_output::transform_flipped_90; - case QWaylandOutput::TransformFlipped180: - return QtWaylandServer::wl_output::transform_flipped_180; - case QWaylandOutput::TransformFlipped270: - return QtWaylandServer::wl_output::transform_flipped_270; - default: - break; - } - - return QtWaylandServer::wl_output::transform_normal; -} - -Output::Output(Compositor *compositor, QWindow *window) - : QtWaylandServer::wl_output(compositor->wl_display(), 2) - , m_compositor(compositor) - , m_window(window) - , m_output(Q_NULLPTR) - , m_position(QPoint()) - , m_availableGeometry(QRect()) - , m_physicalSize(QSize()) - , m_subpixel(QWaylandOutput::SubpixelUnknown) - , m_transform(QWaylandOutput::TransformNormal) - , m_scaleFactor(1) -{ - m_mode.size = window ? window->size() : QSize(); - m_mode.refreshRate = 60; - - qRegisterMetaType<QWaylandOutput::Mode>("WaylandOutput::Mode"); -} - -void Output::output_bind_resource(Resource *resource) -{ - send_geometry(resource->handle, - m_position.x(), m_position.y(), - m_physicalSize.width(), m_physicalSize.height(), - toWlSubpixel(m_subpixel), m_manufacturer, m_model, - toWlTransform(m_transform)); - - send_mode(resource->handle, mode_current | mode_preferred, - m_mode.size.width(), m_mode.size.height(), - m_mode.refreshRate); - - if (resource->version() >= 2) { - send_scale(resource->handle, m_scaleFactor); - send_done(resource->handle); - } -} - -void Output::setManufacturer(const QString &manufacturer) -{ - m_manufacturer = manufacturer; -} - -void Output::setModel(const QString &model) -{ - m_model = model; -} - -void Output::setPosition(const QPoint &position) -{ - if (m_position == position) - return; - - m_position = position; - - sendGeometryInfo(); -} - -void Output::setMode(const QWaylandOutput::Mode &mode) -{ - if (m_mode.size == mode.size && m_mode.refreshRate == mode.refreshRate) - return; - - m_mode = mode; - - Q_FOREACH (Resource *resource, resourceMap().values()) { - send_mode(resource->handle, mode_current, - m_mode.size.width(), m_mode.size.height(), - m_mode.refreshRate * 1000); - if (resource->version() >= 2) - send_done(resource->handle); - } -} - -QRect Output::geometry() const -{ - return QRect(m_position, m_mode.size); -} - -void Output::setGeometry(const QRect &geometry) -{ - if (m_position == geometry.topLeft() && m_mode.size == geometry.size()) - return; - - m_position = geometry.topLeft(); - m_mode.size = geometry.size(); - - Q_FOREACH (Resource *resource, resourceMap().values()) { - send_geometry(resource->handle, - m_position.x(), m_position.y(), - m_physicalSize.width(), m_physicalSize.height(), - toWlSubpixel(m_subpixel), m_manufacturer, m_model, - toWlTransform(m_transform)); - send_mode(resource->handle, mode_current, - m_mode.size.width(), m_mode.size.height(), - m_mode.refreshRate * 1000); - if (resource->version() >= 2) - send_done(resource->handle); - } -} - -void Output::setAvailableGeometry(const QRect &availableGeometry) -{ - m_availableGeometry = availableGeometry; -} - -void Output::setPhysicalSize(const QSize &physicalSize) -{ - if (m_physicalSize == physicalSize) - return; - - m_physicalSize = physicalSize; - - sendGeometryInfo(); -} - -void Output::setSubpixel(const QWaylandOutput::Subpixel &subpixel) -{ - if (m_subpixel == subpixel) - return; - - m_subpixel = subpixel; - - sendGeometryInfo(); -} - -void Output::setTransform(const QWaylandOutput::Transform &transform) -{ - if (m_transform == transform) - return; - - m_transform = transform; - - sendGeometryInfo(); -} - -void Output::setScaleFactor(int scale) -{ - if (m_scaleFactor == scale) - return; - - m_scaleFactor = scale; - - Q_FOREACH (Resource *resource, resourceMap().values()) { - if (resource->version() >= 2) { - send_scale(resource->handle, m_scaleFactor); - send_done(resource->handle); - } - } -} - -OutputResource *Output::outputForClient(wl_client *client) const -{ - return static_cast<OutputResource *>(resourceMap().value(client)); -} - -void Output::sendGeometryInfo() -{ - Q_FOREACH (Resource *resource, resourceMap().values()) { - send_geometry(resource->handle, - m_position.x(), m_position.x(), - m_physicalSize.width(), m_physicalSize.height(), - toWlSubpixel(m_subpixel), m_manufacturer, m_model, - toWlTransform(m_transform)); - if (resource->version() >= 2) - send_done(resource->handle); - } -} - -} // namespace Wayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwloutput_p.h b/src/compositor/wayland_wrapper/qwloutput_p.h deleted file mode 100644 index 3efd49fb6..000000000 --- a/src/compositor/wayland_wrapper/qwloutput_p.h +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WL_OUTPUT_H -#define WL_OUTPUT_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> - -#include <QtCore/QRect> -#include <QtCore/QList> - -#include <QtCompositor/private/qwayland-server-wayland.h> -#include <QtCompositor/qwaylandoutput.h> - -QT_BEGIN_NAMESPACE - -class QWindow; - -namespace QtWayland { - -class Compositor; - -struct OutputResource : public QtWaylandServer::wl_output::Resource -{ - OutputResource() {} -}; - -class Output : public QtWaylandServer::wl_output -{ -public: - explicit Output(Compositor *compositor, QWindow *window = 0); - - Compositor *compositor() const { return m_compositor; } - - QWaylandOutput *output() const { return m_output; } - - QString manufacturer() const { return m_manufacturer; } - void setManufacturer(const QString &manufacturer); - - QString model() const { return m_model; } - void setModel(const QString &model); - - QPoint position() const { return m_position; } - void setPosition(const QPoint &position); - - QRect geometry() const; - void setGeometry(const QRect &geometry); - - QWaylandOutput::Mode mode() const { return m_mode; } - void setMode(const QWaylandOutput::Mode &mode); - - QRect availableGeometry() const { return m_availableGeometry; } - void setAvailableGeometry(const QRect &availableGeometry); - - QSize physicalSize() const { return m_physicalSize; } - void setPhysicalSize(const QSize &physicalSize); - - QWaylandOutput::Subpixel subpixel() const { return m_subpixel; } - void setSubpixel(const QWaylandOutput::Subpixel &subpixel); - - QWaylandOutput::Transform transform() const { return m_transform; } - void setTransform(const QWaylandOutput::Transform &transform); - - int scaleFactor() const { return m_scaleFactor; } - void setScaleFactor(int scale); - - QWindow *window() const { return m_window; } - - OutputResource *outputForClient(struct wl_client *client) const; - - QWaylandOutput *waylandOutput() const { return m_output; } - - void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE; - Resource *output_allocate() Q_DECL_OVERRIDE { return new OutputResource; } - -private: - friend class QT_PREPEND_NAMESPACE(QWaylandOutput); - - Compositor *m_compositor; - QWindow *m_window; - QWaylandOutput *m_output; - QString m_manufacturer; - QString m_model; - QPoint m_position; - QWaylandOutput::Mode m_mode; - QRect m_availableGeometry; - QSize m_physicalSize; - QWaylandOutput::Subpixel m_subpixel; - QWaylandOutput::Transform m_transform; - int m_scaleFactor; - QList<QWaylandSurface *> m_surfaces; - - void sendGeometryInfo(); -}; - -} - -QT_END_NAMESPACE - -#endif //WL_OUTPUT_H diff --git a/src/compositor/wayland_wrapper/qwlpointer.cpp b/src/compositor/wayland_wrapper/qwlpointer.cpp deleted file mode 100644 index 10c2d1037..000000000 --- a/src/compositor/wayland_wrapper/qwlpointer.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlpointer_p.h" - -#include "qwlcompositor_p.h" -#include "qwlinputdevice_p.h" -#include "qwlkeyboard_p.h" -#include "qwlsurface_p.h" -#include "qwaylandcompositor.h" -#include "qwaylandsurfaceview.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -using QtWaylandServer::wl_keyboard; - -static uint32_t toWaylandButton(Qt::MouseButton button) -{ -#ifndef BTN_LEFT - uint32_t BTN_LEFT = 0x110; -#endif - // the range of valid buttons (evdev module) is from 0x110 - // through 0x11f. 0x120 is the first 'Joystick' button. - switch (button) { - case Qt::LeftButton: return BTN_LEFT; - case Qt::RightButton: return uint32_t(0x111); - case Qt::MiddleButton: return uint32_t(0x112); - case Qt::ExtraButton1: return uint32_t(0x113); // AKA Qt::BackButton, Qt::XButton1 - case Qt::ExtraButton2: return uint32_t(0x114); // AKA Qt::ForwardButton, Qt::XButton2 - case Qt::ExtraButton3: return uint32_t(0x115); - case Qt::ExtraButton4: return uint32_t(0x116); - case Qt::ExtraButton5: return uint32_t(0x117); - case Qt::ExtraButton6: return uint32_t(0x118); - case Qt::ExtraButton7: return uint32_t(0x119); - case Qt::ExtraButton8: return uint32_t(0x11a); - case Qt::ExtraButton9: return uint32_t(0x11b); - case Qt::ExtraButton10: return uint32_t(0x11c); - case Qt::ExtraButton11: return uint32_t(0x11d); - case Qt::ExtraButton12: return uint32_t(0x11e); - case Qt::ExtraButton13: return uint32_t(0x11f); - // default should not occur; but if it does, then return Wayland's highest possible button number. - default: return uint32_t(0x11f); - } -} - -Pointer::Pointer(Compositor *compositor, InputDevice *seat) - : wl_pointer() - , PointerGrabber() - , m_compositor(compositor) - , m_seat(seat) - , m_grab(this) - , m_grabButton() - , m_grabTime() - , m_grabSerial() - , m_position(100, 100) - , m_focus() - , m_focusResource() - , m_current() - , m_currentPoint() - , m_buttonCount() -{ - connect(&m_focusDestroyListener, &WlListener::fired, this, &Pointer::focusDestroyed); -} - -void Pointer::setFocus(QWaylandSurfaceView *surface, const QPointF &position) -{ - if (m_focusResource && m_focus != surface) { - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - send_leave(m_focusResource->handle, serial, m_focus->surface()->handle()->resource()->handle); - m_focusDestroyListener.reset(); - } - - Resource *resource = surface ? resourceMap().value(surface->surface()->handle()->resource()->client()) : 0; - - if (resource && (m_focus != surface || resource != m_focusResource)) { - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - Keyboard *keyboard = m_seat->keyboardDevice(); - if (keyboard) { - wl_keyboard::Resource *kr = keyboard->resourceMap().value(surface->surface()->handle()->resource()->client()); - if (kr) - keyboard->sendKeyModifiers(kr, serial); - } - send_enter(resource->handle, serial, surface->surface()->handle()->resource()->handle, - wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); - - m_focusDestroyListener.listenForDestruction(surface->surface()->handle()->resource()->handle); - } - - m_focusResource = resource; - m_focus = surface; -} - -void Pointer::focusDestroyed(void *data) -{ - Q_UNUSED(data) - m_focusDestroyListener.reset(); - - m_focus = 0; - m_focusResource = 0; - setMouseFocus(0, QPointF(), QPointF()); -} - -void Pointer::startGrab(PointerGrabber *grab) -{ - m_grab = grab; - grab->m_pointer = this; - - if (m_current) - grab->focus(); -} - -void Pointer::endGrab() -{ - m_grab = this; - m_grab->focus(); -} - -void Pointer::setCurrent(QWaylandSurfaceView *surface, const QPointF &point) -{ - m_current = surface; - m_currentPoint = point; -} - -bool Pointer::buttonPressed() const -{ - return m_buttonCount > 0; -} - -PointerGrabber *Pointer::currentGrab() const -{ - return m_grab; -} - -Qt::MouseButton Pointer::grabButton() const -{ - return m_grabButton; -} - -uint32_t Pointer::grabTime() const -{ - return m_grabTime; -} - -uint32_t Pointer::grabSerial() const -{ - return m_grabSerial; -} - -QWaylandSurfaceView *Pointer::focusSurface() const -{ - return m_focus; -} - -QWaylandSurfaceView *Pointer::current() const -{ - return m_current; -} - -QPointF Pointer::position() const -{ - return m_position; -} - -QPointF Pointer::currentPosition() const -{ - return m_currentPoint; -} - -QtWaylandServer::wl_pointer::Resource *Pointer::focusResource() const -{ - return m_focusResource; -} - -void Pointer::pointer_destroy_resource(wl_pointer::Resource *resource) -{ - if (m_focusResource == resource) - m_focusResource = 0; -} - -void Pointer::pointer_release(wl_pointer::Resource *resource) -{ - wl_resource_destroy(resource->handle); -} - -void Pointer::setMouseFocus(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos) -{ - m_position = globalPos; - - m_current = surface; - m_currentPoint = localPos; - - m_grab->focus(); -} - -void Pointer::sendButton(uint32_t time, Qt::MouseButton button, uint32_t state) -{ - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - send_button(m_focusResource->handle, serial, time, toWaylandButton(button), state); -} - -void Pointer::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) -{ - sendMouseMoveEvent(localPos, globalPos); - uint32_t time = m_compositor->currentTimeMsecs(); - if (m_buttonCount == 0) { - m_grabButton = button; - m_grabTime = time; - } - m_buttonCount++; - m_grab->button(time, button, WL_POINTER_BUTTON_STATE_PRESSED); - - if (m_buttonCount == 1) - m_grabSerial = wl_display_get_serial(m_compositor->wl_display()); -} - -void Pointer::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos) -{ - sendMouseMoveEvent(localPos, globalPos); - uint32_t time = m_compositor->currentTimeMsecs(); - m_buttonCount--; - m_grab->button(time, button, WL_POINTER_BUTTON_STATE_RELEASED); - - if (m_buttonCount == 1) - m_grabSerial = wl_display_get_serial(m_compositor->wl_display()); -} - -void Pointer::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos) -{ - uint32_t time = m_compositor->currentTimeMsecs(); - - m_position = globalPos; - m_currentPoint = localPos; - - m_grab->motion(time); -} - -void Pointer::sendMouseWheelEvent(Qt::Orientation orientation, int delta) -{ - if (!m_focusResource) - return; - - uint32_t time = m_compositor->currentTimeMsecs(); - uint32_t axis = orientation == Qt::Horizontal ? WL_POINTER_AXIS_HORIZONTAL_SCROLL - : WL_POINTER_AXIS_VERTICAL_SCROLL; - send_axis(m_focusResource->handle, time, axis, wl_fixed_from_int(-delta / 12)); -} - -void Pointer::focus() -{ - if (buttonPressed()) - return; - - setFocus(m_current, m_currentPoint); -} - -void Pointer::motion(uint32_t time) -{ - if (m_focusResource) - send_motion(m_focusResource->handle, time, - wl_fixed_from_double(m_currentPoint.x()), - wl_fixed_from_double(m_currentPoint.y())); - -} - -void Pointer::button(uint32_t time, Qt::MouseButton button, uint32_t state) -{ - if (m_focusResource) { - sendButton(time, button, state); - } - - if (!buttonPressed() && state == WL_POINTER_BUTTON_STATE_RELEASED) - setFocus(m_current, m_currentPoint); -} - -void Pointer::pointer_set_cursor(wl_pointer::Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) -{ - Q_UNUSED(resource); - Q_UNUSED(serial); - - if (!surface) { - m_compositor->waylandCompositor()->setCursorSurface(NULL, 0, 0); - return; - } - - Surface *s = Surface::fromResource(surface); - s->setCursorSurface(true); - m_compositor->waylandCompositor()->setCursorSurface(s->waylandSurface(), hotspot_x, hotspot_y); -} - -PointerGrabber::~PointerGrabber() -{ -} - -} // namespace QtWayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlpointer_p.h b/src/compositor/wayland_wrapper/qwlpointer_p.h deleted file mode 100644 index b50350d8b..000000000 --- a/src/compositor/wayland_wrapper/qwlpointer_p.h +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLPOINTER_P_H -#define QTWAYLAND_QWLPOINTER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> - -#include <QtCore/QList> -#include <QtCore/QPoint> -#include <QtCore/QObject> - -#include <QtCompositor/private/qwayland-server-wayland.h> - -#include <stdint.h> - -#include "qwllistener_p.h" - -QT_BEGIN_NAMESPACE - -class QWaylandSurfaceView; - -namespace QtWayland { - -class Compositor; -class InputDevice; -class Pointer; -class Surface; - -class Q_COMPOSITOR_EXPORT PointerGrabber { -public: - virtual ~PointerGrabber(); - - virtual void focus() = 0; - virtual void motion(uint32_t time) = 0; - virtual void button(uint32_t time, Qt::MouseButton button, uint32_t state) = 0; - - Pointer *m_pointer; -}; - -class Q_COMPOSITOR_EXPORT Pointer : public QObject, public QtWaylandServer::wl_pointer, public PointerGrabber -{ -public: - Pointer(Compositor *compositor, InputDevice *seat); - - void setFocus(QWaylandSurfaceView *surface, const QPointF &position); - - void startGrab(PointerGrabber *currentGrab); - void endGrab(); - PointerGrabber *currentGrab() const; - Qt::MouseButton grabButton() const; - uint32_t grabTime() const; - uint32_t grabSerial() const; - - void setCurrent(QWaylandSurfaceView *surface, const QPointF &point); - void setMouseFocus(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos); - - void sendButton(uint32_t time, Qt::MouseButton button, uint32_t state); - - void sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos); - void sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos); - void sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos); - void sendMouseWheelEvent(Qt::Orientation orientation, int delta); - - QWaylandSurfaceView *focusSurface() const; - QWaylandSurfaceView *current() const; - QPointF position() const; - QPointF currentPosition() const; - Resource *focusResource() const; - - bool buttonPressed() const; - - void focus() Q_DECL_OVERRIDE; - void motion(uint32_t time) Q_DECL_OVERRIDE; - void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; - -protected: - void pointer_set_cursor(Resource *resource, uint32_t serial, wl_resource *surface, int32_t hotspot_x, int32_t hotspot_y) Q_DECL_OVERRIDE; - void pointer_release(Resource *resource) Q_DECL_OVERRIDE; - void pointer_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - -private: - void focusDestroyed(void *data); - - Compositor *m_compositor; - InputDevice *m_seat; - - PointerGrabber *m_grab; - Qt::MouseButton m_grabButton; - uint32_t m_grabTime; - uint32_t m_grabSerial; - - QPointF m_position; - - QWaylandSurfaceView *m_focus; - Resource *m_focusResource; - - QWaylandSurfaceView *m_current; - QPointF m_currentPoint; - - int m_buttonCount; - - WlListener m_focusDestroyListener; -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLPOINTER_P_H diff --git a/src/compositor/wayland_wrapper/qwlqtkey.cpp b/src/compositor/wayland_wrapper/qwlqtkey.cpp deleted file mode 100644 index 1eb6c2f1b..000000000 --- a/src/compositor/wayland_wrapper/qwlqtkey.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlqtkey_p.h" -#include "qwlsurface_p.h" -#include <QKeyEvent> -#include <QWindow> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -QtKeyExtensionGlobal::QtKeyExtensionGlobal(Compositor *compositor) - : QtWaylandServer::qt_key_extension(compositor->wl_display(), 2) - , m_compositor(compositor) -{ -} - -bool QtKeyExtensionGlobal::postQtKeyEvent(QKeyEvent *event, Surface *surface) -{ - uint32_t time = m_compositor->currentTimeMsecs(); - - Resource *target = surface ? resourceMap().value(surface->resource()->client()) : 0; - - if (target) { - send_qtkey(target->handle, - surface ? surface->resource()->handle : 0, - time, event->type(), event->key(), event->modifiers(), - event->nativeScanCode(), - event->nativeVirtualKey(), - event->nativeModifiers(), - event->text(), - event->isAutoRepeat(), - event->count()); - - return true; - } - - return false; -} - -} - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlqtkey_p.h b/src/compositor/wayland_wrapper/qwlqtkey_p.h deleted file mode 100644 index 938fa0b84..000000000 --- a/src/compositor/wayland_wrapper/qwlqtkey_p.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WLQTKEY_H -#define WLQTKEY_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qwlcompositor_p.h> - -#include "wayland-util.h" - -#include <QtCompositor/private/qwayland-server-qtkey-extension.h> - -QT_BEGIN_NAMESPACE - -class Compositor; -class Surface; -class QKeyEvent; - -namespace QtWayland { - -class QtKeyExtensionGlobal : public QtWaylandServer::qt_key_extension -{ -public: - QtKeyExtensionGlobal(Compositor *compositor); - - bool postQtKeyEvent(QKeyEvent *event, Surface *surface); - -private: - Compositor *m_compositor; -}; - -} - -QT_END_NAMESPACE - -#endif // WLQTKEY_H diff --git a/src/compositor/wayland_wrapper/qwlqttouch_p.h b/src/compositor/wayland_wrapper/qwlqttouch_p.h deleted file mode 100644 index 003f783dc..000000000 --- a/src/compositor/wayland_wrapper/qwlqttouch_p.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WLTOUCH_H -#define WLTOUCH_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qwlcompositor_p.h> -#include <QtCompositor/private/qwayland-server-touch-extension.h> -#include "wayland-util.h" - -QT_BEGIN_NAMESPACE - -class Compositor; -class Surface; -class QTouchEvent; -class QWaylandSurfaceView; - -namespace QtWayland { - -class TouchExtensionGlobal : public QtWaylandServer::qt_touch_extension -{ -public: - TouchExtensionGlobal(Compositor *compositor); - ~TouchExtensionGlobal(); - - bool postTouchEvent(QTouchEvent *event, QWaylandSurfaceView *view); - - void setFlags(int flags) { m_flags = flags; } - -protected: - void touch_extension_bind_resource(Resource *resource) Q_DECL_OVERRIDE; - void touch_extension_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - -private: - Compositor *m_compositor; - int m_flags; - QList<Resource *> m_resources; - QVector<float> m_posData; -}; - -} - -QT_END_NAMESPACE - -#endif // WLTOUCH_H diff --git a/src/compositor/wayland_wrapper/qwlregion.cpp b/src/compositor/wayland_wrapper/qwlregion.cpp index 03829df9a..9f55980e8 100644 --- a/src/compositor/wayland_wrapper/qwlregion.cpp +++ b/src/compositor/wayland_wrapper/qwlregion.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -40,8 +36,6 @@ #include "qwlregion_p.h" -#include "qwlcompositor_p.h" - QT_BEGIN_NAMESPACE namespace QtWayland { diff --git a/src/compositor/wayland_wrapper/qwlregion_p.h b/src/compositor/wayland_wrapper/qwlregion_p.h index 4df39602b..ca14c7a51 100644 --- a/src/compositor/wayland_wrapper/qwlregion_p.h +++ b/src/compositor/wayland_wrapper/qwlregion_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -52,18 +48,18 @@ // We mean it. // -#include <QtCompositor/qwaylandexport.h> +#include <QtWaylandCompositor/qwaylandexport.h> #include <QRegion> #include <wayland-util.h> -#include <QtCompositor/private/qwayland-server-wayland.h> +#include <QtWaylandCompositor/private/qwayland-server-wayland.h> QT_BEGIN_NAMESPACE namespace QtWayland { -class Q_COMPOSITOR_EXPORT Region : public QtWaylandServer::wl_region +class Q_WAYLAND_COMPOSITOR_EXPORT Region : public QtWaylandServer::wl_region { public: Region(struct wl_client *client, uint32_t id); diff --git a/src/compositor/wayland_wrapper/qwlshellsurface.cpp b/src/compositor/wayland_wrapper/qwlshellsurface.cpp deleted file mode 100644 index b2725462b..000000000 --- a/src/compositor/wayland_wrapper/qwlshellsurface.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlshellsurface_p.h" - -#include "qwlcompositor_p.h" -#include "qwlsurface_p.h" -#include "qwloutput_p.h" -#include "qwlinputdevice_p.h" -#include "qwlsubsurface_p.h" -#include "qwlpointer_p.h" -#include "qwlextendedsurface_p.h" - -#include "qwaylandoutput.h" -#include "qwaylandsurfaceview.h" - -#include <QtCore/qglobal.h> -#include <QtCore/QDebug> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -Shell::Shell() -{ -} - -const wl_interface *Shell::interface() const -{ - return &wl_shell_interface; -} - -void Shell::bind(struct wl_client *client, uint32_t version, uint32_t id) -{ - add(client, id, version); -} - -ShellSurfacePopupGrabber *Shell::getPopupGrabber(InputDevice *input) -{ - if (!m_popupGrabber.contains(input)) - m_popupGrabber.insert(input, new ShellSurfacePopupGrabber(input)); - - return m_popupGrabber.value(input); -} - -void Shell::shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface_res) -{ - Surface *surface = Surface::fromResource(surface_res); - new ShellSurface(this, resource->client(), id, surface); -} - - - -ShellSurface::ShellSurface(Shell *shell, wl_client *client, uint32_t id, Surface *surface) - : QWaylandSurfaceInterface(surface->waylandSurface()) - , wl_shell_surface(client, id, 1) - , m_shell(shell) - , m_surface(surface) - , m_resizeGrabber(0) - , m_moveGrabber(0) - , m_popupGrabber(0) - , m_popupSerial() -{ - m_view = surface->compositor()->waylandCompositor()->createView(surface->waylandSurface()); - connect(surface->waylandSurface(), &QWaylandSurface::configure, this, &ShellSurface::configure); - connect(surface->waylandSurface(), &QWaylandSurface::mapped, this, &ShellSurface::mapped); -} - -ShellSurface::~ShellSurface() -{ - delete m_view; -} - -void ShellSurface::sendConfigure(uint32_t edges, int32_t width, int32_t height) -{ - send_configure(edges, width, height); -} - -void ShellSurface::ping(uint32_t serial) -{ - m_pings.insert(serial); - send_ping(serial); -} - -void ShellSurface::adjustPosInResize() -{ - if (m_surface->transientParent()) - return; - if (!m_resizeGrabber || !(m_resizeGrabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP_LEFT)) - return; - - int bottomLeftX = m_resizeGrabber->point.x() + m_resizeGrabber->width; - int bottomLeftY = m_resizeGrabber->point.y() + m_resizeGrabber->height; - qreal x = m_view->pos().x(); - qreal y = m_view->pos().y(); - if (m_resizeGrabber->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP) - y = bottomLeftY - m_view->surface()->size().height(); - if (m_resizeGrabber->resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT) - x = bottomLeftX - m_view->surface()->size().width(); - QPointF newPos(x,y); - m_view->setPos(newPos); -} - -void ShellSurface::resetResizeGrabber() -{ - m_resizeGrabber = 0; -} - -void ShellSurface::resetMoveGrabber() -{ - m_moveGrabber = 0; -} - -void ShellSurface::setOffset(const QPointF &offset) -{ - m_surface->setTransientOffset(offset.x(), offset.y()); -} - -void ShellSurface::configure(bool hasBuffer) -{ - m_surface->setMapped(hasBuffer); -} - -bool ShellSurface::runOperation(QWaylandSurfaceOp *op) -{ - switch (op->type()) { - case QWaylandSurfaceOp::Ping: - ping(static_cast<QWaylandSurfacePingOp *>(op)->serial()); - return true; - case QWaylandSurfaceOp::Resize: - requestSize(static_cast<QWaylandSurfaceResizeOp *>(op)->size()); - return true; - default: - break; - } - return false; -} - -void ShellSurface::mapped() -{ - if (m_surface->waylandSurface()->windowType() == QWaylandSurface::Popup) { - if (m_surface->mapped() && m_popupGrabber->grabSerial() == m_popupSerial) { - m_popupGrabber->addPopup(this); - } else { - send_popup_done(); - m_popupGrabber->setClient(0); - } - } -} - -void ShellSurface::requestSize(const QSize &size) -{ - send_configure(WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT, size.width(), size.height()); -} - -void ShellSurface::shell_surface_destroy_resource(Resource *) -{ - if (m_popupGrabber) - m_popupGrabber->removePopup(this); - - delete this; -} - -void ShellSurface::shell_surface_move(Resource *resource, - struct wl_resource *input_device_super, - uint32_t time) -{ - Q_UNUSED(resource); - Q_UNUSED(time); - - if (m_resizeGrabber || m_moveGrabber) { - qDebug() << "invalid state"; - return; - } - - InputDevice *input_device = InputDevice::fromSeatResource(input_device_super); - Pointer *pointer = input_device->pointerDevice(); - - m_moveGrabber = new ShellSurfaceMoveGrabber(this, pointer->position() - m_view->pos()); - - pointer->startGrab(m_moveGrabber); -} - -void ShellSurface::shell_surface_resize(Resource *resource, - struct wl_resource *input_device_super, - uint32_t time, - uint32_t edges) -{ - Q_UNUSED(resource); - Q_UNUSED(time); - Q_UNUSED(edges); - - if (m_moveGrabber || m_resizeGrabber) { - qDebug() << "invalid state2"; - return; - } - - m_resizeGrabber = new ShellSurfaceResizeGrabber(this); - - InputDevice *input_device = InputDevice::fromSeatResource(input_device_super); - Pointer *pointer = input_device->pointerDevice(); - - m_resizeGrabber->point = pointer->position(); - m_resizeGrabber->resize_edges = static_cast<wl_shell_surface_resize>(edges); - m_resizeGrabber->width = m_view->surface()->size().width(); - m_resizeGrabber->height = m_view->surface()->size().height(); - - pointer->startGrab(m_resizeGrabber); -} - -void ShellSurface::shell_surface_set_toplevel(Resource *resource) -{ - Q_UNUSED(resource); - m_surface->setTransientParent(0); - m_surface->setTransientOffset(0, 0); - - setSurfaceType(QWaylandSurface::Toplevel); - - m_surface->setVisibility(QWindow::Windowed); -} - -void ShellSurface::shell_surface_set_transient(Resource *resource, - struct wl_resource *parent_surface_resource, - int x, - int y, - uint32_t flags) -{ - - Q_UNUSED(resource); - Q_UNUSED(flags); - Surface *parent_surface = Surface::fromResource(parent_surface_resource); - m_surface->setTransientParent(parent_surface); - m_surface->setTransientOffset(x, y); - if (flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE) - m_surface->setTransientInactive(true); - - setSurfaceType(QWaylandSurface::Transient); - - m_surface->setVisibility(QWindow::AutomaticVisibility); -} - -void ShellSurface::shell_surface_set_fullscreen(Resource *resource, - uint32_t method, - uint32_t framerate, - struct wl_resource *output_resource) -{ - Q_UNUSED(resource); - Q_UNUSED(method); - Q_UNUSED(framerate); - - QWaylandOutput *output = output_resource - ? QWaylandOutput::fromResource(output_resource) - : Q_NULLPTR; - if (!output) { - // Look for an output that can contain this surface - Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->outputs()) { - if (curOutput->geometry().size().width() >= m_surface->size().width() && - curOutput->geometry().size().height() >= m_surface->size().height()) { - output = curOutput; - break; - } - } - } - if (!output) { - qWarning() << "Unable to resize surface full screen, cannot determine output"; - return; - } - QSize outputSize = output->geometry().size(); - - m_view->setPos(output->geometry().topLeft()); - send_configure(resize_bottom_right, outputSize.width(), outputSize.height()); - - m_surface->setVisibility(QWindow::FullScreen); -} - -void ShellSurface::shell_surface_set_popup(Resource *resource, wl_resource *input_device, uint32_t serial, wl_resource *parent, int32_t x, int32_t y, uint32_t flags) -{ - Q_UNUSED(resource); - Q_UNUSED(input_device); - Q_UNUSED(flags); - - InputDevice *input = InputDevice::fromSeatResource(input_device); - m_popupGrabber = m_shell->getPopupGrabber(input); - - m_popupSerial = serial; - m_surface->setTransientParent(Surface::fromResource(parent)); - m_surface->setTransientOffset(x, y); - - setSurfaceType(QWaylandSurface::Popup); - - m_surface->setVisibility(QWindow::AutomaticVisibility); -} - -void ShellSurface::shell_surface_set_maximized(Resource *resource, - struct wl_resource *output_resource) -{ - Q_UNUSED(resource); - - QWaylandOutput *output = output_resource - ? QWaylandOutput::fromResource(output_resource) - : Q_NULLPTR; - if (!output) { - // Look for an output that can contain this surface - Q_FOREACH (QWaylandOutput *curOutput, m_surface->compositor()->outputs()) { - if (curOutput->geometry().size().width() >= m_surface->size().width() && - curOutput->geometry().size().height() >= m_surface->size().height()) { - output = curOutput; - break; - } - } - } - if (!output) { - qWarning() << "Unable to maximize surface, cannot determine output"; - return; - } - QSize outputSize = output->availableGeometry().size(); - - m_view->setPos(output->availableGeometry().topLeft()); - send_configure(resize_bottom_right, outputSize.width(), outputSize.height()); - - m_surface->setVisibility(QWindow::Maximized); -} - -void ShellSurface::shell_surface_pong(Resource *resource, - uint32_t serial) -{ - Q_UNUSED(resource); - if (m_pings.remove(serial)) - emit m_surface->waylandSurface()->pong(); - else - qWarning("Received an unexpected pong!"); -} - -void ShellSurface::shell_surface_set_title(Resource *resource, - const QString &title) -{ - Q_UNUSED(resource); - m_surface->setTitle(title); -} - -void ShellSurface::shell_surface_set_class(Resource *resource, - const QString &className) -{ - Q_UNUSED(resource); - m_surface->setClassName(className); -} - -ShellSurfaceGrabber::ShellSurfaceGrabber(ShellSurface *shellSurface) - : PointerGrabber() - , shell_surface(shellSurface) -{ -} - -ShellSurfaceGrabber::~ShellSurfaceGrabber() -{ -} - -ShellSurfaceResizeGrabber::ShellSurfaceResizeGrabber(ShellSurface *shellSurface) - : ShellSurfaceGrabber(shellSurface) -{ -} - -void ShellSurfaceResizeGrabber::focus() -{ -} - -void ShellSurfaceResizeGrabber::motion(uint32_t time) -{ - Q_UNUSED(time); - - int width_delta = point.x() - m_pointer->position().x(); - int height_delta = point.y() - m_pointer->position().y(); - - int new_height = height; - if (resize_edges & WL_SHELL_SURFACE_RESIZE_TOP) - new_height = qMax(new_height + height_delta, 1); - else if (resize_edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) - new_height = qMax(new_height - height_delta, 1); - - int new_width = width; - if (resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT) - new_width = qMax(new_width + width_delta, 1); - else if (resize_edges & WL_SHELL_SURFACE_RESIZE_RIGHT) - new_width = qMax(new_width - width_delta, 1); - - shell_surface->sendConfigure(resize_edges, new_width, new_height); -} - -void ShellSurfaceResizeGrabber::button(uint32_t time, Qt::MouseButton button, uint32_t state) -{ - Q_UNUSED(time) - - if (button == Qt::LeftButton && !state) { - m_pointer->endGrab(); - shell_surface->resetResizeGrabber(); - delete this; - } -} - -ShellSurfaceMoveGrabber::ShellSurfaceMoveGrabber(ShellSurface *shellSurface, const QPointF &offset) - : ShellSurfaceGrabber(shellSurface) - , m_offset(offset) -{ -} - -void ShellSurfaceMoveGrabber::focus() -{ -} - -void ShellSurfaceMoveGrabber::motion(uint32_t time) -{ - Q_UNUSED(time); - - QPointF pos(m_pointer->position() - m_offset); - shell_surface->m_view->setPos(pos); - if (shell_surface->m_surface->transientParent()) { - QWaylandSurfaceView *view = shell_surface->m_surface->transientParent()->waylandSurface()->views().first(); - if (view) - shell_surface->setOffset(pos - view->pos()); - } - -} - -void ShellSurfaceMoveGrabber::button(uint32_t time, Qt::MouseButton button, uint32_t state) -{ - Q_UNUSED(time) - - if (button == Qt::LeftButton && !state) { - m_pointer->setFocus(0, QPointF()); - m_pointer->endGrab(); - shell_surface->resetMoveGrabber(); - delete this; - } -} - -ShellSurfacePopupGrabber::ShellSurfacePopupGrabber(InputDevice *inputDevice) - : PointerGrabber() - , m_inputDevice(inputDevice) - , m_client(0) - , m_surfaces() - , m_initialUp(false) -{ -} - -uint32_t ShellSurfacePopupGrabber::grabSerial() const -{ - return m_inputDevice->pointerDevice()->grabSerial(); -} - -struct ::wl_client *ShellSurfacePopupGrabber::client() const -{ - return m_client; -} - -void ShellSurfacePopupGrabber::setClient(struct ::wl_client *client) -{ - m_client = client; -} - -void ShellSurfacePopupGrabber::addPopup(ShellSurface *surface) -{ - if (m_surfaces.isEmpty()) { - m_client = surface->resource()->client(); - - if (m_inputDevice->pointerDevice()->buttonPressed()) - m_initialUp = false; - - m_surfaces.append(surface); - m_inputDevice->pointerDevice()->startGrab(this); - } else { - m_surfaces.append(surface); - } -} - -void ShellSurfacePopupGrabber::removePopup(ShellSurface *surface) -{ - if (m_surfaces.isEmpty()) - return; - - m_surfaces.removeOne(surface); - if (m_surfaces.isEmpty()) - m_inputDevice->pointerDevice()->endGrab(); -} - -void ShellSurfacePopupGrabber::focus() -{ - if (m_pointer->current() && m_pointer->current()->surface()->handle()->resource()->client() == m_client) - m_pointer->setFocus(m_pointer->current(), m_pointer->currentPosition()); - else - m_pointer->setFocus(0, QPointF()); -} - -void ShellSurfacePopupGrabber::motion(uint32_t time) -{ - m_pointer->motion(time); -} - -void ShellSurfacePopupGrabber::button(uint32_t time, Qt::MouseButton button, uint32_t state) -{ - if (m_pointer->focusResource()) { - m_pointer->sendButton(time, button, state); - } else if (state == QtWaylandServer::wl_pointer::button_state_pressed && - (m_initialUp || time - m_pointer->grabTime() > 500) && - m_pointer->currentGrab() == this) { - m_pointer->endGrab(); - Q_FOREACH (ShellSurface *surface, m_surfaces) { - surface->send_popup_done(); - } - m_surfaces.clear(); - } - - if (state == QtWaylandServer::wl_pointer::button_state_released) - m_initialUp = true; -} - - -} - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlshellsurface_p.h b/src/compositor/wayland_wrapper/qwlshellsurface_p.h deleted file mode 100644 index fab2a5c0b..000000000 --- a/src/compositor/wayland_wrapper/qwlshellsurface_p.h +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WLSHELLSURFACE_H -#define WLSHELLSURFACE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/qwaylandsurface.h> -#include <QtCompositor/qwaylandglobalinterface.h> -#include <QtCompositor/qwaylandsurfaceinterface.h> - -#include <wayland-server.h> -#include <QHash> -#include <QPoint> -#include <QSet> -#include <private/qwlpointer_p.h> - -#include <QtCompositor/private/qwayland-server-wayland.h> - -QT_BEGIN_NAMESPACE - -class QWaylandSurfaceView; - -namespace QtWayland { - -class Compositor; -class Surface; -class ShellSurface; -class ShellSurfaceResizeGrabber; -class ShellSurfaceMoveGrabber; -class ShellSurfacePopupGrabber; - -class Shell : public QWaylandGlobalInterface, public QtWaylandServer::wl_shell -{ -public: - Shell(); - - const wl_interface *interface() const Q_DECL_OVERRIDE; - - void bind(struct wl_client *client, uint32_t version, uint32_t id) Q_DECL_OVERRIDE; - - ShellSurfacePopupGrabber* getPopupGrabber(InputDevice *input); - -private: - void shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE; - - QHash<InputDevice*, ShellSurfacePopupGrabber*> m_popupGrabber; -}; - -class Q_COMPOSITOR_EXPORT ShellSurface : public QObject, public QWaylandSurfaceInterface, public QtWaylandServer::wl_shell_surface -{ -public: - ShellSurface(Shell *shell, struct wl_client *client, uint32_t id, Surface *surface); - ~ShellSurface(); - void sendConfigure(uint32_t edges, int32_t width, int32_t height); - - void adjustPosInResize(); - void resetResizeGrabber(); - void resetMoveGrabber(); - - void setOffset(const QPointF &offset); - - void configure(bool hasBuffer); - - void requestSize(const QSize &size); - void ping(uint32_t serial); - -protected: - bool runOperation(QWaylandSurfaceOp *op) Q_DECL_OVERRIDE; - -private Q_SLOTS: - void mapped(); - -private: - Shell *m_shell; - Surface *m_surface; - QWaylandSurfaceView *m_view; - - ShellSurfaceResizeGrabber *m_resizeGrabber; - ShellSurfaceMoveGrabber *m_moveGrabber; - ShellSurfacePopupGrabber *m_popupGrabber; - - uint32_t m_popupSerial; - - QSet<uint32_t> m_pings; - - void shell_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - - void shell_surface_move(Resource *resource, - struct wl_resource *input_device_super, - uint32_t time) Q_DECL_OVERRIDE; - void shell_surface_resize(Resource *resource, - struct wl_resource *input_device, - uint32_t time, - uint32_t edges) Q_DECL_OVERRIDE; - void shell_surface_set_toplevel(Resource *resource) Q_DECL_OVERRIDE; - void shell_surface_set_transient(Resource *resource, - struct wl_resource *parent_surface_resource, - int x, - int y, - uint32_t flags) Q_DECL_OVERRIDE; - void shell_surface_set_fullscreen(Resource *resource, - uint32_t method, - uint32_t framerate, - struct wl_resource *output_resource) Q_DECL_OVERRIDE; - void shell_surface_set_popup(Resource *resource, - struct wl_resource *input_device, - uint32_t time, - struct wl_resource *parent, - int32_t x, - int32_t y, - uint32_t flags) Q_DECL_OVERRIDE; - void shell_surface_set_maximized(Resource *resource, - struct wl_resource *output_resource) Q_DECL_OVERRIDE; - void shell_surface_pong(Resource *resource, - uint32_t serial) Q_DECL_OVERRIDE; - void shell_surface_set_title(Resource *resource, - const QString &title) Q_DECL_OVERRIDE; - void shell_surface_set_class(Resource *resource, - const QString &class_) Q_DECL_OVERRIDE; - - friend class ShellSurfaceMoveGrabber; -}; - -class ShellSurfaceGrabber : public PointerGrabber -{ -public: - ShellSurfaceGrabber(ShellSurface *shellSurface); - ~ShellSurfaceGrabber(); - - ShellSurface *shell_surface; -}; - -class ShellSurfaceResizeGrabber : public ShellSurfaceGrabber -{ -public: - ShellSurfaceResizeGrabber(ShellSurface *shellSurface); - - QPointF point; - enum wl_shell_surface_resize resize_edges; - int32_t width; - int32_t height; - - void focus() Q_DECL_OVERRIDE; - void motion(uint32_t time) Q_DECL_OVERRIDE; - void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; -}; - -class ShellSurfaceMoveGrabber : public ShellSurfaceGrabber -{ -public: - ShellSurfaceMoveGrabber(ShellSurface *shellSurface, const QPointF &offset); - - void focus() Q_DECL_OVERRIDE; - void motion(uint32_t time) Q_DECL_OVERRIDE; - void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; - -private: - QPointF m_offset; -}; - -class ShellSurfacePopupGrabber : public PointerGrabber -{ -public: - ShellSurfacePopupGrabber(InputDevice *inputDevice); - - uint32_t grabSerial() const; - - struct ::wl_client *client() const; - void setClient(struct ::wl_client *client); - - void addPopup(ShellSurface *surface); - void removePopup(ShellSurface *surface); - - void focus() Q_DECL_OVERRIDE; - void motion(uint32_t time) Q_DECL_OVERRIDE; - void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE; - -private: - InputDevice *m_inputDevice; - struct ::wl_client *m_client; - QList<ShellSurface *> m_surfaces; - bool m_initialUp; -}; - -} - -QT_END_NAMESPACE - -#endif // WLSHELLSURFACE_H diff --git a/src/compositor/wayland_wrapper/qwlsubsurface.cpp b/src/compositor/wayland_wrapper/qwlsubsurface.cpp deleted file mode 100644 index afc6d1825..000000000 --- a/src/compositor/wayland_wrapper/qwlsubsurface.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlsubsurface_p.h" - -#include "qwlcompositor_p.h" -#include "qwaylandsurface.h" -#include "qwaylandsurfaceview.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -SubSurfaceExtensionGlobal::SubSurfaceExtensionGlobal(Compositor *compositor) - : m_compositor(compositor) -{ - wl_global_create(m_compositor->wl_display(), - &qt_sub_surface_extension_interface, - qt_sub_surface_extension_interface.version, - this, - SubSurfaceExtensionGlobal::bind_func); -} - -void SubSurfaceExtensionGlobal::bind_func(wl_client *client, void *data, uint32_t version, uint32_t id) -{ - Q_UNUSED(version); - struct wl_resource *resource = wl_resource_create(client, &qt_sub_surface_extension_interface,version,id); - wl_resource_set_implementation(resource, &sub_surface_extension_interface, data, 0); -} - -void SubSurfaceExtensionGlobal::get_sub_surface_aware_surface(wl_client *client, wl_resource *sub_surface_extension_resource, uint32_t id, wl_resource *surface_resource) -{ - Q_UNUSED(sub_surface_extension_resource); - Surface *surface = Surface::fromResource(surface_resource); - new SubSurface(client,id,surface); -} - -const struct qt_sub_surface_extension_interface SubSurfaceExtensionGlobal::sub_surface_extension_interface = { - SubSurfaceExtensionGlobal::get_sub_surface_aware_surface -}; - -SubSurface::SubSurface(wl_client *client, uint32_t id, Surface *surface) - : m_surface(surface) - , m_parent(0) -{ - surface->setSubSurface(this); - m_sub_surface_resource = wl_resource_create(client, &qt_sub_surface_interface, qt_sub_surface_interface.version, id); - wl_resource_set_implementation(m_sub_surface_resource, &sub_surface_interface, this, 0); -} - -SubSurface::~SubSurface() -{ - if (m_parent) { - m_parent->removeSubSurface(this); - } - QLinkedList<QWaylandSurface *>::iterator it; - for (it = m_sub_surfaces.begin(); it != m_sub_surfaces.end(); ++it) { - (*it)->handle()->subSurface()->parentDestroyed(); - } -} - -void SubSurface::setSubSurface(SubSurface *subSurface, int x, int y) -{ - if (!m_sub_surfaces.contains(subSurface->m_surface->waylandSurface())) { - m_sub_surfaces.append(subSurface->m_surface->waylandSurface()); - subSurface->setParent(this); - } - foreach (QWaylandSurfaceView *view, subSurface->m_surface->waylandSurface()->views()) - view->setPos(QPointF(x,y)); -} - -void SubSurface::removeSubSurface(SubSurface *subSurfaces) -{ - Q_ASSERT(m_sub_surfaces.contains(subSurfaces->m_surface->waylandSurface())); - m_sub_surfaces.removeOne(subSurfaces->m_surface->waylandSurface()); -} - -SubSurface *SubSurface::parent() const -{ - return m_parent; -} - -void SubSurface::setParent(SubSurface *parent) -{ - if (m_parent == parent) - return; - - QWaylandSurface *oldParent = 0; - QWaylandSurface *newParent = 0; - - if (m_parent) { - oldParent = m_parent->m_surface->waylandSurface(); - m_parent->removeSubSurface(this); - } - if (parent) { - newParent = parent->m_surface->waylandSurface(); - } - m_parent = parent; - - m_surface->waylandSurface()->parentChanged(newParent,oldParent); -} - -QLinkedList<QWaylandSurface *> SubSurface::subSurfaces() const -{ - return m_sub_surfaces; -} - -void SubSurface::parentDestroyed() -{ - m_parent = 0; -} -void SubSurface::attach_sub_surface(wl_client *client, wl_resource *sub_surface_parent_resource, wl_resource *sub_surface_child_resource, int32_t x, int32_t y) -{ - Q_UNUSED(client); - SubSurface *parent_sub_surface = static_cast<SubSurface *>(sub_surface_parent_resource->data); - SubSurface *child_sub_surface = static_cast<SubSurface *>(sub_surface_child_resource->data); - parent_sub_surface->setSubSurface(child_sub_surface,x,y); -} - -void SubSurface::move_sub_surface(wl_client *client, wl_resource *sub_surface_parent_resource, wl_resource *sub_surface_child_resource, int32_t x, int32_t y) -{ - Q_UNUSED(client); - Q_UNUSED(x); - Q_UNUSED(y); - SubSurface *parent_sub_surface = static_cast<SubSurface *>(sub_surface_parent_resource->data); - SubSurface *child_sub_surface = static_cast<SubSurface *>(sub_surface_child_resource->data); - Q_UNUSED(parent_sub_surface); - Q_UNUSED(child_sub_surface); -} - -void SubSurface::raise(wl_client *client, wl_resource *sub_surface_parent_resource, wl_resource *sub_surface_child_resource) -{ - Q_UNUSED(client); - Q_UNUSED(sub_surface_parent_resource); - Q_UNUSED(sub_surface_child_resource); -} - -void SubSurface::lower(wl_client *client, wl_resource *sub_surface_parent_resource, wl_resource *sub_surface_child_resource) -{ - Q_UNUSED(client); - Q_UNUSED(sub_surface_parent_resource); - Q_UNUSED(sub_surface_child_resource); -} - -const struct qt_sub_surface_interface SubSurface::sub_surface_interface = { - SubSurface::attach_sub_surface, - SubSurface::move_sub_surface, - SubSurface::raise, - SubSurface::lower -}; - -} - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlsubsurface_p.h b/src/compositor/wayland_wrapper/qwlsubsurface_p.h deleted file mode 100644 index bce79342d..000000000 --- a/src/compositor/wayland_wrapper/qwlsubsurface_p.h +++ /dev/null @@ -1,144 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WLSUBSURFACE_H -#define WLSUBSURFACE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qwlsurface_p.h> - -#include <QtCompositor/private/wayland-sub-surface-extension-server-protocol.h> - -#include <QtCore/QLinkedList> - -QT_BEGIN_NAMESPACE - -class Compositor; -class QWaylandSurface; - -namespace QtWayland { - -class SubSurfaceExtensionGlobal -{ -public: - SubSurfaceExtensionGlobal(Compositor *compositor); - -private: - Compositor *m_compositor; - - static void bind_func(struct wl_client *client, void *data, - uint32_t version, uint32_t id); - static void get_sub_surface_aware_surface(struct wl_client *client, - struct wl_resource *sub_surface_extension_resource, - uint32_t id, - struct wl_resource *surface_resource); - - static const struct qt_sub_surface_extension_interface sub_surface_extension_interface; -}; - -class SubSurface -{ -public: - SubSurface(struct wl_client *client, uint32_t id, Surface *surface); - ~SubSurface(); - - void setSubSurface(SubSurface *subSurface, int x, int y); - void removeSubSurface(SubSurface *subSurfaces); - - SubSurface *parent() const; - void setParent(SubSurface *parent); - - QLinkedList<QWaylandSurface *> subSurfaces() const; - - Surface *surface() const; - QWaylandSurface *waylandSurface() const; - -private: - void parentDestroyed(); - struct wl_resource *m_sub_surface_resource; - Surface *m_surface; - - SubSurface *m_parent; - QLinkedList<QWaylandSurface *> m_sub_surfaces; - - static void attach_sub_surface(struct wl_client *client, - struct wl_resource *sub_surface_parent_resource, - struct wl_resource *sub_surface_child_resource, - int32_t x, - int32_t y); - static void move_sub_surface(struct wl_client *client, - struct wl_resource *sub_surface_parent_resource, - struct wl_resource *sub_surface_child_resource, - int32_t x, - int32_t y); - static void raise(struct wl_client *client, - struct wl_resource *sub_surface_parent_resource, - struct wl_resource *sub_surface_child_resource); - static void lower(struct wl_client *client, - struct wl_resource *sub_surface_parent_resource, - struct wl_resource *sub_surface_child_resource); - static const struct qt_sub_surface_interface sub_surface_interface; -}; - -inline Surface *SubSurface::surface() const -{ - return m_surface; -} - -inline QWaylandSurface *SubSurface::waylandSurface() const -{ - return m_surface->waylandSurface(); -} - -} - -QT_END_NAMESPACE - -#endif // WLSUBSURFACE_H diff --git a/src/compositor/wayland_wrapper/qwlsurface.cpp b/src/compositor/wayland_wrapper/qwlsurface.cpp deleted file mode 100644 index d23c6aeb0..000000000 --- a/src/compositor/wayland_wrapper/qwlsurface.cpp +++ /dev/null @@ -1,575 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwlsurface_p.h" - -#include "qwaylandsurface.h" -#include "qwlcompositor_p.h" -#include "qwlinputdevice_p.h" -#include "qwlextendedsurface_p.h" -#include "qwlregion_p.h" -#include "qwlsubsurface_p.h" -#include "qwlsurfacebuffer_p.h" -#include "qwaylandsurfaceview.h" -#include "qwaylandoutput.h" - -#include <QtCore/QDebug> -#include <QTouchEvent> -#include <QGuiApplication> -#include <QScreen> - -#include <wayland-server.h> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -class FrameCallback { -public: - FrameCallback(Surface *surf, wl_resource *res) - : surface(surf) - , resource(res) - , canSend(false) - { -#if WAYLAND_VERSION_MAJOR < 1 || (WAYLAND_VERSION_MAJOR == 1 && WAYLAND_VERSION_MINOR <= 2) - res->data = this; - res->destroy = destroyCallback; -#else - wl_resource_set_implementation(res, 0, this, destroyCallback); -#endif - } - ~FrameCallback() - { - } - void destroy() - { - if (resource) - wl_resource_destroy(resource); - else - delete this; - } - void send(uint time) - { - wl_callback_send_done(resource, time); - wl_resource_destroy(resource); - } - static void destroyCallback(wl_resource *res) - { -#if WAYLAND_VERSION_MAJOR < 1 || (WAYLAND_VERSION_MAJOR == 1 && WAYLAND_VERSION_MINOR <= 2) - FrameCallback *_this = static_cast<FrameCallback *>(res->data); -#else - FrameCallback *_this = static_cast<FrameCallback *>(wl_resource_get_user_data(res)); -#endif - _this->surface->removeFrameCallback(_this); - delete _this; - } - Surface *surface; - wl_resource *resource; - bool canSend; -}; - -static QRegion infiniteRegion() { - return QRegion(QRect(QPoint(std::numeric_limits<int>::min(), std::numeric_limits<int>::min()), - QPoint(std::numeric_limits<int>::max(), std::numeric_limits<int>::max()))); -} - -Surface::Surface(struct wl_client *client, uint32_t id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface) - : QtWaylandServer::wl_surface(client, id, version) - , m_compositor(compositor->handle()) - , m_waylandSurface(surface) - , m_mainOutput(0) - , m_buffer(0) - , m_surfaceMapped(false) - , m_attacher(0) - , m_extendedSurface(0) - , m_subSurface(0) - , m_inputPanelSurface(0) - , m_inputRegion(infiniteRegion()) - , m_transientParent(0) - , m_transientInactive(false) - , m_transientOffset(QPointF(0, 0)) - , m_isCursorSurface(false) - , m_destroyed(false) - , m_contentOrientation(Qt::PrimaryOrientation) - , m_visibility(QWindow::Hidden) - , m_role(0) - , m_roleHandler(0) -{ - m_pending.buffer = 0; - m_pending.newlyAttached = false; - m_pending.inputRegion = infiniteRegion(); -} - -Surface::~Surface() -{ - delete m_subSurface; - - m_bufferRef = QWaylandBufferRef(); - - for (int i = 0; i < m_bufferPool.size(); i++) - m_bufferPool[i]->setDestroyIfUnused(true); - - foreach (FrameCallback *c, m_pendingFrameCallbacks) - c->destroy(); - foreach (FrameCallback *c, m_frameCallbacks) - c->destroy(); -} - -bool Surface::setRole(const SurfaceRole *role, wl_resource *errorResource, uint32_t errorCode) -{ - if (m_role && m_role != role) { - wl_resource_post_error(errorResource, errorCode, "Cannot assign role %s to wl_surface@%d, already has role %s\n", role->name, - wl_resource_get_id(resource()->handle), m_role->name); - return false; - } - m_role = role; - return true; -} - -void Surface::setTransientOffset(qreal x, qreal y) -{ - m_transientOffset.setX(x); - m_transientOffset.setY(y); -} - -void Surface::releaseSurfaces() -{ - -} - -Surface *Surface::fromResource(struct ::wl_resource *resource) -{ - return static_cast<Surface *>(Resource::fromResource(resource)->surface_object); -} - -QWaylandSurface::Type Surface::type() const -{ - if (m_buffer && m_buffer->waylandBufferHandle()) { - if (m_buffer->isShmBuffer()) { - return QWaylandSurface::Shm; - } else { - return QWaylandSurface::Texture; - } - } - return QWaylandSurface::Invalid; -} - -bool Surface::isYInverted() const -{ - if (m_buffer) - return m_buffer->isYInverted(); - return false; -} - -bool Surface::mapped() const -{ - return !m_unmapLocks.isEmpty() || (m_buffer && bool(m_buffer->waylandBufferHandle())); -} - -QSize Surface::size() const -{ - return m_size; -} - -void Surface::setSize(const QSize &size) -{ - if (size != m_size) { - m_opaqueRegion = QRegion(); - m_size = size; - m_waylandSurface->sizeChanged(); - } -} - -QRegion Surface::inputRegion() const -{ - return m_inputRegion; -} - -QRegion Surface::opaqueRegion() const -{ - return m_opaqueRegion; -} - -void Surface::sendFrameCallback() -{ - uint time = m_compositor->currentTimeMsecs(); - foreach (FrameCallback *callback, m_frameCallbacks) { - if (callback->canSend) { - callback->send(time); - m_frameCallbacks.removeOne(callback); - } - } -} - -void Surface::removeFrameCallback(FrameCallback *callback) -{ - m_pendingFrameCallbacks.removeOne(callback); - m_frameCallbacks.removeOne(callback); -} - -QWaylandSurface * Surface::waylandSurface() const -{ - return m_waylandSurface; -} - -QPoint Surface::lastMousePos() const -{ - return m_lastLocalMousePos; -} - -void Surface::setExtendedSurface(ExtendedSurface *extendedSurface) -{ - m_extendedSurface = extendedSurface; - if (m_extendedSurface) - emit m_waylandSurface->extendedSurfaceReady(); -} - -ExtendedSurface *Surface::extendedSurface() const -{ - return m_extendedSurface; -} - -void Surface::setSubSurface(SubSurface *subSurface) -{ - m_subSurface = subSurface; -} - -SubSurface *Surface::subSurface() const -{ - return m_subSurface; -} - -void Surface::setInputPanelSurface(InputPanelSurface *inputPanelSurface) -{ - m_inputPanelSurface = inputPanelSurface; -} - -InputPanelSurface *Surface::inputPanelSurface() const -{ - return m_inputPanelSurface; -} - -Compositor *Surface::compositor() const -{ - return m_compositor; -} - -Output *Surface::mainOutput() const -{ - if (!m_mainOutput) - return m_compositor->primaryOutput()->handle(); - return m_mainOutput; -} - -void Surface::setMainOutput(Output *output) -{ - m_mainOutput = output; -} - -QList<Output *> Surface::outputs() const -{ - return m_outputs; -} - -void Surface::addToOutput(Output *output) -{ - if (!output) - return; - - if (!m_mainOutput) - m_mainOutput = output; - - if (m_outputs.contains(output)) - return; - - m_outputs.append(output); - - QWaylandSurfaceEnterEvent event(output->waylandOutput()); - QCoreApplication::sendEvent(waylandSurface(), &event); - - // Send surface enter event - Q_FOREACH (Resource *resource, resourceMap().values()) { - QList<Output::Resource *> outputs = output->resourceMap().values(); - for (int i = 0; i < outputs.size(); i++) - send_enter(resource->handle, outputs.at(i)->handle); - } -} - -void Surface::removeFromOutput(Output *output) -{ - if (!output) - return; - - m_outputs.removeOne(output); - - if (m_outputs.size() == 0) - m_mainOutput = m_compositor->primaryOutput()->handle(); - - QWaylandSurfaceLeaveEvent event(output->waylandOutput()); - QCoreApplication::sendEvent(waylandSurface(), &event); - - // Send surface leave event - Q_FOREACH (Resource *resource, resourceMap().values()) { - QList<Output::Resource *> outputs = output->resourceMap().values(); - for (int i = 0; i < outputs.size(); i++) - send_leave(resource->handle, outputs.at(i)->handle); - } -} - -/*! - * Sets the backbuffer for this surface. The back buffer is not yet on - * screen and will become live during the next swapBuffers(). - * - * The backbuffer represents the current state of the surface for the - * purpose of GUI-thread accessible properties such as size and visibility. - */ -void Surface::setBackBuffer(SurfaceBuffer *buffer) -{ - m_buffer = buffer; - - if (m_buffer) { - bool valid = m_buffer->waylandBufferHandle() != 0; - if (valid) - setSize(m_buffer->size()); - - m_damage = m_damage.intersected(QRect(QPoint(), m_size)); - emit m_waylandSurface->damaged(m_damage); - } else { - m_compositor->resetInputDevice(this); - } - m_damage = QRegion(); -} - -void Surface::setMapped(bool mapped) -{ - if (!m_surfaceMapped && mapped) { - m_surfaceMapped = true; - emit m_waylandSurface->mapped(); - } else if (!mapped && m_surfaceMapped) { - m_surfaceMapped = false; - emit m_waylandSurface->unmapped(); - } -} - -void Surface::addUnmapLock(QWaylandUnmapLock *l) -{ - m_unmapLocks << l; -} - -void Surface::removeUnmapLock(QWaylandUnmapLock *l) -{ - m_unmapLocks.removeOne(l); - if (!mapped() && m_attacher) { - setSize(QSize()); - m_attacher->unmap(); - } -} - -SurfaceBuffer *Surface::createSurfaceBuffer(struct ::wl_resource *buffer) -{ - SurfaceBuffer *newBuffer = 0; - for (int i = 0; i < m_bufferPool.size(); i++) { - if (!m_bufferPool[i]->isRegisteredWithBuffer()) { - newBuffer = m_bufferPool[i]; - newBuffer->initialize(buffer); - break; - } - } - - if (!newBuffer) { - newBuffer = new SurfaceBuffer(this); - newBuffer->initialize(buffer); - m_bufferPool.append(newBuffer); - if (m_bufferPool.size() > 3) - qWarning() << "Increased buffer pool size to" << m_bufferPool.size() << "for surface with title:" << title() << "className:" << className(); - } - - return newBuffer; -} - -Qt::ScreenOrientation Surface::contentOrientation() const -{ - return m_contentOrientation; -} - -void Surface::surface_destroy_resource(Resource *) -{ - if (m_extendedSurface) { - m_extendedSurface->setParentSurface(Q_NULLPTR); - m_extendedSurface = 0; - } - - if (transientParent()) { - foreach (Surface *surface, compositor()->surfaces()) { - if (surface->transientParent() == this) { - surface->setTransientParent(0); - } - } - } - - m_destroyed = true; - m_waylandSurface->destroy(); - emit m_waylandSurface->surfaceDestroyed(); -} - -void Surface::surface_destroy(Resource *resource) -{ - wl_resource_destroy(resource->handle); -} - -void Surface::surface_attach(Resource *, struct wl_resource *buffer, int x, int y) -{ - if (m_pending.buffer) - m_pending.buffer->disown(); - m_pending.buffer = createSurfaceBuffer(buffer); - m_pending.offset = QPoint(x, y); - m_pending.newlyAttached = true; -} - -void Surface::surface_damage(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) -{ - m_pending.damage = m_pending.damage.united(QRect(x, y, width, height)); -} - -void Surface::surface_frame(Resource *resource, uint32_t callback) -{ - struct wl_resource *frame_callback = wl_resource_create(resource->client(), &wl_callback_interface, wl_callback_interface.version, callback); - m_pendingFrameCallbacks << new FrameCallback(this, frame_callback); -} - -void Surface::surface_set_opaque_region(Resource *, struct wl_resource *region) -{ - m_opaqueRegion = region ? Region::fromResource(region)->region() : QRegion(); -} - -void Surface::surface_set_input_region(Resource *, struct wl_resource *region) -{ - if (region) { - m_pending.inputRegion = Region::fromResource(region)->region(); - } else { - m_pending.inputRegion = infiniteRegion(); - } -} - -void Surface::surface_commit(Resource *) -{ - m_damage = m_pending.damage; - - if (m_pending.buffer || m_pending.newlyAttached) { - setBackBuffer(m_pending.buffer); - m_bufferRef = QWaylandBufferRef(m_buffer); - - if (m_attacher) { - if (m_bufferRef) { - m_attacher->attach(m_bufferRef); - } else if (!mapped()) { - setSize(QSize()); - m_attacher->unmap(); - } - } - emit m_waylandSurface->configure(m_bufferRef); - if (m_roleHandler) - m_roleHandler->configure(m_pending.offset.x(), m_pending.offset.y()); - } - - m_pending.buffer = 0; - m_pending.offset = QPoint(); - m_pending.newlyAttached = false; - m_pending.damage = QRegion(); - - if (m_buffer) - m_buffer->setCommitted(); - - m_frameCallbacks << m_pendingFrameCallbacks; - m_pendingFrameCallbacks.clear(); - - m_inputRegion = m_pending.inputRegion.intersected(QRect(QPoint(), m_size)); - - emit m_waylandSurface->redraw(); -} - -void Surface::surface_set_buffer_transform(Resource *resource, int32_t orientation) -{ - Q_UNUSED(resource); - QScreen *screen = QGuiApplication::primaryScreen(); - bool isPortrait = screen->primaryOrientation() == Qt::PortraitOrientation; - Qt::ScreenOrientation oldOrientation = m_contentOrientation; - switch (orientation) { - case WL_OUTPUT_TRANSFORM_90: - m_contentOrientation = isPortrait ? Qt::InvertedLandscapeOrientation : Qt::PortraitOrientation; - break; - case WL_OUTPUT_TRANSFORM_180: - m_contentOrientation = isPortrait ? Qt::InvertedPortraitOrientation : Qt::InvertedLandscapeOrientation; - break; - case WL_OUTPUT_TRANSFORM_270: - m_contentOrientation = isPortrait ? Qt::LandscapeOrientation : Qt::InvertedPortraitOrientation; - break; - default: - m_contentOrientation = Qt::PrimaryOrientation; - } - if (m_contentOrientation != oldOrientation) - emit waylandSurface()->contentOrientationChanged(); -} - -void Surface::frameStarted() -{ - foreach (FrameCallback *c, m_frameCallbacks) - c->canSend = true; -} - -void Surface::setClassName(const QString &className) -{ - if (m_className != className) { - m_className = className; - emit waylandSurface()->classNameChanged(); - } -} - -void Surface::setTitle(const QString &title) -{ - if (m_title != title) { - m_title = title; - emit waylandSurface()->titleChanged(); - } -} - -} // namespace Wayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlsurface_p.h b/src/compositor/wayland_wrapper/qwlsurface_p.h deleted file mode 100644 index 343955c1a..000000000 --- a/src/compositor/wayland_wrapper/qwlsurface_p.h +++ /dev/null @@ -1,304 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WL_SURFACE_H -#define WL_SURFACE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> - -#include <private/qwlsurfacebuffer_p.h> -#include <private/qwloutput_p.h> -#include <QtCompositor/qwaylandsurface.h> -#include <QtCompositor/qwaylandbufferref.h> - -#include <QtCore/QVector> -#include <QtCore/QRect> -#include <QtGui/QRegion> -#include <QtGui/QImage> -#include <QtGui/QWindow> - -#include <QtCore/QTextStream> -#include <QtCore/QMetaType> - -#include <wayland-util.h> - -#include <QtCompositor/private/qwayland-server-wayland.h> - -QT_BEGIN_NAMESPACE - -class QTouchEvent; - -class QWaylandUnmapLock; - -namespace QtWayland { - -class Compositor; -class Buffer; -class ExtendedSurface; -class InputPanelSurface; -class SubSurface; -class FrameCallback; - -class SurfaceRole; -class RoleBase; - -class Q_COMPOSITOR_EXPORT Surface : public QtWaylandServer::wl_surface -{ -public: - Surface(struct wl_client *client, uint32_t id, int version, QWaylandCompositor *compositor, QWaylandSurface *surface); - ~Surface(); - - bool setRole(const SurfaceRole *role, wl_resource *errorResource, uint32_t errorCode); - const SurfaceRole *role() const { return m_role; } - template<class T> - bool setRoleHandler(T *handler); - - static Surface *fromResource(struct ::wl_resource *resource); - - QWaylandSurface::Type type() const; - bool isYInverted() const; - - bool mapped() const; - - using QtWaylandServer::wl_surface::resource; - - QSize size() const; - void setSize(const QSize &size); - - QRegion inputRegion() const; - QRegion opaqueRegion() const; - - void sendFrameCallback(); - void removeFrameCallback(FrameCallback *callback); - - QWaylandSurface *waylandSurface() const; - - QPoint lastMousePos() const; - - void setExtendedSurface(ExtendedSurface *extendedSurface); - ExtendedSurface *extendedSurface() const; - - void setSubSurface(SubSurface *subSurface); - SubSurface *subSurface() const; - - void setInputPanelSurface(InputPanelSurface *inputPanelSurface); - InputPanelSurface *inputPanelSurface() const; - - Compositor *compositor() const; - - Output *mainOutput() const; - void setMainOutput(Output *output); - - QList<Output *> outputs() const; - - void addToOutput(Output *output); - void removeFromOutput(Output *output); - - QString className() const { return m_className; } - void setClassName(const QString &className); - - QString title() const { return m_title; } - void setTitle(const QString &title); - - Surface *transientParent() const { return m_transientParent; } - void setTransientParent(Surface *parent) { m_transientParent = parent; } - - bool transientInactive() const { return m_transientInactive; } - void setTransientInactive(bool v) { m_transientInactive = v; } - - void setTransientOffset(qreal x, qreal y); - - bool isCursorSurface() const { return m_isCursorSurface; } - void setCursorSurface(bool isCursor) { m_isCursorSurface = isCursor; } - - void releaseSurfaces(); - void frameStarted(); - - void addUnmapLock(QWaylandUnmapLock *l); - void removeUnmapLock(QWaylandUnmapLock *l); - - void setMapped(bool mapped); - void setVisibility(QWindow::Visibility visibility) { m_visibility = visibility; } - - inline bool isDestroyed() const { return m_destroyed; } - - Qt::ScreenOrientation contentOrientation() const; - -protected: - void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - - void surface_destroy(Resource *resource) Q_DECL_OVERRIDE; - void surface_attach(Resource *resource, - struct wl_resource *buffer, int x, int y) Q_DECL_OVERRIDE; - void surface_damage(Resource *resource, - int32_t x, int32_t y, int32_t width, int32_t height) Q_DECL_OVERRIDE; - void surface_frame(Resource *resource, - uint32_t callback) Q_DECL_OVERRIDE; - void surface_set_opaque_region(Resource *resource, - struct wl_resource *region) Q_DECL_OVERRIDE; - void surface_set_input_region(Resource *resource, - struct wl_resource *region) Q_DECL_OVERRIDE; - void surface_commit(Resource *resource) Q_DECL_OVERRIDE; - void surface_set_buffer_transform(Resource *resource, int32_t transform) Q_DECL_OVERRIDE; - - Q_DISABLE_COPY(Surface) - - Compositor *m_compositor; - QWaylandSurface *m_waylandSurface; - Output *m_mainOutput; - QList<Output *> m_outputs; - - QRegion m_damage; - SurfaceBuffer *m_buffer; - QWaylandBufferRef m_bufferRef; - bool m_surfaceMapped; - QWaylandBufferAttacher *m_attacher; - QVector<QWaylandUnmapLock *> m_unmapLocks; - - struct { - SurfaceBuffer *buffer; - QRegion damage; - QPoint offset; - bool newlyAttached; - QRegion inputRegion; - } m_pending; - - QPoint m_lastLocalMousePos; - QPoint m_lastGlobalMousePos; - - QList<FrameCallback *> m_pendingFrameCallbacks; - QList<FrameCallback *> m_frameCallbacks; - - ExtendedSurface *m_extendedSurface; - SubSurface *m_subSurface; - InputPanelSurface *m_inputPanelSurface; - - QRegion m_inputRegion; - QRegion m_opaqueRegion; - - QVector<SurfaceBuffer *> m_bufferPool; - - QSize m_size; - QString m_className; - QString m_title; - Surface *m_transientParent; - bool m_transientInactive; - QPointF m_transientOffset; - bool m_isCursorSurface; - bool m_destroyed; - Qt::ScreenOrientation m_contentOrientation; - QWindow::Visibility m_visibility; - - const SurfaceRole *m_role; - RoleBase *m_roleHandler; - - void setBackBuffer(SurfaceBuffer *buffer); - SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer); - - friend class QWaylandSurface; - friend class RoleBase; -}; - -class SurfaceRole -{ -public: - const char *name; -}; - -class RoleBase -{ -public: - virtual ~RoleBase() { - if (m_surface) { - m_surface->m_roleHandler = 0; m_surface = 0; - } - } - -protected: - RoleBase() : m_surface(0) {} - static inline RoleBase *roleOf(Surface *s) { return s->m_roleHandler; } - - virtual void configure(int dx, int dy) = 0; - -private: - Surface *m_surface; - friend class Surface; -}; - -template<class T> -class SurfaceRoleHandler : public RoleBase -{ -public: - static T *get(Surface *surface) { - if (surface->role() == T::role()) { - return static_cast<T *>(roleOf(surface)); - } - return 0; - } -}; - -template<class T> -bool Surface::setRoleHandler(T *handler) -{ - RoleBase *base = handler; - if (m_role == T::role()) { - m_roleHandler = base; - base->m_surface = this; - return true; - } - return false; -} - -} - -QT_END_NAMESPACE - -#endif //WL_SURFACE_H diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp index 1229d286f..240ce01bc 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -40,9 +36,6 @@ #include "qwlsurfacebuffer_p.h" -#include "qwlsurface_p.h" -#include "qwlcompositor_p.h" - #ifdef QT_COMPOSITOR_WAYLAND_GL #include "hardware_integration/qwlclientbufferintegration_p.h" #include <qpa/qplatformopenglcontext.h> @@ -51,13 +44,15 @@ #include <QtCore/QDebug> #include <wayland-server-protocol.h> -#include "qwaylandshmformathelper.h" +#include "qwaylandshmformathelper_p.h" + +#include <QtWaylandCompositor/private/qwaylandcompositor_p.h> QT_BEGIN_NAMESPACE namespace QtWayland { -SurfaceBuffer::SurfaceBuffer(Surface *surface) +SurfaceBuffer::SurfaceBuffer(QWaylandSurface *surface) : m_surface(surface) , m_compositor(surface->compositor()) , m_buffer(0) @@ -66,14 +61,8 @@ SurfaceBuffer::SurfaceBuffer(Surface *surface) , m_surface_has_buffer(false) , m_destroyed(false) , m_is_displayed(false) - , m_texture(0) - , m_is_shm_resolved(false) - , m_shmBuffer(0) - , m_isSizeResolved(false) - , m_size() , m_used(false) , m_destroyIfUnused(false) - , m_image(0) { } @@ -86,81 +75,31 @@ SurfaceBuffer::~SurfaceBuffer() void SurfaceBuffer::initialize(struct ::wl_resource *buffer) { m_buffer = buffer; - m_texture = 0; m_committed = false; m_is_registered_for_buffer = true; m_surface_has_buffer = true; m_is_displayed = false; m_destroyed = false; - m_handle = 0; - m_is_shm_resolved = false; - m_shmBuffer = 0; - m_isSizeResolved = false; - m_size = QSize(); m_destroy_listener.surfaceBuffer = this; m_destroy_listener.listener.notify = destroy_listener_callback; if (buffer) { - ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); - hwIntegration->unlockNativeBuffer(m_handle); - hwIntegration->initialize(buffer); + if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) + integration->initializeBuffer(buffer); wl_signal_add(&buffer->destroy_signal, &m_destroy_listener.listener); } } void SurfaceBuffer::destructBufferState() { - destroyTexture(); if (m_buffer) { - sendRelease(); - - if (m_handle) { - if (m_shmBuffer) { - delete static_cast<QImage *>(m_handle); -#ifdef QT_COMPOSITOR_WAYLAND_GL - } else { - ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); - hwIntegration->unlockNativeBuffer(m_handle); -#endif - } - } + if (m_committed) + sendRelease(); wl_list_remove(&m_destroy_listener.listener.link); } m_buffer = 0; - m_handle = 0; m_committed = false; m_is_registered_for_buffer = false; m_is_displayed = false; - m_image = QImage(); -} - -QSize SurfaceBuffer::size() const -{ - if (!m_isSizeResolved) { - if (isShmBuffer()) { - m_size = QSize(wl_shm_buffer_get_width(m_shmBuffer), wl_shm_buffer_get_height(m_shmBuffer)); -#ifdef QT_COMPOSITOR_WAYLAND_GL - } else { - ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); - m_size = hwIntegration->bufferSize(m_buffer); -#endif - } - } - - return m_size; -} - -bool SurfaceBuffer::isShmBuffer() const -{ - if (!m_is_shm_resolved) { -#if (WAYLAND_VERSION_MAJOR >= 1) && (WAYLAND_VERSION_MINOR >= 2) - m_shmBuffer = wl_shm_buffer_get(m_buffer); -#else - if (wl_buffer_is_shm(static_cast<struct ::wl_buffer*>(m_buffer->data))) - m_shmBuffer = static_cast<struct ::wl_buffer*>(m_buffer->data); -#endif - m_is_shm_resolved = true; - } - return m_shmBuffer != 0; } void SurfaceBuffer::sendRelease() @@ -181,156 +120,130 @@ void SurfaceBuffer::setDisplayed() m_is_displayed = true; } -void SurfaceBuffer::destroyTexture() +void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, void *data) { -#ifdef QT_COMPOSITOR_WAYLAND_GL - if (m_texture) { - Q_ASSERT(QOpenGLContext::currentContext()); - ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); - if (hwIntegration->textureForBuffer(m_buffer) == 0) - glDeleteTextures(1, &m_texture); - else - hwIntegration->destroyTextureForBuffer(m_buffer, m_texture); - m_texture = 0; - } -#endif + Q_UNUSED(data); + struct surface_buffer_destroy_listener *destroy_listener = + reinterpret_cast<struct surface_buffer_destroy_listener *>(listener); + SurfaceBuffer *d = destroy_listener->surfaceBuffer; + + // Mark the buffer as destroyed and clear m_buffer right away to avoid + // touching it before it is properly cleaned up. + d->m_destroyed = true; + d->m_buffer = 0; } -uint SurfaceBuffer::textureTarget() const +void SurfaceBuffer::ref() { -#ifdef QT_COMPOSITOR_WAYLAND_GL - ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); - return hwIntegration->textureTargetForBuffer(m_buffer); -#endif - - return 0; + m_used = m_refCount.ref(); } -void SurfaceBuffer::handleAboutToBeDisplayed() +void SurfaceBuffer::deref() { - qDebug() << Q_FUNC_INFO; + m_used = m_refCount.deref(); + if (!m_used) + disown(); } -void SurfaceBuffer::handleDisplayed() +void SurfaceBuffer::setDestroyIfUnused(bool destroy) { - qDebug() << Q_FUNC_INFO; + m_destroyIfUnused = destroy; + destroyIfUnused(); } -void *SurfaceBuffer::handle() const +void SurfaceBuffer::destroyIfUnused() { - if (!m_buffer) - return 0; - - if (!m_handle) { - SurfaceBuffer *that = const_cast<SurfaceBuffer *>(this); - if (isShmBuffer()) { - const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer)); - int stride = wl_shm_buffer_get_stride(m_shmBuffer); - int width = wl_shm_buffer_get_width(m_shmBuffer); - int height = wl_shm_buffer_get_height(m_shmBuffer); - QImage *image = new QImage(data,width,height,stride, QImage::Format_ARGB32_Premultiplied); - that->m_handle = image; -#ifdef QT_COMPOSITOR_WAYLAND_GL - } else { - ClientBufferIntegration *clientBufferIntegration = m_compositor->clientBufferIntegration(); - that->m_handle = clientBufferIntegration->lockNativeBuffer(m_buffer); -#endif - } - } - return m_handle; + if (!m_used && m_destroyIfUnused) + delete this; } -QImage SurfaceBuffer::image() +QSize SurfaceBuffer::size() const { - /* This api may be available on non-shm buffer. But be sure about it's format. */ - if (!m_buffer || !isShmBuffer()) - return QImage(); - - if (m_image.isNull()) - { - const uchar *data = static_cast<const uchar *>(wl_shm_buffer_get_data(m_shmBuffer)); - int stride = wl_shm_buffer_get_stride(m_shmBuffer); - int width = wl_shm_buffer_get_width(m_shmBuffer); - int height = wl_shm_buffer_get_height(m_shmBuffer); - QImage::Format format = QWaylandShmFormatHelper::fromWaylandShmFormat(wl_shm_format(wl_shm_buffer_get_format(m_shmBuffer))); - m_image = QImage(data, width, height, stride, format); + if (!m_buffer) + return QSize(); + + if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) { + int width = wl_shm_buffer_get_width(shmBuffer); + int height = wl_shm_buffer_get_height(shmBuffer); + return QSize(width, height); + } + if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) { + return integration->bufferSize(m_buffer); } - return m_image; + return QSize(); } -void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, void *data) +QWaylandSurface::Origin SurfaceBuffer::origin() const { - Q_UNUSED(data); - struct surface_buffer_destroy_listener *destroy_listener = - reinterpret_cast<struct surface_buffer_destroy_listener *>(listener); - SurfaceBuffer *d = destroy_listener->surfaceBuffer; + if (isShm()) { + return QWaylandSurface::OriginTopLeft; + } - // Mark the buffer as destroyed and clear m_buffer right away to avoid - // touching it before it is properly cleaned up. - d->m_destroyed = true; - d->m_buffer = 0; + if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) { + return integration->origin(m_buffer); + } + return QWaylandSurface::OriginTopLeft; } -void SurfaceBuffer::createTexture() +QImage SurfaceBuffer::image() const { - destroyTexture(); + if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) { + int width = wl_shm_buffer_get_width(shmBuffer); + int height = wl_shm_buffer_get_height(shmBuffer); + int bytesPerLine = wl_shm_buffer_get_stride(shmBuffer); + uchar *data = static_cast<uchar *>(wl_shm_buffer_get_data(shmBuffer)); + return QImage(data, width, height, bytesPerLine, QImage::Format_ARGB32_Premultiplied); + } - ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); -#ifdef QT_COMPOSITOR_WAYLAND_GL - m_texture = hwIntegration->textureForBuffer(m_buffer); - hwIntegration->bindTextureToBuffer(m_buffer); -#else - Q_UNUSED(hwIntegration); -#endif + return QImage(); } -void SurfaceBuffer::updateTexture() +QWaylandBufferRef::BufferFormatEgl SurfaceBuffer::bufferFormatEgl() const { -#ifdef QT_COMPOSITOR_WAYLAND_GL - ClientBufferIntegration *hwIntegration = m_compositor->clientBufferIntegration(); - hwIntegration->updateTextureForBuffer(m_buffer); -#endif -} + Q_ASSERT(isShm() == false); -bool SurfaceBuffer::isYInverted() const -{ - bool ret = false; - static bool negateReturn = qgetenv("QT_COMPOSITOR_NEGATE_INVERTED_Y").toInt(); - ClientBufferIntegration *clientBufferIntegration = m_compositor->clientBufferIntegration(); - -#ifdef QT_COMPOSITOR_WAYLAND_GL - if (clientBufferIntegration && waylandBufferHandle() && !isShmBuffer()) { - ret = clientBufferIntegration->isYInverted(waylandBufferHandle()); - } else -#endif - ret = true; + if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) + return clientInt->bufferFormat(m_buffer); - return ret != negateReturn; + return QWaylandBufferRef::BufferFormatEgl_Null; } -void SurfaceBuffer::ref() +void SurfaceBuffer::bindToTexture() const { - m_used = m_refCount.ref(); + Q_ASSERT(m_compositor); + if (isShm()) { + QImage image = this->image(); + if (image.hasAlphaChannel()) { + if (image.format() != QImage::Format_RGBA8888) { + image = image.convertToFormat(QImage::Format_RGBA8888); + } + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits()); + } else { + if (image.format() != QImage::Format_RGBX8888) { + image = image.convertToFormat(QImage::Format_RGBX8888); + } + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits()); + } + } else { + if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) { + clientInt->bindTextureToBuffer(m_buffer); + } + } } -void SurfaceBuffer::deref() +uint SurfaceBuffer::textureForPlane(int plane) const { - m_used = m_refCount.deref(); - if (!m_used) - disown(); -} + if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) + return clientInt->textureForBuffer(m_buffer, plane); -void SurfaceBuffer::setDestroyIfUnused(bool destroy) -{ - m_destroyIfUnused = destroy; - destroyIfUnused(); + return 0; } -void SurfaceBuffer::destroyIfUnused() +void SurfaceBuffer::updateTexture() const { - if (!m_used && m_destroyIfUnused) - delete this; + if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) + clientInt->updateTextureForBuffer(m_buffer); } } diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h index 3401d218b..95e7e8158 100644 --- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h @@ -3,36 +3,32 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Compositor. +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. ** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later 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 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** @@ -57,18 +53,19 @@ #include <QImage> #include <QAtomicInt> +#include <QtWaylandCompositor/QWaylandSurface> +#include <QtWaylandCompositor/QWaylandBufferRef> + #include <wayland-server.h> QT_BEGIN_NAMESPACE class QWaylandClientBufferIntegration; class QWaylandBufferRef; +class QWaylandCompositor; namespace QtWayland { -class Surface; -class Compositor; - struct surface_buffer_destroy_listener { struct wl_listener listener; @@ -78,18 +75,13 @@ struct surface_buffer_destroy_listener class SurfaceBuffer { public: - SurfaceBuffer(Surface *surface); + SurfaceBuffer(QWaylandSurface *surface); ~SurfaceBuffer(); void initialize(struct ::wl_resource *bufferResource); void destructBufferState(); - QSize size() const; - - bool isShmBuffer() const; - bool isYInverted() const; - inline bool isRegisteredWithBuffer() const { return m_is_registered_for_buffer; } void sendRelease(); @@ -97,43 +89,36 @@ public: void setDisplayed(); - inline bool isComitted() const { return m_committed; } + inline bool isCommitted() const { return m_committed; } inline void setCommitted() { m_committed = true; } inline bool isDisplayed() const { return m_is_displayed; } - inline bool textureCreated() const { return m_texture; } - bool isDestroyed() { return m_destroyed; } - void createTexture(); - uint textureTarget() const; - void updateTexture(); -#ifdef QT_COMPOSITOR_WAYLAND_GL - inline GLuint texture() const; -#else - inline uint texture() const; -#endif - - void destroyTexture(); - inline struct ::wl_resource *waylandBufferHandle() const { return m_buffer; } - void handleAboutToBeDisplayed(); - void handleDisplayed(); - - void bufferWasDestroyed(); void setDestroyIfUnused(bool destroy); - void *handle() const; - QImage image(); + QSize size() const; + QWaylandSurface::Origin origin() const; + bool isShm() const { return wl_shm_buffer_get(m_buffer); } + + QImage image() const; + QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const; + void bindToTexture() const; + uint textureForPlane(int plane) const; + void updateTexture() const; + + static bool hasContent(SurfaceBuffer *buffer) { return buffer && buffer->waylandBufferHandle(); } private: void ref(); void deref(); void destroyIfUnused(); - Surface *m_surface; - Compositor *m_compositor; + QWaylandSurface *m_surface; + QWaylandCompositor *m_compositor; struct ::wl_resource *m_buffer; + int m_bufferScale; struct surface_buffer_destroy_listener m_destroy_listener; bool m_committed; bool m_is_registered_for_buffer; @@ -141,47 +126,16 @@ private: bool m_destroyed; bool m_is_displayed; -#ifdef QT_COMPOSITOR_WAYLAND_GL - GLuint m_texture; -#else - uint m_texture; -#endif - void *m_handle; - mutable bool m_is_shm_resolved; - -#if (WAYLAND_VERSION_MAJOR >= 1) && (WAYLAND_VERSION_MINOR >= 2) - mutable struct ::wl_shm_buffer *m_shmBuffer; -#else - mutable struct ::wl_buffer *m_shmBuffer; -#endif - - mutable bool m_isSizeResolved; - mutable QSize m_size; + QAtomicInt m_refCount; bool m_used; bool m_destroyIfUnused; - QImage m_image; - static void destroy_listener_callback(wl_listener *listener, void *data); friend class ::QWaylandBufferRef; }; -#ifdef QT_COMPOSITOR_WAYLAND_GL -GLuint SurfaceBuffer::texture() const -{ - if (m_buffer) - return m_texture; - return 0; -} -#else -uint SurfaceBuffer::texture() const -{ - return 0; -} -#endif - } QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwltextinput.cpp b/src/compositor/wayland_wrapper/qwltextinput.cpp deleted file mode 100644 index 992ca0dc5..000000000 --- a/src/compositor/wayland_wrapper/qwltextinput.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwltextinput_p.h" - -#include "qwlcompositor_p.h" -#include "qwlinputdevice_p.h" -#include "qwlinputmethod_p.h" -#include "qwlinputmethodcontext_p.h" -#include "qwlinputpanel_p.h" -#include "qwlsurface_p.h" - -#include <algorithm> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -TextInput::TextInput(Compositor *compositor, struct ::wl_client *client, int id) - : wl_text_input(client, id, 1) - , m_compositor(compositor) - , m_focus() - , m_inputPanelVisible() - , m_cursorRectangle() -{ -} - -Surface *TextInput::focus() const -{ - return m_focus; -} - -bool TextInput::inputPanelVisible() const -{ - return m_inputPanelVisible; -} - -QRect TextInput::cursorRectangle() const -{ - return m_cursorRectangle; -} - -void TextInput::deactivate(InputMethod *inputMethod) -{ - if (m_activeInputMethods.removeOne(inputMethod)) - inputMethod->deactivate(); - - if (m_activeInputMethods.isEmpty()) - send_leave(); -} - -void TextInput::text_input_destroy_resource(Resource *) -{ - Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { - deactivate(inputMethod); - } - - delete this; -} - -void TextInput::text_input_activate(Resource *, wl_resource *seat, wl_resource *surface) -{ - Surface *oldSurface = m_focus; - m_focus = Surface::fromResource(surface); - - if (oldSurface != m_focus) - send_leave(); - - bool wasEmpty = m_activeInputMethods.isEmpty(); - - InputMethod *inputMethod = InputDevice::fromSeatResource(seat)->inputMethod(); - - if (!m_activeInputMethods.contains(inputMethod)) { - m_activeInputMethods.append(inputMethod); - inputMethod->activate(this); - } - - if (wasEmpty || oldSurface != m_focus) - send_enter(surface); -} - -void TextInput::text_input_deactivate(Resource *, wl_resource *seat) -{ - InputMethod *inputMethod = InputDevice::fromSeatResource(seat)->inputMethod(); - - deactivate(inputMethod); -} - -static bool isInputMethodBound(InputMethod *inputMethod) -{ - return inputMethod->isBound(); -} - -void TextInput::text_input_show_input_panel(Resource *) -{ - m_inputPanelVisible = true; - - if (std::find_if(m_activeInputMethods.cbegin(), m_activeInputMethods.cend(), isInputMethodBound) != m_activeInputMethods.cend()) - m_compositor->inputPanel()->setInputPanelVisible(true); -} - -void TextInput::text_input_hide_input_panel(Resource *) -{ - m_inputPanelVisible = false; - - if (std::find_if(m_activeInputMethods.cbegin(), m_activeInputMethods.cend(), isInputMethodBound) != m_activeInputMethods.cend()) - m_compositor->inputPanel()->setInputPanelVisible(false); -} - -void TextInput::text_input_set_cursor_rectangle(Resource *, int32_t x, int32_t y, int32_t width, int32_t height) -{ - m_cursorRectangle = QRect(x, y, width, height); - - if (!m_activeInputMethods.isEmpty()) - m_compositor->inputPanel()->setCursorRectangle(m_cursorRectangle); -} - -void TextInput::text_input_reset(Resource *) -{ - Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { - if (inputMethod->context()) - inputMethod->context()->send_reset(); - } -} - -void TextInput::text_input_commit_state(Resource *, uint32_t serial) -{ - Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { - if (inputMethod->context()) - inputMethod->context()->send_commit_state(serial); - } -} - -void TextInput::text_input_set_content_type(Resource *, uint32_t hint, uint32_t purpose) -{ - Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { - if (inputMethod->context()) - inputMethod->context()->send_content_type(hint, purpose); - } -} - -void TextInput::text_input_set_preferred_language(Resource *, const QString &language) -{ - Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { - if (inputMethod->context()) - inputMethod->context()->send_preferred_language(language); - } -} - -void TextInput::text_input_set_surrounding_text(Resource *, const QString &text, uint32_t cursor, uint32_t anchor) -{ - Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { - if (inputMethod->context()) - inputMethod->context()->send_surrounding_text(text, cursor, anchor); - } -} - -void TextInput::text_input_invoke_action(Resource *, uint32_t button, uint32_t index) -{ - Q_FOREACH (InputMethod *inputMethod, m_activeInputMethods) { - if (inputMethod->context()) - inputMethod->context()->send_invoke_action(button, index); - } -} - -} // namespace QtWayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwltextinput_p.h b/src/compositor/wayland_wrapper/qwltextinput_p.h deleted file mode 100644 index da09bca4f..000000000 --- a/src/compositor/wayland_wrapper/qwltextinput_p.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLTEXTINPUT_P_H -#define QTWAYLAND_QWLTEXTINPUT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/private/qwayland-server-text.h> - -#include <QRect> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -class Compositor; -class InputMethod; -class Surface; - -class TextInput : public QtWaylandServer::wl_text_input -{ -public: - explicit TextInput(Compositor *compositor, struct ::wl_client *client, int id); - - Surface *focus() const; - - bool inputPanelVisible() const; - QRect cursorRectangle() const; - - void deactivate(InputMethod *inputMethod); - -protected: - void text_input_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - - void text_input_activate(Resource *resource, wl_resource *seat, wl_resource *surface) Q_DECL_OVERRIDE; - void text_input_deactivate(Resource *resource, wl_resource *seat) Q_DECL_OVERRIDE; - void text_input_show_input_panel(Resource *resource) Q_DECL_OVERRIDE; - void text_input_hide_input_panel(Resource *resource) Q_DECL_OVERRIDE; - void text_input_reset(Resource *resource) Q_DECL_OVERRIDE; - void text_input_commit_state(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; - void text_input_set_content_type(Resource *resource, uint32_t hint, uint32_t purpose) Q_DECL_OVERRIDE; - void text_input_set_cursor_rectangle(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) Q_DECL_OVERRIDE; - void text_input_set_preferred_language(Resource *resource, const QString &language) Q_DECL_OVERRIDE; - void text_input_set_surrounding_text(Resource *resource, const QString &text, uint32_t cursor, uint32_t anchor) Q_DECL_OVERRIDE; - void text_input_invoke_action(Resource *resource, uint32_t button, uint32_t index) Q_DECL_OVERRIDE; - -private: - Compositor *m_compositor; - QList<InputMethod*> m_activeInputMethods; - Surface *m_focus; - - bool m_inputPanelVisible; - QRect m_cursorRectangle; - -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLTEXTINPUT_P_H diff --git a/src/compositor/wayland_wrapper/qwltextinputmanager.cpp b/src/compositor/wayland_wrapper/qwltextinputmanager.cpp deleted file mode 100644 index ce16f01c9..000000000 --- a/src/compositor/wayland_wrapper/qwltextinputmanager.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwltextinputmanager_p.h" - -#include "qwlcompositor_p.h" -#include "qwltextinput_p.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -TextInputManager::TextInputManager(Compositor *compositor) - : QtWaylandServer::wl_text_input_manager(compositor->wl_display(), 1) - , m_compositor(compositor) -{ -} - -TextInputManager::~TextInputManager() -{ -} - -void TextInputManager::text_input_manager_create_text_input(Resource *resource, uint32_t id) -{ - new TextInput(m_compositor, resource->client(), id); -} - -} // namespace QtWayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwltextinputmanager_p.h b/src/compositor/wayland_wrapper/qwltextinputmanager_p.h deleted file mode 100644 index 4cb088e93..000000000 --- a/src/compositor/wayland_wrapper/qwltextinputmanager_p.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLTEXTINPUTMANAGER_P_H -#define QTWAYLAND_QWLTEXTINPUTMANAGER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/private/qwayland-server-text.h> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -class Compositor; - -class TextInputManager : public QtWaylandServer::wl_text_input_manager -{ -public: - TextInputManager(Compositor *compositor); - ~TextInputManager(); - -protected: - void text_input_manager_create_text_input(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; - -private: - Compositor *m_compositor; -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLTEXTINPUTMANAGER_P_H diff --git a/src/compositor/wayland_wrapper/qwltouch.cpp b/src/compositor/wayland_wrapper/qwltouch.cpp deleted file mode 100644 index d15988940..000000000 --- a/src/compositor/wayland_wrapper/qwltouch.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwltouch_p.h" - -#include "qwlcompositor_p.h" -#include "qwlsurface_p.h" -#include "qwaylandsurfaceview.h" - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -Touch::Touch(Compositor *compositor) - : wl_touch() - , m_compositor(compositor) - , m_focus() - , m_focusResource() - , m_grab(this) -{ - m_grab->setTouch(this); - connect(&m_focusDestroyListener, &WlListener::fired, this, &Touch::focusDestroyed); -} - -void Touch::setFocus(QWaylandSurfaceView *surface) -{ - m_focusDestroyListener.reset(); - if (surface) - m_focusDestroyListener.listenForDestruction(surface->surface()->handle()->resource()->handle); - - m_focus = surface; - m_focusResource = surface ? resourceMap().value(surface->surface()->handle()->resource()->client()) : 0; -} - -void Touch::startGrab(TouchGrabber *grab) -{ - m_grab = grab; - grab->setTouch(this); -} - -void Touch::endGrab() -{ - m_grab = this; -} - -void Touch::focusDestroyed(void *data) -{ - Q_UNUSED(data) - m_focusDestroyListener.reset(); - - m_focus = 0; - m_focusResource = 0; -} - -void Touch::touch_destroy_resource(Resource *resource) -{ - if (m_focusResource == resource) - m_focusResource = 0; -} - -void Touch::touch_release(Resource *resource) -{ - wl_resource_destroy(resource->handle); -} - -void Touch::sendCancel() -{ - if (m_focusResource) - send_cancel(m_focusResource->handle); -} - -void Touch::sendFrame() -{ - if (m_focusResource) - send_frame(m_focusResource->handle); -} - -void Touch::sendDown(int touch_id, const QPointF &position) -{ - m_grab->down(m_compositor->currentTimeMsecs(), touch_id, position); -} - -void Touch::sendMotion(int touch_id, const QPointF &position) -{ - m_grab->motion(m_compositor->currentTimeMsecs(), touch_id, position); -} - -void Touch::sendUp(int touch_id) -{ - m_grab->up(m_compositor->currentTimeMsecs(), touch_id); -} - -void Touch::down(uint32_t time, int touch_id, const QPointF &position) -{ - if (!m_focusResource || !m_focus) - return; - - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - - send_down(m_focusResource->handle, serial, time, m_focus->surface()->handle()->resource()->handle, touch_id, - wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); -} - -void Touch::up(uint32_t time, int touch_id) -{ - if (!m_focusResource) - return; - - uint32_t serial = wl_display_next_serial(m_compositor->wl_display()); - - send_up(m_focusResource->handle, serial, time, touch_id); -} - -void Touch::motion(uint32_t time, int touch_id, const QPointF &position) -{ - if (!m_focusResource) - return; - - send_motion(m_focusResource->handle, time, touch_id, - wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y())); -} - -TouchGrabber::TouchGrabber() - : m_touch(0) -{ -} - -TouchGrabber::~TouchGrabber() -{ -} - -const Touch *TouchGrabber::touch() const -{ - return m_touch; -} - -Touch *TouchGrabber::touch() -{ - return m_touch; -} - -void TouchGrabber::setTouch(Touch *touch) -{ - m_touch = touch; -} - -} // namespace QtWayland - -QT_END_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwltouch_p.h b/src/compositor/wayland_wrapper/qwltouch_p.h deleted file mode 100644 index febfb9303..000000000 --- a/src/compositor/wayland_wrapper/qwltouch_p.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB). -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTWAYLAND_QWLTOUCH_P_H -#define QTWAYLAND_QWLTOUCH_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> - -#include <QtCore/QPoint> -#include <QtCore/QObject> - -#include <QtCompositor/private/qwayland-server-wayland.h> - -#include "qwllistener_p.h" - -QT_BEGIN_NAMESPACE - -class QWaylandSurfaceView; - -namespace QtWayland { - -class Compositor; -class Surface; -class Touch; - -class Q_COMPOSITOR_EXPORT TouchGrabber { -public: - TouchGrabber(); - virtual ~TouchGrabber(); - - virtual void down(uint32_t time, int touch_id, const QPointF &position) = 0; - virtual void up(uint32_t time, int touch_id) = 0; - virtual void motion(uint32_t time, int touch_id, const QPointF &position) = 0; - - const Touch *touch() const; - Touch *touch(); - void setTouch(Touch *touch); - -private: - Touch *m_touch; -}; - -class Q_COMPOSITOR_EXPORT Touch : public QObject, public QtWaylandServer::wl_touch, public TouchGrabber -{ -public: - explicit Touch(Compositor *compositor); - - void setFocus(QWaylandSurfaceView *surface); - - void startGrab(TouchGrabber *grab); - void endGrab(); - - void sendCancel(); - void sendFrame(); - - void sendDown(int touch_id, const QPointF &position); - void sendMotion(int touch_id, const QPointF &position); - void sendUp(int touch_id); - - void down(uint32_t time, int touch_id, const QPointF &position); - void up(uint32_t time, int touch_id); - void motion(uint32_t time, int touch_id, const QPointF &position); - -private: - void focusDestroyed(void *data); - void touch_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - void touch_release(Resource *resource) Q_DECL_OVERRIDE; - - Compositor *m_compositor; - - QWaylandSurfaceView *m_focus; - Resource *m_focusResource; - WlListener m_focusDestroyListener; - - TouchGrabber *m_grab; -}; - -} // namespace QtWayland - -QT_END_NAMESPACE - -#endif // QTWAYLAND_QWLTOUCH_P_H diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri index eb66f6949..f338ddc05 100644 --- a/src/compositor/wayland_wrapper/wayland_wrapper.pri +++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri @@ -1,70 +1,23 @@ CONFIG += wayland-scanner WAYLANDSERVERSOURCES += \ - ../extensions/surface-extension.xml \ - ../extensions/sub-surface-extension.xml \ - ../extensions/touch-extension.xml \ - ../extensions/qtkey-extension.xml \ - ../extensions/windowmanager.xml \ ../3rdparty/protocol/wayland.xml \ - ../3rdparty/protocol/input-method.xml \ - ../3rdparty/protocol/text.xml HEADERS += \ - wayland_wrapper/qwlcompositor_p.h \ wayland_wrapper/qwldatadevice_p.h \ wayland_wrapper/qwldatadevicemanager_p.h \ wayland_wrapper/qwldataoffer_p.h \ wayland_wrapper/qwldatasource_p.h \ - wayland_wrapper/qwldisplay_p.h \ - wayland_wrapper/qwlextendedsurface_p.h \ - wayland_wrapper/qwlinputdevice_p.h \ - wayland_wrapper/qwlinputmethod_p.h \ - wayland_wrapper/qwlinputmethodcontext_p.h \ - wayland_wrapper/qwlinputpanel_p.h \ - wayland_wrapper/qwlinputpanelsurface_p.h \ - wayland_wrapper/qwlkeyboard_p.h \ - wayland_wrapper/qwloutput_p.h \ - wayland_wrapper/qwlpointer_p.h \ - wayland_wrapper/qwlqtkey_p.h \ - wayland_wrapper/qwlqttouch_p.h \ wayland_wrapper/qwlregion_p.h \ - wayland_wrapper/qwlshellsurface_p.h \ - wayland_wrapper/qwlsubsurface_p.h \ - wayland_wrapper/qwlsurface_p.h \ wayland_wrapper/qwlsurfacebuffer_p.h \ - wayland_wrapper/qwltextinput_p.h \ - wayland_wrapper/qwltextinputmanager_p.h \ - wayland_wrapper/qwltouch_p.h \ - wayland_wrapper/qwllistener_p.h \ - ../shared/qwaylandxkb.h \ + ../shared/qwaylandxkb_p.h \ SOURCES += \ - wayland_wrapper/qwlcompositor.cpp \ wayland_wrapper/qwldatadevice.cpp \ wayland_wrapper/qwldatadevicemanager.cpp \ wayland_wrapper/qwldataoffer.cpp \ wayland_wrapper/qwldatasource.cpp \ - wayland_wrapper/qwldisplay.cpp \ - wayland_wrapper/qwlextendedsurface.cpp \ - wayland_wrapper/qwlinputdevice.cpp \ - wayland_wrapper/qwlinputmethod.cpp \ - wayland_wrapper/qwlinputmethodcontext.cpp \ - wayland_wrapper/qwlinputpanel.cpp \ - wayland_wrapper/qwlinputpanelsurface.cpp \ - wayland_wrapper/qwlkeyboard.cpp \ - wayland_wrapper/qwloutput.cpp \ - wayland_wrapper/qwlpointer.cpp \ - wayland_wrapper/qwlqtkey.cpp \ - wayland_wrapper/qwlqttouch.cpp \ wayland_wrapper/qwlregion.cpp \ - wayland_wrapper/qwlshellsurface.cpp \ - wayland_wrapper/qwlsubsurface.cpp \ - wayland_wrapper/qwlsurface.cpp \ wayland_wrapper/qwlsurfacebuffer.cpp \ - wayland_wrapper/qwltextinput.cpp \ - wayland_wrapper/qwltextinputmanager.cpp \ - wayland_wrapper/qwltouch.cpp \ - wayland_wrapper/qwllistener.cpp \ ../shared/qwaylandxkb.cpp \ INCLUDEPATH += wayland_wrapper diff --git a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp deleted file mode 100644 index 25e0419e9..000000000 --- a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <windowmanagerprotocol/waylandwindowmanagerintegration_p.h> - -#include <wayland_wrapper/qwldisplay_p.h> -#include <wayland_wrapper/qwlcompositor_p.h> - -#include <compositor_api/qwaylandclient.h> -#include <compositor_api/qwaylandcompositor.h> - -#include <wayland-server.h> - -#include <QUrl> - -QT_BEGIN_NAMESPACE - -WindowManagerServerIntegration::WindowManagerServerIntegration(QWaylandCompositor *compositor, QObject *parent) - : QObject(parent) - , QtWaylandServer::qt_windowmanager() - , m_showIsFullScreen(false) - , m_compositor(compositor) -{ -} - -WindowManagerServerIntegration::~WindowManagerServerIntegration() -{ -} - -void WindowManagerServerIntegration::initialize(QtWayland::Display *waylandDisplay) -{ - init(waylandDisplay->handle(), 1); -} - -void WindowManagerServerIntegration::setShowIsFullScreen(bool value) -{ - m_showIsFullScreen = value; - Q_FOREACH (Resource *resource, resourceMap().values()) { - send_hints(resource->handle, static_cast<int32_t>(m_showIsFullScreen)); - } -} - -void WindowManagerServerIntegration::sendQuitMessage(wl_client *client) -{ - Resource *resource = resourceMap().value(client); - - if (resource) - send_quit(resource->handle); -} - -void WindowManagerServerIntegration::windowmanager_bind_resource(Resource *resource) -{ - send_hints(resource->handle, static_cast<int32_t>(m_showIsFullScreen)); -} - -void WindowManagerServerIntegration::windowmanager_destroy_resource(Resource *resource) -{ - m_urls.remove(resource); -} - -void WindowManagerServerIntegration::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl) -{ - QString url = m_urls.value(resource, QString()); - - url.append(newUrl); - - if (remaining) - m_urls.insert(resource, url); - else { - m_urls.remove(resource); - m_compositor->openUrl(QWaylandClient::fromWlClient(resource->client()), QUrl(url)); - } -} - -QT_END_NAMESPACE diff --git a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration_p.h b/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration_p.h deleted file mode 100644 index 895f35b59..000000000 --- a/src/compositor/windowmanagerprotocol/waylandwindowmanagerintegration_p.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WAYLANDWINDOWMANAGERINTEGRATION_H -#define WAYLANDWINDOWMANAGERINTEGRATION_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCompositor/qwaylandexport.h> -#include <QtCompositor/private/qwayland-server-windowmanager.h> - -#include <QObject> -#include <QMap> - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - class Display; -} - -class QWaylandCompositor; - -class Q_COMPOSITOR_EXPORT WindowManagerServerIntegration : public QObject, public QtWaylandServer::qt_windowmanager -{ - Q_OBJECT -public: - explicit WindowManagerServerIntegration(QWaylandCompositor *compositor, QObject *parent = Q_NULLPTR); - ~WindowManagerServerIntegration(); - - void initialize(QtWayland::Display *waylandDisplay); - - void setShowIsFullScreen(bool value); - void sendQuitMessage(wl_client *client); - -protected: - void windowmanager_bind_resource(Resource *resource) Q_DECL_OVERRIDE; - void windowmanager_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - void windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &url) Q_DECL_OVERRIDE; - -private: - bool m_showIsFullScreen; - QWaylandCompositor *m_compositor; - QMap<Resource*, QString> m_urls; -}; - -QT_END_NAMESPACE - -#endif // WAYLANDWINDOWMANAGERINTEGRATION_H diff --git a/src/compositor/windowmanagerprotocol/windowmanagerprotocol.pri b/src/compositor/windowmanagerprotocol/windowmanagerprotocol.pri deleted file mode 100644 index da3f2529c..000000000 --- a/src/compositor/windowmanagerprotocol/windowmanagerprotocol.pri +++ /dev/null @@ -1,9 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - windowmanagerprotocol/waylandwindowmanagerintegration_p.h - -SOURCES += \ - windowmanagerprotocol/waylandwindowmanagerintegration.cpp - - |