summaryrefslogtreecommitdiffstats
path: root/src/compositor/extensions
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@theqtcompany.com>2015-07-30 14:53:35 +0200
committerJørgen Lind <jorgen.lind@theqtcompany.com>2015-08-28 13:09:42 +0200
commitce58545b220a49354533a27ef79cdbc8d50186cd (patch)
tree660232f61bc971d68c29b37acfa9c709f617c697 /src/compositor/extensions
parent5edaac978e01ead8648aad91f0d050748f7a8915 (diff)
Rework how we manage extensions
Diffstat (limited to 'src/compositor/extensions')
-rw-r--r--src/compositor/extensions/extensions.pri33
-rw-r--r--src/compositor/extensions/qwaylandwindowmanagerextension.cpp108
-rw-r--r--src/compositor/extensions/qwaylandwindowmanagerextension.h80
-rw-r--r--src/compositor/extensions/qwlextendedsurface.cpp192
-rw-r--r--src/compositor/extensions/qwlextendedsurface_p.h150
-rw-r--r--src/compositor/extensions/qwlinputpanel.cpp136
-rw-r--r--src/compositor/extensions/qwlinputpanel_p.h91
-rw-r--r--src/compositor/extensions/qwlinputpanelsurface.cpp87
-rw-r--r--src/compositor/extensions/qwlinputpanelsurface_p.h83
-rw-r--r--src/compositor/extensions/qwlqtkey.cpp83
-rw-r--r--src/compositor/extensions/qwlqtkey_p.h73
-rw-r--r--src/compositor/extensions/qwlqttouch.cpp172
-rw-r--r--src/compositor/extensions/qwlqttouch_p.h96
-rw-r--r--src/compositor/extensions/qwlshellsurface.cpp567
-rw-r--r--src/compositor/extensions/qwlshellsurface_p.h244
-rw-r--r--src/compositor/extensions/qwlsubsurface.cpp161
-rw-r--r--src/compositor/extensions/qwlsubsurface_p.h114
-rw-r--r--src/compositor/extensions/qwltextinput.cpp211
-rw-r--r--src/compositor/extensions/qwltextinput_p.h95
-rw-r--r--src/compositor/extensions/qwltextinputmanager.cpp64
-rw-r--r--src/compositor/extensions/qwltextinputmanager_p.h68
21 files changed, 2908 insertions, 0 deletions
diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri
new file mode 100644
index 000000000..070c319c2
--- /dev/null
+++ b/src/compositor/extensions/extensions.pri
@@ -0,0 +1,33 @@
+CONFIG += wayland-scanner
+WAYLANDSERVERSOURCES += \
+ ../extensions/sub-surface-extension.xml \
+ ../extensions/surface-extension.xml \
+ ../extensions/touch-extension.xml \
+ ../extensions/qtkey-extension.xml \
+ ../extensions/windowmanager.xml \
+
+HEADERS += \
+ extensions/qwlextendedsurface_p.h \
+ extensions/qwlsubsurface_p.h \
+ extensions/qwlqttouch_p.h \
+ extensions/qwlqtkey_p.h \
+ extensions/qwlshellsurface_p.h \
+ extensions/qwaylandwindowmanagerextension.h \
+ extensions/qwltextinput_p.h \
+ extensions/qwltextinputmanager_p.h \
+ extensions/qwlinputpanel_p.h \
+ extensions/qwlinputpanelsurface_p.h \
+
+SOURCES += \
+ extensions/qwlextendedsurface.cpp \
+ extensions/qwlsubsurface.cpp \
+ extensions/qwlqttouch.cpp \
+ extensions/qwlqtkey.cpp \
+ extensions/qwlshellsurface.cpp \
+ extensions/qwaylandwindowmanagerextension.cpp \
+ extensions/qwltextinput.cpp \
+ extensions/qwltextinputmanager.cpp \
+ extensions/qwlinputpanel.cpp \
+ extensions/qwlinputpanelsurface.cpp \
+
+INCLUDEPATH += extensions
diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.cpp b/src/compositor/extensions/qwaylandwindowmanagerextension.cpp
new file mode 100644
index 000000000..160fb690f
--- /dev/null
+++ b/src/compositor/extensions/qwaylandwindowmanagerextension.cpp
@@ -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$
+**
+****************************************************************************/
+
+#include "qwaylandwindowmanagerextension.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)
+ : QWaylandExtension(compositor)
+ , 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/extensions/qwaylandwindowmanagerextension.h b/src/compositor/extensions/qwaylandwindowmanagerextension.h
new file mode 100644
index 000000000..5cd64e06d
--- /dev/null
+++ b/src/compositor/extensions/qwaylandwindowmanagerextension.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 WAYLANDWINDOWMANAGERINTEGRATION_H
+#define WAYLANDWINDOWMANAGERINTEGRATION_H
+
+#include <QtCompositor/qwaylandexport.h>
+#include <QtCompositor/private/qwayland-server-windowmanager.h>
+
+#include <QtCompositor/QWaylandExtension>
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+ class Display;
+}
+
+class QWaylandCompositor;
+
+class Q_COMPOSITOR_EXPORT WindowManagerServerIntegration : public QWaylandExtension, public QtWaylandServer::qt_windowmanager
+{
+ Q_OBJECT
+public:
+ explicit WindowManagerServerIntegration(QWaylandCompositor *compositor, QObject *parent = 0);
+ ~WindowManagerServerIntegration();
+
+ void initialize(QtWayland::Display *waylandDisplay);
+
+ void setShowIsFullScreen(bool value);
+ void sendQuitMessage(wl_client *client);
+
+ const wl_interface *interface() const Q_DECL_OVERRIDE { return QtWaylandServer::qt_windowmanager::interface(); }
+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/extensions/qwlextendedsurface.cpp b/src/compositor/extensions/qwlextendedsurface.cpp
new file mode 100644
index 000000000..42c100531
--- /dev/null
+++ b/src/compositor/extensions/qwlextendedsurface.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** 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 "qwlextendedsurface_p.h"
+
+#include "qwlcompositor_p.h"
+#include "qwlsurface_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+SurfaceExtensionGlobal::SurfaceExtensionGlobal(Compositor *compositor)
+ : QWaylandExtension(compositor->waylandCompositor())
+ , QtWaylandServer::qt_surface_extension(compositor->wl_display(), 1)
+{
+}
+
+void SurfaceExtensionGlobal::surface_extension_get_extended_surface(Resource *resource,
+ 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);
+}
+
+ExtendedSurface *ExtendedSurface::get(QWaylandSurface *surface)
+{
+ return static_cast<ExtendedSurface *>(surface->extension(qt_extended_surface::name()));
+}
+
+ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, int version, Surface *surface)
+ : QWaylandExtension(surface->waylandSurface())
+ , QtWaylandServer::qt_extended_surface(client, id, version)
+ , m_surface(surface)
+ , m_windowFlags(0)
+{
+}
+
+ExtendedSurface::~ExtendedSurface()
+{
+}
+
+void ExtendedSurface::sendGenericProperty(const QString &name, const QVariant &variant)
+{
+ QByteArray byteValue;
+ QDataStream ds(&byteValue, QIODevice::WriteOnly);
+ ds << variant;
+ send_set_generic_property(name, byteValue);
+
+}
+
+void ExtendedSurface::sendOnScreenVisibilityChange(bool onScreen)
+{
+ setVisibility(onScreen ? QWindow::AutomaticVisibility : QWindow::Hidden);
+}
+
+void ExtendedSurface::setVisibility(QWindow::Visibility visibility)
+{
+ send_onscreen_visibility(visibility);
+}
+
+void ExtendedSurface::setParentSurface(Surface *surface)
+{
+ m_surface = surface;
+}
+
+void ExtendedSurface::extended_surface_update_generic_property(Resource *resource,
+ const QString &name,
+ struct wl_array *value)
+{
+ Q_UNUSED(resource);
+ QVariant variantValue;
+ QByteArray byteValue((const char*)value->data, value->size);
+ QDataStream ds(&byteValue, QIODevice::ReadOnly);
+ ds >> variantValue;
+ setWindowPropertyImpl(name,variantValue);
+}
+
+Qt::ScreenOrientations ExtendedSurface::contentOrientationMask() const
+{
+ return m_contentOrientationMask;
+}
+
+void ExtendedSurface::extended_surface_set_content_orientation_mask(Resource *resource, int32_t orientation)
+{
+ Q_UNUSED(resource);
+ Qt::ScreenOrientations mask = 0;
+ if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION)
+ mask |= Qt::PortraitOrientation;
+ if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION)
+ mask |= Qt::LandscapeOrientation;
+ if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION)
+ mask |= Qt::InvertedPortraitOrientation;
+ if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION)
+ mask |= Qt::InvertedLandscapeOrientation;
+ if (orientation & QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION)
+ mask |= Qt::PrimaryOrientation;
+
+ Qt::ScreenOrientations oldMask = m_contentOrientationMask;
+ m_contentOrientationMask = mask;
+
+ if (mask != oldMask)
+ emit contentOrientationMaskChanged();
+}
+
+QVariantMap ExtendedSurface::windowProperties() const
+{
+ return m_windowProperties;
+}
+
+QVariant ExtendedSurface::windowProperty(const QString &propertyName) const
+{
+ QVariantMap props = m_windowProperties;
+ return props.value(propertyName);
+}
+
+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);
+ emit windowPropertyChanged(name,value);
+}
+
+void ExtendedSurface::extended_surface_set_window_flags(Resource *resource, int32_t flags)
+{
+ Q_UNUSED(resource);
+ WindowFlags windowFlags(flags);
+ if (windowFlags == m_windowFlags)
+ return;
+ m_windowFlags = windowFlags;
+ emit windowFlagsChanged();
+}
+
+void ExtendedSurface::extended_surface_destroy_resource(Resource *)
+{
+ delete this;
+}
+
+void ExtendedSurface::extended_surface_raise(Resource *)
+{
+ if (m_surface)
+ emit m_surface->waylandSurface()->raiseRequested();
+}
+
+void ExtendedSurface::extended_surface_lower(Resource *)
+{
+ if (m_surface)
+ emit m_surface->waylandSurface()->lowerRequested();
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwlextendedsurface_p.h b/src/compositor/extensions/qwlextendedsurface_p.h
new file mode 100644
index 000000000..f0953b499
--- /dev/null
+++ b/src/compositor/extensions/qwlextendedsurface_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 WLEXTENDEDSURFACE_H
+#define WLEXTENDEDSURFACE_H
+
+#include <wayland-server.h>
+
+#include <QtCompositor/private/qwayland-server-surface-extension.h>
+#include <private/qwlsurface_p.h>
+#include <QtCompositor/qwaylandsurface.h>
+#include <QtCompositor/qwaylandextension.h>
+
+#include <QtCore/QVariant>
+#include <QtCore/QLinkedList>
+#include <QtGui/QWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandSurface;
+
+namespace QtWayland {
+
+class Compositor;
+
+class SurfaceExtensionGlobal : public QWaylandExtension, public QtWaylandServer::qt_surface_extension
+{
+public:
+ SurfaceExtensionGlobal(Compositor *compositor);
+
+ const wl_interface *interface() const Q_DECL_OVERRIDE { return QtWaylandServer::qt_surface_extension::interface(); }
+
+private:
+ void surface_extension_get_extended_surface(Resource *resource,
+ uint32_t id,
+ struct wl_resource *surface);
+
+};
+
+class Q_COMPOSITOR_EXPORT ExtendedSurface : public QWaylandExtension, 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)
+
+ static ExtendedSurface *get(QWaylandSurface *surface);
+
+ ExtendedSurface(struct wl_client *client, uint32_t id, int version, Surface *surface);
+ ~ExtendedSurface();
+
+ void sendGenericProperty(const QString &name, const QVariant &variant);
+
+ void sendOnScreenVisibilityChange(bool onScreen);
+ 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;
+
+ WindowFlags windowFlags() const { return m_windowFlags; }
+
+ QVariantMap windowProperties() const;
+ QVariant windowProperty(const QString &propertyName) const;
+ void setWindowProperty(const QString &name, const QVariant &value);
+
+ const wl_interface *interface() const Q_DECL_OVERRIDE { return QtWaylandServer::qt_extended_surface::interface(); }
+
+signals:
+ void contentOrientationMaskChanged();
+ void windowFlagsChanged();
+ void windowPropertyChanged(const QString &name, const QVariant &value);
+
+private:
+ void setWindowPropertyImpl(const QString &name, const QVariant &value);
+
+ Surface *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/qwlinputpanel.cpp b/src/compositor/extensions/qwlinputpanel.cpp
new file mode 100644
index 000000000..d1c6ab825
--- /dev/null
+++ b/src/compositor/extensions/qwlinputpanel.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** 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 "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
+
+QWaylandInputPanelPrivate::QWaylandInputPanelPrivate(QtWayland::Compositor *compositor)
+ : QWaylandExtensionTemplatePrivateImpl(compositor->waylandCompositor())
+ , m_compositor(compositor)
+ , m_focus()
+ , m_inputPanelVisible(false)
+ , m_cursorRectangle()
+{
+ init(compositor->wl_display(), 1);
+}
+
+QWaylandInputPanelPrivate::~QWaylandInputPanelPrivate()
+{
+}
+
+QWaylandInputPanel *QWaylandInputPanelPrivate::waylandInputPanel() const
+{
+ QWaylandInputPanel *panel = const_cast<QWaylandInputPanel *>(q_func());
+ return panel;
+}
+
+QtWayland::Surface *QWaylandInputPanelPrivate::focus() const
+{
+ return m_focus;
+}
+
+void QWaylandInputPanelPrivate::setFocus(QtWayland::Surface *focus)
+{
+ Q_Q(QWaylandInputPanel);
+ if (m_focus == focus)
+ return;
+
+ m_focus = focus;
+
+ Q_EMIT q->focusChanged();
+}
+
+bool QWaylandInputPanelPrivate::inputPanelVisible() const
+{
+ return m_inputPanelVisible;
+}
+
+void QWaylandInputPanelPrivate::setInputPanelVisible(bool inputPanelVisible)
+{
+ Q_Q(QWaylandInputPanel);
+ if (m_inputPanelVisible == inputPanelVisible)
+ return;
+
+ m_inputPanelVisible = inputPanelVisible;
+
+ q->visibleChanged();
+}
+
+QRect QWaylandInputPanelPrivate::cursorRectangle() const
+{
+ return m_cursorRectangle;
+}
+
+void QWaylandInputPanelPrivate::setCursorRectangle(const QRect &cursorRectangle)
+{
+ Q_Q(QWaylandInputPanel);
+ if (m_cursorRectangle == cursorRectangle)
+ return;
+
+ m_cursorRectangle = cursorRectangle;
+
+ Q_EMIT q->cursorRectangleChanged();
+}
+
+QWaylandInputPanelPrivate *QWaylandInputPanelPrivate::get(QWaylandExtensionContainer *container)
+{
+ QWaylandInputPanel *panel = static_cast<QWaylandInputPanel *>(container->extension(wl_input_panel::name()));
+ if (panel)
+ return panel->d_func();
+ return Q_NULLPTR;
+}
+
+QWaylandInputPanelPrivate *QWaylandInputPanelPrivate::get(QWaylandInputPanel *panel)
+{
+ return panel->d_func();
+}
+
+void QWaylandInputPanelPrivate::input_panel_get_input_panel_surface(Resource *resource, uint32_t id, wl_resource *surface)
+{
+ new QtWayland::InputPanelSurface(resource->client(), id, QtWayland::Surface::fromResource(surface));
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwlinputpanel_p.h b/src/compositor/extensions/qwlinputpanel_p.h
new file mode 100644
index 000000000..49a14e792
--- /dev/null
+++ b/src/compositor/extensions/qwlinputpanel_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** 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_QWLINPUTPANEL_P_H
+#define QTWAYLAND_QWLINPUTPANEL_P_H
+
+#include <QtCompositor/qwaylandexport.h>
+#include <QtCompositor/qwaylandinputpanel.h>
+
+#include <QtCompositor/private/qwaylandextension_p.h>
+#include <QtCompositor/private/qwayland-server-input-method.h>
+
+#include <QRect>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+class Compositor;
+class Surface;
+class TextInput;
+}
+
+
+class Q_COMPOSITOR_EXPORT QWaylandInputPanelPrivate : public QWaylandExtensionTemplatePrivateImpl<QtWaylandServer::wl_input_panel>
+{
+ Q_DECLARE_PUBLIC(QWaylandInputPanel)
+public:
+ QWaylandInputPanelPrivate(QtWayland::Compositor *compositor);
+ ~QWaylandInputPanelPrivate();
+
+ QWaylandInputPanel *waylandInputPanel() const;
+
+ QtWayland::Surface *focus() const;
+ void setFocus(QtWayland::Surface *focus);
+
+ bool inputPanelVisible() const;
+ void setInputPanelVisible(bool inputPanelVisible);
+
+ QRect cursorRectangle() const;
+ void setCursorRectangle(const QRect &cursorRectangle);
+
+ static QWaylandInputPanelPrivate *get(QWaylandExtensionContainer *container);
+ static QWaylandInputPanelPrivate *get(QWaylandInputPanel *panel);
+protected:
+ void input_panel_get_input_panel_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE;
+
+private:
+ QtWayland::Compositor *m_compositor;
+
+ QtWayland::Surface *m_focus;
+ bool m_inputPanelVisible;
+ QRect m_cursorRectangle;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTWAYLAND_QWLINPUTPANEL_P_H
diff --git a/src/compositor/extensions/qwlinputpanelsurface.cpp b/src/compositor/extensions/qwlinputpanelsurface.cpp
new file mode 100644
index 000000000..a72afa2b3
--- /dev/null
+++ b/src/compositor/extensions/qwlinputpanelsurface.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** 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 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 "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/extensions/qwlinputpanelsurface_p.h b/src/compositor/extensions/qwlinputpanelsurface_p.h
new file mode 100644
index 000000000..0591832fb
--- /dev/null
+++ b/src/compositor/extensions/qwlinputpanelsurface_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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 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_QWLINPUTPANELSURFACE_P_H
+#define QTWAYLAND_QWLINPUTPANELSURFACE_P_H
+
+#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/extensions/qwlqtkey.cpp b/src/compositor/extensions/qwlqtkey.cpp
new file mode 100644
index 000000000..b7d567a0a
--- /dev/null
+++ b/src/compositor/extensions/qwlqtkey.cpp
@@ -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$
+**
+****************************************************************************/
+
+#include "qwlqtkey_p.h"
+#include "qwlsurface_p.h"
+#include <QKeyEvent>
+#include <QWindow>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+QtKeyExtensionGlobal::QtKeyExtensionGlobal(Compositor *compositor)
+ : QWaylandExtension(compositor->waylandCompositor())
+ , 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;
+}
+
+QtKeyExtensionGlobal *QtKeyExtensionGlobal::get(QWaylandExtensionContainer *container)
+{
+ return static_cast<QtKeyExtensionGlobal *>(container->extension(qt_key_extension::name()));
+}
+
+}
+
+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..542f6eae2
--- /dev/null
+++ b/src/compositor/extensions/qwlqtkey_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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
+
+#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 QWaylandExtension, public QtWaylandServer::qt_key_extension
+{
+ Q_OBJECT
+public:
+ QtKeyExtensionGlobal(Compositor *compositor);
+
+ bool postQtKeyEvent(QKeyEvent *event, Surface *surface);
+
+ const struct wl_interface *interface() const Q_DECL_OVERRIDE { return qt_key_extension::interface(); }
+
+ static QtKeyExtensionGlobal *get(QWaylandExtensionContainer *container);
+private:
+ Compositor *m_compositor;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // WLQTKEY_H
diff --git a/src/compositor/extensions/qwlqttouch.cpp b/src/compositor/extensions/qwlqttouch.cpp
new file mode 100644
index 000000000..872bbdcb5
--- /dev/null
+++ b/src/compositor/extensions/qwlqttouch.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** 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 "qwlqttouch_p.h"
+#include "qwlsurface_p.h"
+#include "qwaylandsurfaceview.h"
+#include <QTouchEvent>
+#include <QWindow>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+static const int maxRawPos = 24;
+
+TouchExtensionGlobal::TouchExtensionGlobal(Compositor *compositor)
+ : QWaylandExtension(compositor->waylandCompositor())
+ , QtWaylandServer::qt_touch_extension(compositor->wl_display(), 1)
+ , m_compositor(compositor)
+ , m_flags(0)
+ , m_resources()
+ , m_posData(maxRawPos * 2)
+{
+}
+
+TouchExtensionGlobal::~TouchExtensionGlobal()
+{
+}
+
+static inline int toFixed(qreal f)
+{
+ return int(f * 10000);
+}
+
+bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandSurfaceView *view)
+{
+ const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
+ const int pointCount = points.count();
+ if (!pointCount)
+ return false;
+
+ QPointF surfacePos = view->requestedPosition();
+ wl_client *surfaceClient = view->surface()->handle()->resource()->client();
+ uint32_t time = m_compositor->currentTimeMsecs();
+ const int rescount = m_resources.count();
+
+ for (int res = 0; res < rescount; ++res) {
+ Resource *target = m_resources.at(res);
+ if (target->client() != surfaceClient)
+ continue;
+
+ // We will use no touch_frame type of event, to reduce the number of
+ // events flowing through the wire. Instead, the number of points sent is
+ // included in the touch point events.
+ int sentPointCount = 0;
+ for (int i = 0; i < pointCount; ++i) {
+ if (points.at(i).state() != Qt::TouchPointStationary)
+ ++sentPointCount;
+ }
+
+ for (int i = 0; i < pointCount; ++i) {
+ const QTouchEvent::TouchPoint &tp(points.at(i));
+ // Stationary points are never sent. They are cached on client side.
+ if (tp.state() == Qt::TouchPointStationary)
+ continue;
+
+ uint32_t id = tp.id();
+ 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 nx = toFixed(tp.normalizedPos().x());
+ int ny = toFixed(tp.normalizedPos().y());
+ int w = toFixed(tp.rect().width());
+ int h = toFixed(tp.rect().height());
+ int vx = toFixed(tp.velocity().x());
+ int vy = toFixed(tp.velocity().y());
+ uint32_t pressure = uint32_t(tp.pressure() * 255);
+
+ QByteArray rawData;
+ QVector<QPointF> rawPosList = tp.rawScreenPositions();
+ int rawPosCount = rawPosList.count();
+ if (rawPosCount) {
+ rawPosCount = qMin(maxRawPos, rawPosCount);
+ QVector<float>::iterator iter = m_posData.begin();
+ for (int rpi = 0; rpi < rawPosCount; ++rpi) {
+ const QPointF &rawPos(rawPosList.at(rpi));
+ // This will stay in screen coordinates for performance
+ // reasons, clients using this data will presumably know
+ // what they are doing.
+ *iter++ = static_cast<float>(rawPos.x());
+ *iter++ = static_cast<float>(rawPos.y());
+ }
+ rawData = QByteArray::fromRawData(reinterpret_cast<const char*>(m_posData.constData()), sizeof(float) * rawPosCount * 2);
+ }
+
+ send_touch(target->handle,
+ time, id, state,
+ x, y, nx, ny, w, h,
+ pressure, vx, vy,
+ flags, rawData);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void TouchExtensionGlobal::setBehviorFlags(BehaviorFlags flags)
+{
+ if (m_flags == flags)
+ return;
+
+ m_flags = flags;
+ behaviorFlagsChanged();
+}
+
+TouchExtensionGlobal *TouchExtensionGlobal::get(QWaylandExtensionContainer *container)
+{
+ return static_cast<TouchExtensionGlobal *>(container->extension(qt_touch_extension::name()));
+}
+
+void TouchExtensionGlobal::touch_extension_bind_resource(Resource *resource)
+{
+ m_resources.append(resource);
+ send_configure(resource->handle, m_flags);
+}
+
+void TouchExtensionGlobal::touch_extension_destroy_resource(Resource *resource)
+{
+ m_resources.removeOne(resource);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwlqttouch_p.h b/src/compositor/extensions/qwlqttouch_p.h
new file mode 100644
index 000000000..2c108f069
--- /dev/null
+++ b/src/compositor/extensions/qwlqttouch_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** 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
+
+#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 QWaylandExtension, 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(Compositor *compositor);
+ ~TouchExtensionGlobal();
+
+ bool postTouchEvent(QTouchEvent *event, QWaylandSurfaceView *view);
+
+ void setBehviorFlags(BehaviorFlags flags);
+ BehaviorFlags behaviorFlags() const { return m_flags; }
+
+ const struct wl_interface *interface() const Q_DECL_OVERRIDE { return QtWaylandServer::qt_touch_extension::interface(); }
+
+ static TouchExtensionGlobal *get(QWaylandExtensionContainer *container);
+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:
+ Compositor *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/extensions/qwlshellsurface.cpp b/src/compositor/extensions/qwlshellsurface.cpp
new file mode 100644
index 000000000..de53f60eb
--- /dev/null
+++ b/src/compositor/extensions/qwlshellsurface.cpp
@@ -0,0 +1,567 @@
+/****************************************************************************
+**
+** 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 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 "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(QWaylandCompositor *compositor)
+ : QWaylandExtension(compositor)
+ , wl_shell(compositor->waylandDisplay(), 1)
+{
+}
+
+const wl_interface *Shell::interface() const
+{
+ return &wl_shell_interface;
+}
+
+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::get(QWaylandSurface *surface)
+{
+ return static_cast<ShellSurface *>(surface->extension(wl_shell_surface::name()));
+}
+
+ShellSurface::ShellSurface(Shell *shell, wl_client *client, uint32_t id, Surface *surface)
+ : QWaylandExtension(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_surfaceType(None)
+{
+ m_view = surface->compositor()->waylandCompositor()->createSurfaceView(surface->waylandSurface());
+ m_view->setOutput(surface->waylandSurface()->primaryOutput());
+ connect(surface->waylandSurface(), &QWaylandSurface::configure, this, &ShellSurface::configure);
+ connect(surface->waylandSurface(), &QWaylandSurface::mapped, this, &ShellSurface::mapped);
+ connect(surface->waylandSurface(), &QWaylandSurface::offsetForNextFrame, this, &ShellSurface::adjustOffset);
+}
+
+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 = wl_display_next_serial(m_surface->compositor()->wl_display());
+ ping(serial);
+}
+
+void ShellSurface::ping(uint32_t serial)
+{
+ m_pings.insert(serial);
+ send_ping(serial);
+}
+
+void ShellSurface::setSurfaceType(SurfaceType type)
+{
+ if (m_surfaceType == type)
+ return;
+
+ m_surfaceType = type;
+ emit surfaceTypeChanged();
+}
+
+ShellSurface::SurfaceType ShellSurface::surfaceType() const
+{
+ return m_surfaceType;
+}
+
+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->requestedPosition().x();
+ qreal y = m_view->requestedPosition().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->setRequestedPosition(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);
+}
+
+void ShellSurface::mapped()
+{
+ if (m_surfaceType == Popup) {
+ if (m_surface->mapped() && m_popupGrabber->grabSerial() == m_popupSerial) {
+ m_popupGrabber->addPopup(this);
+ } else {
+ send_popup_done();
+ m_popupGrabber->setClient(0);
+ }
+ }
+}
+
+void ShellSurface::adjustOffset(const QPoint &p)
+{
+ QPointF offset(p);
+ QPointF pos = m_view->requestedPosition();
+ m_view->setRequestedPosition(pos + offset);
+}
+
+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->requestedPosition());
+
+ 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);
+
+ 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()->primaryOutputSpace()->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->setRequestedPosition(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()->primaryOutputSpace()->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->setRequestedPosition(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->setRequestedPosition(pos);
+ if (shell_surface->m_surface->transientParent()) {
+ QWaylandSurfaceView *view = shell_surface->m_surface->transientParent()->waylandSurface()->views().first();
+ if (view)
+ shell_surface->setOffset(pos - view->requestedPosition());
+ }
+
+}
+
+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/extensions/qwlshellsurface_p.h b/src/compositor/extensions/qwlshellsurface_p.h
new file mode 100644
index 000000000..804ee2cff
--- /dev/null
+++ b/src/compositor/extensions/qwlshellsurface_p.h
@@ -0,0 +1,244 @@
+/****************************************************************************
+**
+** 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 WLSHELLSURFACE_H
+#define WLSHELLSURFACE_H
+
+#include <QtCompositor/qwaylandexport.h>
+#include <QtCompositor/qwaylandsurface.h>
+#include <QtCompositor/qwaylandextension.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 QWaylandExtension, public QtWaylandServer::wl_shell
+{
+ Q_OBJECT
+public:
+ Shell(QWaylandCompositor *compositor);
+
+ const wl_interface *interface() const 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 QWaylandExtension, public QtWaylandServer::wl_shell_surface
+{
+ Q_OBJECT
+ Q_PROPERTY(SurfaceType surfaceType READ surfaceType WRITE setSurfaceType NOTIFY surfaceTypeChanged)
+public:
+ enum SurfaceType {
+ None,
+ Toplevel,
+ Transient,
+ Popup
+ };
+
+ static ShellSurface *get(QWaylandSurface *surface);
+
+ 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);
+
+ Q_INVOKABLE void ping();
+ void ping(uint32_t serial);
+
+ QWaylandSurfaceView *view() { return m_view; }
+
+ const struct wl_interface *interface() const Q_DECL_OVERRIDE { return QtWaylandServer::wl_shell_surface::interface(); }
+
+ void setSurfaceType(SurfaceType type);
+ SurfaceType surfaceType() const;
+
+signals:
+ void surfaceTypeChanged();
+
+private Q_SLOTS:
+ void mapped();
+ void adjustOffset(const QPoint &p);
+
+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;
+
+ SurfaceType m_surfaceType;
+
+ 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/extensions/qwlsubsurface.cpp b/src/compositor/extensions/qwlsubsurface.cpp
new file mode 100644
index 000000000..fb99fbe81
--- /dev/null
+++ b/src/compositor/extensions/qwlsubsurface.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** 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 "qwlsubsurface_p.h"
+
+#include "qwlcompositor_p.h"
+#include "qwaylandsurface.h"
+#include "qwaylandsurfaceview.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+SubSurfaceExtensionGlobal::SubSurfaceExtensionGlobal(QWaylandCompositor *compositor)
+ : QWaylandExtension(compositor)
+ , qt_sub_surface_extension(compositor->waylandDisplay(), 1)
+ , m_compositor(compositor)
+{
+}
+
+void SubSurfaceExtensionGlobal::sub_surface_extension_get_sub_surface_aware_surface(Resource *resource,
+ uint32_t id,
+ struct ::wl_resource *surface)
+{
+ QWaylandSurface *waylandsurface = QWaylandSurface::fromResource(surface);
+ new SubSurface(resource->client(),id,waylandsurface);
+}
+
+SubSurface::SubSurface(wl_client *client, uint32_t id, QWaylandSurface *surface)
+ : QWaylandExtension(surface)
+ , qt_sub_surface(client, id, 1)
+ , m_surface(surface)
+ , m_parent(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)) {
+ m_sub_surfaces.append(subSurface->m_surface);
+ subSurface->setParent(this);
+ }
+ foreach (QWaylandSurfaceView *view, subSurface->m_surface->views())
+ view->setRequestedPosition(QPointF(x,y));
+}
+
+void SubSurface::removeSubSurface(SubSurface *subSurfaces)
+{
+ Q_ASSERT(m_sub_surfaces.contains(subSurfaces->m_surface));
+ m_sub_surfaces.removeOne(subSurfaces->m_surface);
+}
+
+SubSurface *SubSurface::parent() const
+{
+ return m_parent;
+}
+
+void SubSurface::setParent(SubSurface *parent)
+{
+ if (m_parent == parent)
+ return;
+
+ SubSurface *oldParent = 0;
+ SubSurface *newParent = 0;
+
+ if (m_parent) {
+ oldParent = m_parent;
+ m_parent->removeSubSurface(this);
+ }
+ if (parent) {
+ newParent = parent;
+ }
+ m_parent = parent;
+
+ parentChanged(newParent,oldParent);
+}
+
+QLinkedList<QWaylandSurface *> SubSurface::subSurfaces() const
+{
+ return m_sub_surfaces;
+}
+
+void SubSurface::parentDestroyed()
+{
+ m_parent = 0;
+}
+
+void SubSurface::sub_surface_attach_sub_surface(Resource *resource, struct ::wl_resource *sub_surface, int32_t x, int32_t y)
+{
+ Q_UNUSED(resource);
+ SubSurface *child_sub_surface = static_cast<SubSurface *>(Resource::fromResource(sub_surface)->sub_surface_object);
+ setSubSurface(child_sub_surface,x,y);
+}
+
+void SubSurface::sub_surface_move_sub_surface(Resource *resource, struct ::wl_resource *sub_surface, int32_t x, int32_t y)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(sub_surface);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+}
+
+void SubSurface::sub_surface_raise(Resource *resource, struct ::wl_resource *sub_surface)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(sub_surface);
+}
+
+void SubSurface::sub_surface_lower(Resource *resource, struct ::wl_resource *sub_surface)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(sub_surface);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwlsubsurface_p.h b/src/compositor/extensions/qwlsubsurface_p.h
new file mode 100644
index 000000000..66eff6dc9
--- /dev/null
+++ b/src/compositor/extensions/qwlsubsurface_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** 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 WLSUBSURFACE_H
+#define WLSUBSURFACE_H
+
+#include <private/qwlsurface_p.h>
+
+#include <QtCompositor/private/qwayland-server-sub-surface-extension.h>
+
+#include <QtCore/QLinkedList>
+
+QT_BEGIN_NAMESPACE
+
+class Compositor;
+class QWaylandSurface;
+
+namespace QtWayland {
+
+class SubSurfaceExtensionGlobal : public QWaylandExtension, public QtWaylandServer::qt_sub_surface_extension
+{
+ Q_OBJECT
+public:
+ SubSurfaceExtensionGlobal(QWaylandCompositor *compositor);
+
+ const struct wl_interface *interface() const { return qt_sub_surface_extension::interface(); }
+private:
+ QWaylandCompositor *m_compositor;
+
+ void sub_surface_extension_get_sub_surface_aware_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE;
+};
+
+class SubSurface : public QWaylandExtension, public QtWaylandServer::qt_sub_surface
+{
+ Q_OBJECT
+ Q_PROPERTY(SubSurface *parent READ parent WRITE setParent NOTIFY parentChanged)
+public:
+ SubSurface(struct wl_client *client, uint32_t id, QWaylandSurface *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;
+
+ QWaylandSurface *surface() const;
+
+ const struct wl_interface *interface() const { return qt_sub_surface::interface(); }
+
+signals:
+ void parentChanged(SubSurface *newParent, SubSurface *oldParent);
+
+protected:
+ void sub_surface_attach_sub_surface(Resource *resource, struct ::wl_resource *sub_surface, int32_t x, int32_t y) Q_DECL_OVERRIDE;
+ void sub_surface_move_sub_surface(Resource *resource, struct ::wl_resource *sub_surface, int32_t x, int32_t y) Q_DECL_OVERRIDE;
+ void sub_surface_raise(Resource *resource, struct ::wl_resource *sub_surface) Q_DECL_OVERRIDE;
+ void sub_surface_lower(Resource *resource, struct ::wl_resource *sub_surface) Q_DECL_OVERRIDE;
+
+private:
+ void parentDestroyed();
+ struct wl_resource *m_sub_surface_resource;
+ QWaylandSurface *m_surface;
+
+ SubSurface *m_parent;
+ QLinkedList<QWaylandSurface *> m_sub_surfaces;
+
+};
+
+inline QWaylandSurface *SubSurface::surface() const
+{
+ return m_surface;
+}
+
+}
+
+QT_END_NAMESPACE
+
+#endif // WLSUBSURFACE_H
diff --git a/src/compositor/extensions/qwltextinput.cpp b/src/compositor/extensions/qwltextinput.cpp
new file mode 100644
index 000000000..af1b73cb6
--- /dev/null
+++ b/src/compositor/extensions/qwltextinput.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** 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 "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(QWaylandExtensionContainer *container, Compositor *compositor, struct ::wl_client *client, int id)
+ : QWaylandExtension(container)
+ , 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()){
+ QWaylandInputPanelPrivate *panel = QWaylandInputPanelPrivate::get(m_compositor->waylandCompositor());
+ if (panel)
+ panel->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()) {
+ QWaylandInputPanelPrivate *panel = QWaylandInputPanelPrivate::get(m_compositor->waylandCompositor());
+ if (panel)
+ panel->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()) {
+ QWaylandInputPanelPrivate *panel = QWaylandInputPanelPrivate::get(m_compositor->waylandCompositor());
+ if (panel)
+ panel->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/extensions/qwltextinput_p.h b/src/compositor/extensions/qwltextinput_p.h
new file mode 100644
index 000000000..60485d32d
--- /dev/null
+++ b/src/compositor/extensions/qwltextinput_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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_QWLTEXTINPUT_P_H
+#define QTWAYLAND_QWLTEXTINPUT_P_H
+
+#include <QtCompositor/QWaylandExtension>
+#include <QtCompositor/private/qwayland-server-text.h>
+
+#include <QRect>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+class Compositor;
+class InputMethod;
+class Surface;
+
+class TextInput : public QWaylandExtension, public QtWaylandServer::wl_text_input
+{
+public:
+ explicit TextInput(QWaylandExtensionContainer *container, Compositor *compositor, struct ::wl_client *client, int id);
+
+ Surface *focus() const;
+
+ bool inputPanelVisible() const;
+ QRect cursorRectangle() const;
+
+ void deactivate(InputMethod *inputMethod);
+
+ const struct wl_interface *interface() const Q_DECL_OVERRIDE { return wl_text_input::interface(); }
+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/extensions/qwltextinputmanager.cpp b/src/compositor/extensions/qwltextinputmanager.cpp
new file mode 100644
index 000000000..738680151
--- /dev/null
+++ b/src/compositor/extensions/qwltextinputmanager.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** 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 "qwltextinputmanager_p.h"
+
+#include "qwlcompositor_p.h"
+#include "qwltextinput_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+TextInputManager::TextInputManager(Compositor *compositor)
+ : QWaylandExtension(compositor->waylandCompositor())
+ , 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(this, m_compositor, resource->client(), id);
+}
+
+} // namespace QtWayland
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwltextinputmanager_p.h b/src/compositor/extensions/qwltextinputmanager_p.h
new file mode 100644
index 000000000..b9f3a0ae5
--- /dev/null
+++ b/src/compositor/extensions/qwltextinputmanager_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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_QWLTEXTINPUTMANAGER_P_H
+#define QTWAYLAND_QWLTEXTINPUTMANAGER_P_H
+
+#include <QtCompositor/QWaylandExtension>
+#include <QtCompositor/private/qwayland-server-text.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+class Compositor;
+
+class TextInputManager : public QWaylandExtension, public QtWaylandServer::wl_text_input_manager, public QWaylandExtensionContainer
+{
+ Q_OBJECT
+public:
+ TextInputManager(Compositor *compositor);
+ ~TextInputManager();
+
+ const struct wl_interface *interface() const Q_DECL_OVERRIDE { return wl_text_input_manager::interface(); }
+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