summaryrefslogtreecommitdiffstats
path: root/examples/wayland
diff options
context:
space:
mode:
Diffstat (limited to 'examples/wayland')
-rw-r--r--examples/wayland/qml-compositor/ContrastEffect.qml90
-rw-r--r--examples/wayland/qml-compositor/WindowChrome.qml63
-rw-r--r--examples/wayland/qml-compositor/WindowContainer.qml212
-rw-r--r--examples/wayland/qml-compositor/background.jpgbin0 -> 30730 bytes
-rw-r--r--examples/wayland/qml-compositor/closebutton.pngbin0 -> 25957 bytes
-rw-r--r--examples/wayland/qml-compositor/compositor.js155
-rw-r--r--examples/wayland/qml-compositor/main.cpp163
-rw-r--r--examples/wayland/qml-compositor/main.qml127
-rw-r--r--examples/wayland/qml-compositor/qml-compositor.pro22
-rw-r--r--examples/wayland/qwindow-compositor/compositorwindow.cpp61
-rw-r--r--examples/wayland/qwindow-compositor/compositorwindow.h64
-rw-r--r--examples/wayland/qwindow-compositor/main.cpp74
-rw-r--r--examples/wayland/qwindow-compositor/qwindow-compositor.pro29
-rw-r--r--examples/wayland/qwindow-compositor/qwindow-compositor.qrc5
-rw-r--r--examples/wayland/qwindow-compositor/qwindowcompositor.cpp478
-rw-r--r--examples/wayland/qwindow-compositor/qwindowcompositor.h117
-rw-r--r--examples/wayland/qwindow-compositor/textureblitter.cpp166
-rw-r--r--examples/wayland/qwindow-compositor/textureblitter.h71
-rw-r--r--examples/wayland/server-buffer/README17
-rw-r--r--examples/wayland/server-buffer/client/client.pro17
-rw-r--r--examples/wayland/server-buffer/client/main.cpp191
-rw-r--r--examples/wayland/server-buffer/client/serverbufferrenderer.cpp135
-rw-r--r--examples/wayland/server-buffer/client/serverbufferrenderer.h70
-rw-r--r--examples/wayland/server-buffer/compositor/compositor.pro23
-rw-r--r--examples/wayland/server-buffer/compositor/compositor.qrc7
-rw-r--r--examples/wayland/server-buffer/compositor/images/background.jpgbin0 -> 30730 bytes
-rw-r--r--examples/wayland/server-buffer/compositor/main.cpp268
-rw-r--r--examples/wayland/server-buffer/compositor/qml/ServerBufferContainer.qml75
-rw-r--r--examples/wayland/server-buffer/compositor/qml/main.qml83
-rw-r--r--examples/wayland/server-buffer/compositor/serverbufferitem.cpp126
-rw-r--r--examples/wayland/server-buffer/compositor/serverbufferitem.h99
-rw-r--r--examples/wayland/server-buffer/compositor/serverbuffertextureprovider.h77
-rw-r--r--examples/wayland/server-buffer/server-buffer.pro3
-rw-r--r--examples/wayland/server-buffer/share-buffer.xml46
-rw-r--r--examples/wayland/wayland.pro13
35 files changed, 3147 insertions, 0 deletions
diff --git a/examples/wayland/qml-compositor/ContrastEffect.qml b/examples/wayland/qml-compositor/ContrastEffect.qml
new file mode 100644
index 000000000..c284b2907
--- /dev/null
+++ b/examples/wayland/qml-compositor/ContrastEffect.qml
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+ShaderEffect {
+ property variant source: null;
+ property color color: "#ffffff"
+ property real blend;
+
+ onSourceChanged: {
+ if (source != null) {
+ source.setPaintEnabled(false);
+ }
+ }
+
+ property string vShaderInvertedY: "
+ uniform highp mat4 qt_Matrix;
+ attribute highp vec4 qt_Vertex;
+ attribute highp vec2 qt_MultiTexCoord0;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ qt_TexCoord0 = qt_MultiTexCoord0;
+ gl_Position = qt_Matrix * qt_Vertex;
+ }
+ "
+ property string vShader: "
+ uniform highp mat4 qt_Matrix;
+ attribute highp vec4 qt_Vertex;
+ attribute highp vec2 qt_MultiTexCoord0;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ qt_TexCoord0 = vec2(0, 1) + qt_MultiTexCoord0 * vec2(1, -1);
+ gl_Position = qt_Matrix * qt_Vertex;
+ }
+ "
+
+ vertexShader: source && source.isYInverted ? vShaderInvertedY : vShader
+
+ fragmentShader: "
+ uniform lowp sampler2D source;
+ uniform highp float qt_Opacity;
+ uniform highp vec4 color;
+ uniform highp float blend;
+ varying highp vec2 qt_TexCoord0;
+ void main() {
+ highp vec4 sourceColor = texture2D(source, qt_TexCoord0);
+ highp vec3 delta = sourceColor.rgb - vec3(0.5);
+ highp vec3 lowerContrast = vec3(0.5) + 0.4 * delta;
+ gl_FragColor = qt_Opacity * mix(sourceColor, color * sourceColor.a * dot(lowerContrast, vec3(11, 16, 5) * (1. / 32.)), blend);
+ }
+ "
+}
diff --git a/examples/wayland/qml-compositor/WindowChrome.qml b/examples/wayland/qml-compositor/WindowChrome.qml
new file mode 100644
index 000000000..fe9f5d78d
--- /dev/null
+++ b/examples/wayland/qml-compositor/WindowChrome.qml
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: chrome
+ anchors.fill: parent
+
+ property variant window: parent;
+ property bool selected: root.selectedWindow === window
+
+ MouseArea {
+ anchors.fill: parent
+ enabled: !window.focus
+ hoverEnabled: !window.focus
+ onClicked: {
+ if (selected) {
+ window.takeFocus();
+ } else {
+ root.selectedWindow = window
+ root.focus = true
+ }
+ }
+ }
+}
diff --git a/examples/wayland/qml-compositor/WindowContainer.qml b/examples/wayland/qml-compositor/WindowContainer.qml
new file mode 100644
index 000000000..5e073298f
--- /dev/null
+++ b/examples/wayland/qml-compositor/WindowContainer.qml
@@ -0,0 +1,212 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Window 2.0
+import QtCompositor 1.0
+
+Item {
+ id: container
+
+ x: targetX
+ y: targetY
+ width: targetWidth
+ height: targetHeight
+ scale: targetScale
+
+ visible: isFullscreen || !root.hasFullscreenWindow
+ onVisibleChanged: {
+ child.surface.clientRenderingEnabled = visible
+ }
+
+ opacity: 0
+
+ property real targetX
+ property real targetY
+ property real targetWidth
+ property real targetHeight
+ property real targetScale
+
+ property variant child: null
+ property variant chrome: null
+ property bool animationsEnabled: false
+ property bool isFullscreen: state === "fullscreen"
+ property int index
+
+ state: child && chrome && chrome.selected && child.focus ? "fullscreen" : "normal"
+
+ Behavior on x {
+ enabled: container.animationsEnabled;
+ NumberAnimation { easing.type: Easing.InCubic; duration: 200; }
+ }
+
+ Behavior on y {
+ enabled: container.animationsEnabled;
+ NumberAnimation { easing.type: Easing.InQuad; duration: 200; }
+ }
+
+ Behavior on width {
+ enabled: container.animationsEnabled;
+ NumberAnimation { easing.type: Easing.InCubic; duration: 200; }
+ }
+
+ Behavior on height {
+ enabled: container.animationsEnabled;
+ NumberAnimation { easing.type: Easing.InCubic; duration: 200; }
+ }
+
+ Behavior on scale {
+ enabled: container.animationsEnabled;
+ NumberAnimation { easing.type: Easing.InQuad; duration: 200; }
+ }
+
+ Behavior on opacity {
+ enabled: true;
+ NumberAnimation { easing.type: Easing.Linear; duration: 250; }
+ }
+
+ ContrastEffect {
+ id: effect
+ source: child
+ anchors.fill: parent
+ blend: { if (child && chrome && (chrome.selected || child.focus)) 0.0; else 0.6 }
+ opacity: 1.0
+ z: 1
+
+ Behavior on blend {
+ enabled: true;
+ NumberAnimation { easing.type: Easing.Linear; duration: 200; }
+ }
+ }
+
+ transform: [
+ Scale { id: scaleTransform; origin.x: container.width / 2; origin.y: container.height / 2; xScale: 1; yScale: 1 }
+ ]
+
+ property real fullscreenScale: Math.min(root.width / width, root.height / height)
+
+ transitions: [
+ Transition {
+ from: "*"; to: "normal"
+ SequentialAnimation {
+ ScriptAction {
+ script: {
+ compositor.fullscreenSurface = null
+ background.opacity = 1
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation { target: container; property: "x"; easing.type: Easing.Linear; to: targetX; duration: 400; }
+ NumberAnimation { target: container; property: "y"; easing.type: Easing.Linear; to: targetY; duration: 400; }
+ NumberAnimation { target: container; property: "scale"; easing.type: Easing.Linear; to: targetScale; duration: 400; }
+ }
+ ScriptAction {
+ script: container.z = 0
+ }
+ }
+ },
+ Transition {
+ from: "*"; to: "fullscreen"
+ SequentialAnimation {
+ ScriptAction {
+ script: {
+ container.z = 1
+ background.opacity = 0
+ }
+ }
+ ParallelAnimation {
+ NumberAnimation { target: container; property: "x"; easing.type: Easing.Linear; to: (root.width - container.width) / 2; duration: 400; }
+ NumberAnimation { target: container; property: "y"; easing.type: Easing.Linear; to: (root.height - container.height) / 2; duration: 400; }
+ NumberAnimation { target: container; property: "scale"; easing.type: Easing.Linear; to: fullscreenScale; duration: 400; }
+ }
+ ScriptAction {
+ script: compositor.fullscreenSurface = child.surface
+ }
+ }
+ }
+ ]
+
+ SequentialAnimation {
+ id: destroyAnimation
+ NumberAnimation { target: scaleTransform; property: "yScale"; easing.type: Easing.Linear; to: 0.01; duration: 200; }
+ NumberAnimation { target: scaleTransform; property: "xScale"; easing.type: Easing.Linear; to: 0.01; duration: 150; }
+ NumberAnimation { target: container; property: "opacity"; easing.type: Easing.Linear; to: 0.0; duration: 150; }
+ ScriptAction { script: container.parent.removeWindow(container) }
+ }
+ SequentialAnimation {
+ id: unmapAnimation
+ NumberAnimation { target: container; property: "opacity"; easing.type: Easing.Linear; to: 0.0; duration: 150; }
+ ScriptAction { script: container.parent.removeWindow(container) }
+ }
+
+ Connections {
+ target: container.child ? container.child.surface : null
+ onUnmapped: unmapAnimation.start()
+ }
+ Connections {
+ target: container.child ? container.child : null
+ onSurfaceDestroyed: {
+ destroyAnimation.start();
+ }
+ }
+
+ Image {
+ source: "closebutton.png"
+ smooth: true
+
+ opacity: !isFullscreen && chrome && chrome.selected ? 1 : 0
+ Behavior on opacity {
+ NumberAnimation { easing.type: Easing.InCubic; duration: 200; }
+ }
+
+ x: parent.width - 32
+ y: 4
+ width: 24
+ height: 24
+ z: 4
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ child.surface.destroySurface()
+ }
+ }
+ }
+}
diff --git a/examples/wayland/qml-compositor/background.jpg b/examples/wayland/qml-compositor/background.jpg
new file mode 100644
index 000000000..445567fbd
--- /dev/null
+++ b/examples/wayland/qml-compositor/background.jpg
Binary files differ
diff --git a/examples/wayland/qml-compositor/closebutton.png b/examples/wayland/qml-compositor/closebutton.png
new file mode 100644
index 000000000..5b5616e98
--- /dev/null
+++ b/examples/wayland/qml-compositor/closebutton.png
Binary files differ
diff --git a/examples/wayland/qml-compositor/compositor.js b/examples/wayland/qml-compositor/compositor.js
new file mode 100644
index 000000000..f24d849c1
--- /dev/null
+++ b/examples/wayland/qml-compositor/compositor.js
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+var windowList = null;
+var indexes = null;
+
+function relayout() {
+ if (windowList === null || windowList.length == 0)
+ return;
+
+ var dim = Math.ceil(Math.sqrt(windowList.length));
+
+ var cols = dim;
+ var rows = Math.ceil(windowList.length / cols);
+
+ var w = root.width / dim;
+ var h = root.height / rows;
+
+ var i;
+ var ix = 0;
+ var iy = 0;
+ var lastDim = 1;
+
+ indexes = new Array(dim * dim);
+
+ for (i = 0; i < windowList.length; ++i) {
+ if (i > 0) {
+ var currentDim = Math.ceil(Math.sqrt(i + 1));
+ if (currentDim == lastDim) {
+ if (iy < currentDim - 1) {
+ ++iy;
+ if (iy == currentDim - 1)
+ ix = 0;
+ } else {
+ ++ix;
+ }
+ } else {
+ iy = 0;
+ ix = currentDim - 1;
+ }
+ lastDim = currentDim;
+ }
+
+ indexes[iy * dim + ix] = i;
+ windowList[i].index = iy * dim + ix;
+
+ var cx = (ix + 0.5) * w;
+ var cy = (iy + 0.5) * h;
+
+ windowList[i].targetScale = 0.98 * Math.min(w / windowList[i].width, h / windowList[i].height);
+
+ windowList[i].targetX = (cx - windowList[i].width / 2);
+ windowList[i].targetY = (cy - windowList[i].height / 2);
+ }
+}
+
+function addWindow(window)
+{
+ if (windowList == null)
+ windowList = new Array(0);
+
+ windowList.push(window);
+ relayout();
+}
+
+function removeWindow(window)
+{
+ var i;
+ for (i = 0; i < windowList.length; ++i) {
+ if (windowList[i] == window)
+ break;
+ }
+
+ var index = windowList[i].index;
+ var dim = Math.ceil(Math.sqrt(windowList.length));
+ var maxY = Math.floor((windowList.length-1) / dim);
+
+ var shrinking = Math.ceil(Math.sqrt(windowList.length - 1)) != dim;
+
+ while (true) {
+ var ix = index % dim;
+ var iy = Math.floor(index / dim);
+
+ if (shrinking) {
+ if (iy > 0)
+ --iy;
+ else if (++ix == dim)
+ break;
+ } else {
+ if (iy < maxY) {
+ if (ix > 0)
+ --ix;
+ else
+ ++iy;
+ } else {
+ ++ix;
+ }
+ }
+
+ var next = iy * dim + ix;
+
+ var currentIndex = indexes[index];
+ var nextIndex = indexes[next];
+
+ if (nextIndex == null)
+ break;
+
+ var temp = windowList[currentIndex];
+ windowList[currentIndex] = windowList[nextIndex];
+ windowList[currentIndex].index = currentIndex;
+ windowList[nextIndex] = temp;
+
+ index = next;
+ }
+
+ windowList.splice(indexes[index], 1);
+ relayout();
+}
diff --git a/examples/wayland/qml-compositor/main.cpp b/examples/wayland/qml-compositor/main.cpp
new file mode 100644
index 000000000..26e730d43
--- /dev/null
+++ b/examples/wayland/qml-compositor/main.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandquickcompositor.h"
+#include "qwaylandquicksurface.h"
+
+#include <QtCompositor/qwaylandsurfaceitem.h>
+
+#include <QGuiApplication>
+#include <QTimer>
+#include <QPainter>
+#include <QMouseEvent>
+
+#include <QQmlContext>
+
+#include <QQuickItem>
+#include <QQuickView>
+
+class QmlCompositor : public QQuickView, public QWaylandQuickCompositor
+{
+ Q_OBJECT
+ Q_PROPERTY(QWaylandQuickSurface* fullscreenSurface READ fullscreenSurface WRITE setFullscreenSurface NOTIFY fullscreenSurfaceChanged)
+
+public:
+ QmlCompositor()
+ : QWaylandQuickCompositor(this, 0, DefaultExtensions | SubSurfaceExtension)
+ , m_fullscreenSurface(0)
+ {
+ setSource(QUrl("main.qml"));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+ setColor(Qt::black);
+ winId();
+ addDefaultShell();
+
+ connect(this, SIGNAL(afterRendering()), this, SLOT(sendCallbacks()));
+ }
+
+ QWaylandQuickSurface *fullscreenSurface() const
+ {
+ return m_fullscreenSurface;
+ }
+
+ Q_INVOKABLE QWaylandSurfaceItem *item(QWaylandSurface *surf)
+ {
+ return static_cast<QWaylandSurfaceItem *>(surf->views().first());
+ }
+
+signals:
+ void windowAdded(QVariant window);
+ void windowDestroyed(QVariant window);
+ void windowResized(QVariant window);
+ void fullscreenSurfaceChanged();
+
+public slots:
+ void destroyWindow(QVariant window) {
+ qvariant_cast<QObject *>(window)->deleteLater();
+ }
+
+ void setFullscreenSurface(QWaylandQuickSurface *surface) {
+ if (surface == m_fullscreenSurface)
+ return;
+ m_fullscreenSurface = surface;
+ emit fullscreenSurfaceChanged();
+ }
+
+private slots:
+ void surfaceMapped() {
+ QWaylandQuickSurface *surface = qobject_cast<QWaylandQuickSurface *>(sender());
+ emit windowAdded(QVariant::fromValue(surface));
+ }
+ void surfaceUnmapped() {
+ QWaylandQuickSurface *surface = qobject_cast<QWaylandQuickSurface *>(sender());
+ if (surface == m_fullscreenSurface)
+ m_fullscreenSurface = 0;
+ emit windowDestroyed(QVariant::fromValue(surface));
+ }
+
+ void surfaceDestroyed(QObject *object) {
+ QWaylandQuickSurface *surface = static_cast<QWaylandQuickSurface *>(object);
+ if (surface == m_fullscreenSurface)
+ m_fullscreenSurface = 0;
+ emit windowDestroyed(QVariant::fromValue(surface));
+ }
+
+ void sendCallbacks() {
+ if (m_fullscreenSurface)
+ sendFrameCallbacks(QList<QWaylandSurface *>() << m_fullscreenSurface);
+ else
+ sendFrameCallbacks(surfaces());
+ }
+
+protected:
+ void resizeEvent(QResizeEvent *event)
+ {
+ QQuickView::resizeEvent(event);
+ QWaylandCompositor::setOutputGeometry(QRect(0, 0, width(), height()));
+ }
+
+ void surfaceCreated(QWaylandSurface *surface) {
+ connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
+ connect(surface, SIGNAL(mapped()), this, SLOT(surfaceMapped()));
+ connect(surface,SIGNAL(unmapped()), this,SLOT(surfaceUnmapped()));
+ }
+
+private:
+ QWaylandQuickSurface *m_fullscreenSurface;
+};
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QmlCompositor compositor;
+ compositor.setTitle(QLatin1String("QML Compositor"));
+ compositor.setGeometry(0, 0, 1024, 768);
+ compositor.show();
+
+ compositor.rootContext()->setContextProperty("compositor", &compositor);
+
+ QObject::connect(&compositor, SIGNAL(windowAdded(QVariant)), compositor.rootObject(), SLOT(windowAdded(QVariant)));
+ QObject::connect(&compositor, SIGNAL(windowResized(QVariant)), compositor.rootObject(), SLOT(windowResized(QVariant)));
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/wayland/qml-compositor/main.qml b/examples/wayland/qml-compositor/main.qml
new file mode 100644
index 000000000..a6b54c312
--- /dev/null
+++ b/examples/wayland/qml-compositor/main.qml
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtCompositor 1.0
+import "compositor.js" as CompositorLogic
+
+Item {
+ id: root
+
+ property variant selectedWindow: null
+ property bool hasFullscreenWindow: typeof compositor != "undefined" && compositor.fullscreenSurface !== null
+
+ Image {
+ id: background
+ Behavior on opacity {
+ NumberAnimation { easing.type: Easing.InCubic; duration: 400; }
+ }
+ anchors.fill: parent
+ fillMode: Image.Tile
+ source: "background.jpg"
+ smooth: true
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ root.selectedWindow = null
+ root.focus = true
+ }
+ }
+
+ MouseArea {
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ width: 2
+ height: 2
+ hoverEnabled: true
+ onEntered: {
+ root.selectedWindow = null
+ root.focus = true
+ }
+ z: 10
+ }
+
+ function windowAdded(window) {
+ var windowContainerComponent = Qt.createComponent("WindowContainer.qml");
+ if (windowContainerComponent.status != Component.Ready) {
+ console.warn("Error loading WindowContainer.qml: " + windowContainerComponent.errorString());
+ return;
+ }
+ var windowContainer = windowContainerComponent.createObject(root);
+
+ windowContainer.child = compositor.item(window);
+ windowContainer.child.parent = windowContainer;
+ windowContainer.child.touchEventsEnabled = true;
+
+ windowContainer.targetWidth = window.size.width;
+ windowContainer.targetHeight = window.size.height;
+
+ var windowChromeComponent = Qt.createComponent("WindowChrome.qml");
+ if (windowChromeComponent.status != Component.Ready) {
+ console.warn("Error loading WindowChrome.qml: " + windowChromeComponent.errorString());
+ return;
+ }
+ var windowChrome = windowChromeComponent.createObject(windowContainer.child);
+
+ CompositorLogic.addWindow(windowContainer);
+
+ windowContainer.opacity = 1
+ windowContainer.animationsEnabled = true;
+ windowContainer.chrome = windowChrome;
+ }
+
+ function windowResized(window) {
+ window.width = window.surface.size.width;
+ window.height = window.surface.size.height;
+
+ CompositorLogic.relayout();
+ }
+
+ function removeWindow(window) {
+ CompositorLogic.removeWindow(window);
+ window.chrome.destroy();
+ window.destroy();
+ }
+
+ onHeightChanged: CompositorLogic.relayout();
+ onWidthChanged: CompositorLogic.relayout();
+}
diff --git a/examples/wayland/qml-compositor/qml-compositor.pro b/examples/wayland/qml-compositor/qml-compositor.pro
new file mode 100644
index 000000000..f908a2f2f
--- /dev/null
+++ b/examples/wayland/qml-compositor/qml-compositor.pro
@@ -0,0 +1,22 @@
+DEFINES += QT_COMPOSITOR_QUICK
+
+LIBS += -L ../../lib
+
+QT += quick qml
+QT += quick-private
+
+QT += compositor
+
+# if you want to compile QtCompositor as part of the application
+# instead of linking to it, remove the QT += compositor and uncomment
+# the following line
+#include (../../src/compositor/compositor.pri)
+
+SOURCES += main.cpp
+
+OTHER_FILES = ContrastEffect.qml main.qml WindowChrome.qml WindowContainer.qml background.jpg closebutton.png compositor.js
+
+target.path = $$[QT_INSTALL_EXAMPLES]/wayland/qml-compositor
+sources.files = $$OTHER_FILES $$SOURCES $$HEADERS $$RESOURCES $$FORMS qml-compositor.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/wayland/qml-compositor
+INSTALLS += target sources
diff --git a/examples/wayland/qwindow-compositor/compositorwindow.cpp b/examples/wayland/qwindow-compositor/compositorwindow.cpp
new file mode 100644
index 000000000..6f8f2321d
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/compositorwindow.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Wayland module
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "compositorwindow.h"
+#include <QTouchEvent>
+
+CompositorWindow::CompositorWindow(const QSurfaceFormat &format, const QRect &geometry)
+ : m_format(format)
+{
+ setSurfaceType(QWindow::OpenGLSurface);
+ setGeometry(geometry);
+ setFormat(format);
+ create();
+ m_context = new QOpenGLContext;
+ m_context->setFormat(format);
+ m_context->create();
+}
+
+void CompositorWindow::touchEvent(QTouchEvent *event)
+{
+ // Do not want any automatically synthesized mouse events
+ // so make sure the touch is always accepted.
+ event->accept();
+}
diff --git a/examples/wayland/qwindow-compositor/compositorwindow.h b/examples/wayland/qwindow-compositor/compositorwindow.h
new file mode 100644
index 000000000..dc87b31a3
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/compositorwindow.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Wayland module
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMPOSITORWINDOW_H
+#define COMPOSITORWINDOW_H
+
+#include <QWindow>
+#include <QOpenGLContext>
+#include <QSurfaceFormat>
+
+class CompositorWindow : public QWindow
+{
+public:
+ CompositorWindow(const QSurfaceFormat &format, const QRect &geometry);
+ QOpenGLContext* context() { return m_context; }
+ bool makeCurrent() { return m_context->makeCurrent(this); }
+ void swapBuffers() { m_context->swapBuffers(this); }
+
+protected:
+ void touchEvent(QTouchEvent *event);
+
+private:
+ QOpenGLContext *m_context;
+ QSurfaceFormat m_format;
+};
+
+#endif // COMPOSITORWINDOW_H
diff --git a/examples/wayland/qwindow-compositor/main.cpp b/examples/wayland/qwindow-compositor/main.cpp
new file mode 100644
index 000000000..a0288982e
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/main.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "compositorwindow.h"
+#include "qwindowcompositor.h"
+
+#include <QGuiApplication>
+#include <QStringList>
+#include <QScreen>
+#include <QSurfaceFormat>
+
+int main(int argc, char *argv[])
+{
+ // Enable the following to have touch events generated from mouse events.
+ // Very handy for testing touch event delivery without a real touch device.
+ // QGuiApplication::setAttribute(Qt::AA_SynthesizeTouchForUnhandledMouseEvents, true);
+
+ QGuiApplication app(argc, argv);
+ QScreen *screen = QGuiApplication::primaryScreen();
+ QRect screenGeometry = screen->availableGeometry();
+
+ QSurfaceFormat format;
+ format.setDepthBufferSize(16);
+ format.setStencilBufferSize(8);
+
+ QRect geom = screenGeometry;
+ if (QCoreApplication::arguments().contains(QLatin1String("-nofullscreen")))
+ geom = QRect(screenGeometry.width() / 4, screenGeometry.height() / 4,
+ screenGeometry.width() / 2, screenGeometry.height() / 2);
+
+ CompositorWindow window(format, geom);
+ QWindowCompositor compositor(&window);
+
+ window.show();
+
+ return app.exec();
+}
diff --git a/examples/wayland/qwindow-compositor/qwindow-compositor.pro b/examples/wayland/qwindow-compositor/qwindow-compositor.pro
new file mode 100644
index 000000000..4bab000b5
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/qwindow-compositor.pro
@@ -0,0 +1,29 @@
+QT += gui gui-private core-private compositor
+
+LIBS += -L ../../lib
+#include (../../src/qt-compositor/qt-compositor.pri)
+
+HEADERS += \
+ compositorwindow.h \
+ qwindowcompositor.h \
+ textureblitter.h
+
+SOURCES += main.cpp \
+ compositorwindow.cpp \
+ qwindowcompositor.cpp \
+ textureblitter.cpp
+
+# to make QtCompositor/... style includes working without installing
+INCLUDEPATH += $$PWD/../../include
+
+# if you want to compile QtCompositor as part of the application
+# instead of linking to it, remove the QT += compositor and uncomment
+# the following line
+#include(../../src/compositor/compositor.pri)
+
+RESOURCES += qwindow-compositor.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/wayland/qwindow-compositor
+sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS qwindow-compositor.pro
+sources.path = $$[QT_INSTALL_EXAMPLES]/wayland/qwindow-compositor
+INSTALLS += target sources
diff --git a/examples/wayland/qwindow-compositor/qwindow-compositor.qrc b/examples/wayland/qwindow-compositor/qwindow-compositor.qrc
new file mode 100644
index 000000000..20dd10a53
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/qwindow-compositor.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="background.jpg">../qml-compositor/background.jpg</file>
+ </qresource>
+</RCC>
diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
new file mode 100644
index 000000000..c933152d8
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowcompositor.h"
+
+#include <QMouseEvent>
+#include <QKeyEvent>
+#include <QTouchEvent>
+#include <QOpenGLFunctions>
+#include <QOpenGLTexture>
+#include <QGuiApplication>
+#include <QCursor>
+#include <QPixmap>
+#include <QLinkedList>
+#include <QScreen>
+#include <QPainter>
+
+#include <QtCompositor/qwaylandinput.h>
+#include <QtCompositor/qwaylandbufferref.h>
+#include <QtCompositor/qwaylandsurfaceview.h>
+
+QT_BEGIN_NAMESPACE
+
+class BufferAttacher : public QWaylandBufferAttacher
+{
+public:
+ BufferAttacher()
+ : QWaylandBufferAttacher()
+ , shmTex(0)
+ {
+ }
+
+ ~BufferAttacher()
+ {
+ delete shmTex;
+ }
+
+ void attach(const QWaylandBufferRef &ref) Q_DECL_OVERRIDE
+ {
+ if (bufferRef) {
+ if (bufferRef.isShm()) {
+ delete shmTex;
+ shmTex = 0;
+ } else {
+ bufferRef.destroyTexture();
+ }
+ }
+
+ bufferRef = ref;
+
+ if (bufferRef) {
+ if (bufferRef.isShm()) {
+ shmTex = new QOpenGLTexture(bufferRef.image(), QOpenGLTexture::DontGenerateMipMaps);
+ texture = shmTex->textureId();
+ } else {
+ texture = bufferRef.createTexture();
+ }
+ }
+ }
+
+ QImage image() const
+ {
+ if (!bufferRef || !bufferRef.isShm())
+ return QImage();
+ return bufferRef.image();
+ }
+
+ QOpenGLTexture *shmTex;
+ QWaylandBufferRef bufferRef;
+ GLuint texture;
+};
+
+QWindowCompositor::QWindowCompositor(CompositorWindow *window)
+ : QWaylandCompositor(window, 0, DefaultExtensions | SubSurfaceExtension)
+ , m_window(window)
+ , m_backgroundTexture(0)
+ , m_textureBlitter(0)
+ , m_renderScheduler(this)
+ , m_draggingWindow(0)
+ , m_dragKeyIsPressed(false)
+ , m_cursorSurface(0)
+ , m_cursorHotspotX(0)
+ , m_cursorHotspotY(0)
+ , m_modifiers(Qt::NoModifier)
+{
+ m_window->makeCurrent();
+
+ m_textureBlitter = new TextureBlitter();
+ m_backgroundImage = makeBackgroundImage(QLatin1String(":/background.jpg"));
+ m_renderScheduler.setSingleShot(true);
+ connect(&m_renderScheduler,SIGNAL(timeout()),this,SLOT(render()));
+
+ QOpenGLFunctions *functions = m_window->context()->functions();
+ functions->glGenFramebuffers(1, &m_surface_fbo);
+
+ window->installEventFilter(this);
+
+ setRetainedSelectionEnabled(true);
+
+ setOutputGeometry(QRect(QPoint(0, 0), window->size()));
+ setOutputRefreshRate(qRound(qGuiApp->primaryScreen()->refreshRate() * 1000.0));
+ addDefaultShell();
+}
+
+QWindowCompositor::~QWindowCompositor()
+{
+ delete m_textureBlitter;
+}
+
+
+QImage QWindowCompositor::makeBackgroundImage(const QString &fileName)
+{
+ Q_ASSERT(m_window);
+
+ int width = m_window->width();
+ int height = m_window->height();
+ QImage baseImage(fileName);
+ QImage patternedBackground(width, height, baseImage.format());
+ QPainter painter(&patternedBackground);
+
+ QSize imageSize = baseImage.size();
+ for (int y = 0; y < height; y += imageSize.height()) {
+ for (int x = 0; x < width; x += imageSize.width()) {
+ painter.drawImage(x, y, baseImage);
+ }
+ }
+
+ return patternedBackground;
+}
+
+void QWindowCompositor::ensureKeyboardFocusSurface(QWaylandSurface *oldSurface)
+{
+ QWaylandSurface *kbdFocus = defaultInputDevice()->keyboardFocus();
+ if (kbdFocus == oldSurface || !kbdFocus)
+ defaultInputDevice()->setKeyboardFocus(m_surfaces.isEmpty() ? 0 : m_surfaces.last());
+}
+
+void QWindowCompositor::surfaceDestroyed()
+{
+ QWaylandSurface *surface = static_cast<QWaylandSurface *>(sender());
+ m_surfaces.removeOne(surface);
+ ensureKeyboardFocusSurface(surface);
+ m_renderScheduler.start(0);
+}
+
+void QWindowCompositor::surfaceMapped()
+{
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+ QPoint pos;
+ if (!m_surfaces.contains(surface)) {
+ if (surface->windowType() != QWaylandSurface::Popup) {
+ uint px = 0;
+ uint py = 0;
+ if (!QCoreApplication::arguments().contains(QLatin1String("-stickytopleft"))) {
+ px = 1 + (qrand() % (m_window->width() - surface->size().width() - 2));
+ py = 1 + (qrand() % (m_window->height() - surface->size().height() - 2));
+ }
+ pos = QPoint(px, py);
+ QWaylandSurfaceView *view = surface->views().first();
+ view->setPos(pos);
+ }
+ } else {
+ m_surfaces.removeOne(surface);
+ }
+
+ if (surface->windowType() == QWaylandSurface::Popup) {
+ QWaylandSurfaceView *view = surface->views().first();
+ view->setPos(surface->transientParent()->views().first()->pos() + surface->transientOffset());
+ }
+
+ m_surfaces.append(surface);
+ defaultInputDevice()->setKeyboardFocus(surface);
+
+ m_renderScheduler.start(0);
+}
+
+void QWindowCompositor::surfaceUnmapped()
+{
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+ if (m_surfaces.removeOne(surface))
+ m_surfaces.insert(0, surface);
+
+ ensureKeyboardFocusSurface(surface);
+ m_renderScheduler.start(0);
+}
+
+void QWindowCompositor::surfaceCommitted()
+{
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+ surfaceCommitted(surface);
+}
+
+void QWindowCompositor::surfacePosChanged()
+{
+ m_renderScheduler.start(0);
+}
+
+void QWindowCompositor::surfaceCommitted(QWaylandSurface *surface)
+{
+ Q_UNUSED(surface)
+ m_renderScheduler.start(0);
+}
+
+void QWindowCompositor::surfaceCreated(QWaylandSurface *surface)
+{
+ connect(surface, SIGNAL(surfaceDestroyed()), this, SLOT(surfaceDestroyed()));
+ connect(surface, SIGNAL(mapped()), this, SLOT(surfaceMapped()));
+ connect(surface, SIGNAL(unmapped()), this, SLOT(surfaceUnmapped()));
+ connect(surface, SIGNAL(redraw()), this, SLOT(surfaceCommitted()));
+ connect(surface, SIGNAL(extendedSurfaceReady()), this, SLOT(sendExpose()));
+ m_renderScheduler.start(0);
+
+ surface->setBufferAttacher(new BufferAttacher);
+}
+
+void QWindowCompositor::sendExpose()
+{
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+ surface->sendOnScreenVisibilityChange(true);
+}
+
+void QWindowCompositor::updateCursor(bool hasBuffer)
+{
+ Q_UNUSED(hasBuffer)
+ if (!m_cursorSurface)
+ return;
+
+ QImage image = static_cast<BufferAttacher *>(m_cursorSurface->bufferAttacher())->image();
+
+ QCursor cursor(QPixmap::fromImage(image), m_cursorHotspotX, m_cursorHotspotY);
+ static bool cursorIsSet = false;
+ if (cursorIsSet) {
+ QGuiApplication::changeOverrideCursor(cursor);
+ } else {
+ QGuiApplication::setOverrideCursor(cursor);
+ cursorIsSet = true;
+ }
+}
+
+QPointF QWindowCompositor::toView(QWaylandSurfaceView *view, const QPointF &pos) const
+{
+ return pos - view->pos();
+}
+
+void QWindowCompositor::setCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY)
+{
+ if ((m_cursorSurface != surface) && surface)
+ connect(surface, SIGNAL(configure(bool)), this, SLOT(updateCursor(bool)));
+
+ m_cursorSurface = surface;
+ m_cursorHotspotX = hotspotX;
+ m_cursorHotspotY = hotspotY;
+ if (m_cursorSurface && !m_cursorSurface->bufferAttacher())
+ m_cursorSurface->setBufferAttacher(new BufferAttacher);
+}
+
+QWaylandSurfaceView *QWindowCompositor::viewAt(const QPointF &point, QPointF *local)
+{
+ for (int i = m_surfaces.size() - 1; i >= 0; --i) {
+ QWaylandSurface *surface = m_surfaces.at(i);
+ foreach (QWaylandSurfaceView *view, surface->views()) {
+ QRectF geo(view->pos(), surface->size());
+ if (geo.contains(point)) {
+ if (local)
+ *local = toView(view, point);
+ return view;
+ }
+ }
+ }
+ return 0;
+}
+
+void QWindowCompositor::render()
+{
+ m_window->makeCurrent();
+ frameStarted();
+
+ cleanupGraphicsResources();
+
+ if (!m_backgroundTexture)
+ m_backgroundTexture = new QOpenGLTexture(m_backgroundImage, QOpenGLTexture::DontGenerateMipMaps);
+
+ m_textureBlitter->bind();
+ // Draw the background image texture
+ m_textureBlitter->drawTexture(m_backgroundTexture->textureId(),
+ QRect(QPoint(0, 0), m_backgroundImage.size()),
+ window()->size(),
+ 0, false, true);
+
+ foreach (QWaylandSurface *surface, m_surfaces) {
+ if (!surface->visible())
+ continue;
+ GLuint texture = static_cast<BufferAttacher *>(surface->bufferAttacher())->texture;
+ foreach (QWaylandSurfaceView *view, surface->views()) {
+ QRect geo(view->pos().toPoint(),surface->size());
+ m_textureBlitter->drawTexture(texture,geo,m_window->size(),0,false,surface->isYInverted());
+ foreach (QWaylandSurface *child, surface->subSurfaces()) {
+ drawSubSurface(view->pos().toPoint(), child);
+ }
+ }
+ }
+
+ m_textureBlitter->release();
+ sendFrameCallbacks(surfaces());
+
+ // N.B. Never call glFinish() here as the busylooping with vsync 'feature' of the nvidia binary driver is not desirable.
+ m_window->swapBuffers();
+}
+
+void QWindowCompositor::drawSubSurface(const QPoint &offset, QWaylandSurface *surface)
+{
+ GLuint texture = static_cast<BufferAttacher *>(surface->bufferAttacher())->texture;
+ QWaylandSurfaceView *view = surface->views().first();
+ QPoint pos = view->pos().toPoint() + offset;
+ QRect geo(pos, surface->size());
+ m_textureBlitter->drawTexture(texture, geo, m_window->size(), 0, false, surface->isYInverted());
+ foreach (QWaylandSurface *child, surface->subSurfaces()) {
+ drawSubSurface(pos, child);
+ }
+}
+
+bool QWindowCompositor::eventFilter(QObject *obj, QEvent *event)
+{
+ if (obj != m_window)
+ return false;
+
+ QWaylandInputDevice *input = defaultInputDevice();
+
+ switch (event->type()) {
+ case QEvent::Expose:
+ m_renderScheduler.start(0);
+ if (m_window->isExposed()) {
+ // Alt-tabbing away normally results in the alt remaining in
+ // pressed state in the clients xkb state. Prevent this by sending
+ // a release. This is not an issue in a "real" compositor but
+ // is very annoying when running in a regular window on xcb.
+ Qt::KeyboardModifiers mods = QGuiApplication::queryKeyboardModifiers();
+ if (m_modifiers != mods && input->keyboardFocus()) {
+ Qt::KeyboardModifiers stuckMods = m_modifiers ^ mods;
+ if (stuckMods & Qt::AltModifier)
+ input->sendKeyReleaseEvent(64); // native scancode for left alt
+ m_modifiers = mods;
+ }
+ }
+ break;
+ case QEvent::MouseButtonPress: {
+ QPointF local;
+ QMouseEvent *me = static_cast<QMouseEvent *>(event);
+ QWaylandSurfaceView *target = viewAt(me->localPos(), &local);
+ if (m_dragKeyIsPressed && target) {
+ m_draggingWindow = target;
+ m_drag_diff = local;
+ } else {
+ if (target && input->keyboardFocus() != target->surface()) {
+ input->setKeyboardFocus(target->surface());
+ m_surfaces.removeOne(target->surface());
+ m_surfaces.append(target->surface());
+ m_renderScheduler.start(0);
+ }
+ input->sendMousePressEvent(me->button(), local, me->localPos());
+ }
+ return true;
+ }
+ case QEvent::MouseButtonRelease: {
+ QWaylandSurfaceView *target = input->mouseFocus();
+ if (m_draggingWindow) {
+ m_draggingWindow = 0;
+ m_drag_diff = QPointF();
+ } else {
+ QMouseEvent *me = static_cast<QMouseEvent *>(event);
+ QPointF localPos;
+ if (target)
+ localPos = toView(target, me->localPos());
+ input->sendMouseReleaseEvent(me->button(), localPos, me->localPos());
+ }
+ return true;
+ }
+ case QEvent::MouseMove: {
+ QMouseEvent *me = static_cast<QMouseEvent *>(event);
+ if (m_draggingWindow) {
+ m_draggingWindow->setPos(me->localPos() - m_drag_diff);
+ m_renderScheduler.start(0);
+ } else {
+ QPointF local;
+ QWaylandSurfaceView *target = viewAt(me->localPos(), &local);
+ input->sendMouseMoveEvent(target, local, me->localPos());
+ }
+ break;
+ }
+ case QEvent::Wheel: {
+ QWheelEvent *we = static_cast<QWheelEvent *>(event);
+ input->sendMouseWheelEvent(we->orientation(), we->delta());
+ break;
+ }
+ case QEvent::KeyPress: {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+ if (ke->key() == Qt::Key_Meta || ke->key() == Qt::Key_Super_L) {
+ m_dragKeyIsPressed = true;
+ }
+ m_modifiers = ke->modifiers();
+ QWaylandSurface *targetSurface = input->keyboardFocus();
+ if (targetSurface)
+ input->sendKeyPressEvent(ke->nativeScanCode());
+ break;
+ }
+ case QEvent::KeyRelease: {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+ if (ke->key() == Qt::Key_Meta || ke->key() == Qt::Key_Super_L) {
+ m_dragKeyIsPressed = false;
+ }
+ m_modifiers = ke->modifiers();
+ QWaylandSurface *targetSurface = input->keyboardFocus();
+ if (targetSurface)
+ input->sendKeyReleaseEvent(ke->nativeScanCode());
+ break;
+ }
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+ QWaylandSurfaceView *target = 0;
+ QTouchEvent *te = static_cast<QTouchEvent *>(event);
+ QList<QTouchEvent::TouchPoint> points = te->touchPoints();
+ QPoint pointPos;
+ if (!points.isEmpty()) {
+ pointPos = points.at(0).pos().toPoint();
+ target = viewAt(pointPos);
+ }
+ if (target && target != input->mouseFocus())
+ input->setMouseFocus(target, pointPos, pointPos);
+ if (input->mouseFocus())
+ input->sendFullTouchEvent(te);
+ break;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.h b/examples/wayland/qwindow-compositor/qwindowcompositor.h
new file mode 100644
index 000000000..57f3e8536
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/qwindowcompositor.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWCOMPOSITOR_H
+#define QWINDOWCOMPOSITOR_H
+
+#include "qwaylandcompositor.h"
+#include "qwaylandsurface.h"
+#include "textureblitter.h"
+#include "compositorwindow.h"
+
+#include <QtGui/private/qopengltexturecache_p.h>
+#include <QObject>
+#include <QTimer>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandSurfaceView;
+class QOpenGLTexture;
+
+class QWindowCompositor : public QObject, public QWaylandCompositor
+{
+ Q_OBJECT
+public:
+ QWindowCompositor(CompositorWindow *window);
+ ~QWindowCompositor();
+
+private slots:
+ void surfaceDestroyed();
+ void surfaceMapped();
+ void surfaceUnmapped();
+ void surfaceCommitted();
+ void surfacePosChanged();
+
+ void render();
+protected:
+ void surfaceCommitted(QWaylandSurface *surface);
+ void surfaceCreated(QWaylandSurface *surface);
+
+ QWaylandSurfaceView* viewAt(const QPointF &point, QPointF *local = 0);
+
+ bool eventFilter(QObject *obj, QEvent *event);
+ QPointF toView(QWaylandSurfaceView *view, const QPointF &pos) const;
+
+ void setCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY);
+
+ void ensureKeyboardFocusSurface(QWaylandSurface *oldSurface);
+ QImage makeBackgroundImage(const QString &fileName);
+
+private slots:
+ void sendExpose();
+ void updateCursor(bool hasBuffer);
+
+private:
+ void drawSubSurface(const QPoint &offset, QWaylandSurface *surface);
+
+ CompositorWindow *m_window;
+ QImage m_backgroundImage;
+ QOpenGLTexture *m_backgroundTexture;
+ QList<QWaylandSurface *> m_surfaces;
+ TextureBlitter *m_textureBlitter;
+ GLuint m_surface_fbo;
+ QTimer m_renderScheduler;
+
+ //Dragging windows around
+ QWaylandSurfaceView *m_draggingWindow;
+ bool m_dragKeyIsPressed;
+ QPointF m_drag_diff;
+
+ //Cursor
+ QWaylandSurface *m_cursorSurface;
+ int m_cursorHotspotX;
+ int m_cursorHotspotY;
+
+ Qt::KeyboardModifiers m_modifiers;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWCOMPOSITOR_H
diff --git a/examples/wayland/qwindow-compositor/textureblitter.cpp b/examples/wayland/qwindow-compositor/textureblitter.cpp
new file mode 100644
index 000000000..813fd8966
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/textureblitter.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "textureblitter.h"
+
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
+
+QT_BEGIN_NAMESPACE
+
+TextureBlitter::TextureBlitter()
+ : m_shaderProgram(new QOpenGLShaderProgram)
+{
+ static const char *textureVertexProgram =
+ "uniform highp mat4 matrix;\n"
+ "attribute highp vec3 vertexCoordEntry;\n"
+ "attribute highp vec2 textureCoordEntry;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " textureCoord = textureCoordEntry;\n"
+ " gl_Position = matrix * vec4(vertexCoordEntry, 1);\n"
+ "}\n";
+
+ static const char *textureFragmentProgram =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 textureCoord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texture, textureCoord);\n"
+ "}\n";
+
+ //Enable transparent windows
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ m_shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ m_shaderProgram->link();
+}
+
+TextureBlitter::~TextureBlitter()
+{
+ delete m_shaderProgram;
+}
+
+void TextureBlitter::bind()
+{
+
+ m_shaderProgram->bind();
+
+ m_vertexCoordEntry = m_shaderProgram->attributeLocation("vertexCoordEntry");
+ m_textureCoordEntry = m_shaderProgram->attributeLocation("textureCoordEntry");
+ m_matrixLocation = m_shaderProgram->uniformLocation("matrix");
+}
+
+void TextureBlitter::release()
+{
+ m_shaderProgram->release();
+}
+
+void TextureBlitter::drawTexture(int textureId, const QRectF &targetRect, const QSize &targetSize, int depth, bool targethasInvertedY, bool sourceHasInvertedY)
+{
+
+ glViewport(0,0,targetSize.width(),targetSize.height());
+ GLfloat zValue = depth / 1000.0f;
+ //Set Texture and Vertex coordinates
+ const GLfloat textureCoordinates[] = {
+ 0, 0,
+ 1, 0,
+ 1, 1,
+ 0, 1
+ };
+
+ GLfloat x1 = targetRect.left();
+ GLfloat x2 = targetRect.right();
+ GLfloat y1, y2;
+ if (targethasInvertedY) {
+ if (sourceHasInvertedY) {
+ y1 = targetRect.top();
+ y2 = targetRect.bottom();
+ } else {
+ y1 = targetRect.bottom();
+ y2 = targetRect.top();
+ }
+ } else {
+ if (sourceHasInvertedY) {
+ y1 = targetSize.height() - targetRect.top();
+ y2 = targetSize.height() - targetRect.bottom();
+ } else {
+ y1 = targetSize.height() - targetRect.bottom();
+ y2 = targetSize.height() - targetRect.top();
+ }
+ }
+
+ const GLfloat vertexCoordinates[] = {
+ GLfloat(x1), GLfloat(y1), zValue,
+ GLfloat(x2), GLfloat(y1), zValue,
+ GLfloat(x2), GLfloat(y2), zValue,
+ GLfloat(x1), GLfloat(y2), zValue
+ };
+
+ //Set matrix to transfrom geometry values into gl coordinate space.
+ m_transformMatrix.setToIdentity();
+ m_transformMatrix.scale( 2.0f / targetSize.width(), 2.0f / targetSize.height() );
+ m_transformMatrix.translate(-targetSize.width() / 2.0f, -targetSize.height() / 2.0f);
+
+ //attach the data!
+ QOpenGLContext *currentContext = QOpenGLContext::currentContext();
+ currentContext->functions()->glEnableVertexAttribArray(m_vertexCoordEntry);
+ currentContext->functions()->glEnableVertexAttribArray(m_textureCoordEntry);
+
+ currentContext->functions()->glVertexAttribPointer(m_vertexCoordEntry, 3, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
+ currentContext->functions()->glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+ m_shaderProgram->setUniformValue(m_matrixLocation, m_transformMatrix);
+
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ currentContext->functions()->glDisableVertexAttribArray(m_vertexCoordEntry);
+ currentContext->functions()->glDisableVertexAttribArray(m_textureCoordEntry);
+}
+
+QT_END_NAMESPACE
diff --git a/examples/wayland/qwindow-compositor/textureblitter.h b/examples/wayland/qwindow-compositor/textureblitter.h
new file mode 100644
index 000000000..7426c6f29
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/textureblitter.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TEXTUREBLITTER_H
+#define TEXTUREBLITTER_H
+
+#include <QtGui/QMatrix4x4>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLShaderProgram;
+class TextureBlitter
+{
+public:
+ TextureBlitter();
+ ~TextureBlitter();
+ void bind();
+ void release();
+ void drawTexture(int textureId, const QRectF &sourceGeometry,
+ const QSize &targetRect, int depth,
+ bool targethasInvertedY, bool sourceHasInvertedY);
+
+private:
+ QOpenGLShaderProgram *m_shaderProgram;
+ QMatrix4x4 m_transformMatrix;
+
+ int m_matrixLocation;
+ int m_vertexCoordEntry;
+ int m_textureCoordEntry;
+};
+
+QT_END_NAMESPACE
+
+#endif // TEXTUREBLITTER_H
diff --git a/examples/wayland/server-buffer/README b/examples/wayland/server-buffer/README
new file mode 100644
index 000000000..762db4238
--- /dev/null
+++ b/examples/wayland/server-buffer/README
@@ -0,0 +1,17 @@
+This is the example to demonstrate the server buffer interfaces
+
+Compile up both compositor and client.
+
+If you have the drm-egl-server buffer integration (and your running Mesa)
+then start the compositor with:
+
+# QT_WAYLAND_SERVER_BUFFER_INTEGRATION=drm-egl-server ./compositor
+
+The compositor is using the hardware integration extension to boradcast
+to all clients to use the same server buffer integration, so all you need
+to do is to start the client with
+
+# ./client -platform wayland
+
+You should then see a red box in top left corner, with a black cross and
+a horisontal line in the top half (centered).
diff --git a/examples/wayland/server-buffer/client/client.pro b/examples/wayland/server-buffer/client/client.pro
new file mode 100644
index 000000000..ce4a04f91
--- /dev/null
+++ b/examples/wayland/server-buffer/client/client.pro
@@ -0,0 +1,17 @@
+TEMPLATE = app
+TARGET = client
+INCLUDEPATH += .
+
+QT += waylandclient-private
+CONFIG += link_pkgconfig
+PKGCONFIG += wayland-client
+
+CONFIG += wayland-scanner
+WAYLANDCLIENTSOURCES += ../share-buffer.xml
+
+SOURCES += \
+ main.cpp \
+ serverbufferrenderer.cpp
+
+HEADERS += \
+ serverbufferrenderer.h
diff --git a/examples/wayland/server-buffer/client/main.cpp b/examples/wayland/server-buffer/client/main.cpp
new file mode 100644
index 000000000..54c586ce6
--- /dev/null
+++ b/examples/wayland/server-buffer/client/main.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "serverbufferrenderer.h"
+
+#include <QtGui/QWindow>
+#include <QtGui/QGuiApplication>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformnativeinterface.h>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLVertexArrayObject>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLTexture>
+#include <QtCore/QTimer>
+
+#include "qwayland-share-buffer.h"
+#include <QtWaylandClient/private/qwayland-wayland.h>
+#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h>
+#include <QtWaylandClient/private/qwaylanddisplay_p.h>
+#include <QtWaylandClient/private/qwaylandintegration_p.h>
+
+
+class Window
+ : public QWindow
+ , public QtWayland::wl_registry
+ , public QtWayland::qt_share_buffer
+{
+ Q_OBJECT
+public:
+ Window(QWindow *parent = 0)
+ : QWindow(parent)
+ , m_context(0)
+ {
+ setSurfaceType(QSurface::OpenGLSurface);
+ QSurfaceFormat sformat = format();
+ sformat.setAlphaBufferSize(8);
+ sformat.setRedBufferSize(8);
+ sformat.setGreenBufferSize(8);
+ sformat.setBlueBufferSize(8);
+ setFormat(sformat);
+ create();
+
+ if (!QGuiApplication::platformNativeInterface() || !QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display")) {
+ qDebug() << "This application requires a wayland plugin";
+ QCoreApplication::quit();
+ return;
+ }
+
+ QWaylandIntegration *wayland_integration = static_cast<QWaylandIntegration *>(QGuiApplicationPrivate::platformIntegration());
+
+ m_server_buffer_integration = wayland_integration->serverBufferIntegration();
+ if (!m_server_buffer_integration) {
+ qDebug() << "This application requires a working serverBufferIntegration";
+ QCoreApplication::quit();
+ return;
+ }
+
+
+ QWaylandDisplay *wayland_display = wayland_integration->display();
+ struct ::wl_registry *registry = wl_display_get_registry(wayland_display->wl_display());
+ wl_proxy_set_queue(reinterpret_cast<struct wl_proxy *>(registry), wayland_display->wl_event_queue());
+ QtWayland::wl_registry::init(registry);
+ }
+
+public slots:
+ void render()
+ {
+ if (m_server_buffer_list.isEmpty())
+ return;
+
+ if (!m_context) {
+ m_context = new QOpenGLContext(this);
+ m_context->setFormat(format());
+ m_context->create();
+ }
+
+ m_context->makeCurrent(this);
+ QOpenGLFunctions *funcs = m_context->functions();
+ funcs->glBindFramebuffer(GL_FRAMEBUFFER, m_context->defaultFramebufferObject());
+
+ glViewport(0, 0, width() * devicePixelRatio(), height() * devicePixelRatio());
+ glClearColor(0.f, 0.f, 0.0f, 1.f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ qreal x = 0;
+ for (int i = 0; i < m_server_buffer_list.size(); i++) {
+ ServerBufferRenderer *renderer = static_cast<ServerBufferRenderer *>(m_server_buffer_list[i]->userData());
+ if (!renderer) {
+ renderer = new ServerBufferRenderer(m_server_buffer_list.at(i));
+ }
+
+ const QSizeF buffer_size = m_server_buffer_list.at(i)->size();
+ qreal scale_x = buffer_size.width() / width();
+ qreal scale_y = buffer_size.height() / height() * - 1;
+ qreal translate_left = (((buffer_size.width() / 2) / width()) * 2) - 1;
+ qreal translate_top = -(((buffer_size.height() / 2) / height()) * 2) + 1;
+ qreal translate_x = translate_left + ((x / width())*2);
+
+ QMatrix4x4 transform;
+ transform.translate(translate_x, translate_top);
+ transform.scale(scale_x, scale_y);
+ renderer->render(transform);
+
+ x += buffer_size.width();
+ }
+
+ m_context->swapBuffers(this);
+ }
+
+protected:
+ void registry_global(uint32_t name, const QString &interface, uint32_t version) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(version);
+ if (interface == QStringLiteral("qt_share_buffer")) {
+ QtWayland::qt_share_buffer::init(QtWayland::wl_registry::object(), name, 1);
+ }
+ }
+
+ void share_buffer_cross_buffer(struct ::qt_server_buffer *buffer) Q_DECL_OVERRIDE
+ {
+ QWaylandServerBuffer *serverBuffer = m_server_buffer_integration->serverBuffer(buffer);
+ if (m_server_buffer_list.isEmpty()) {
+ setWidth(serverBuffer->size().width());
+ setHeight(serverBuffer->size().height());
+ } else {
+ setWidth(width() + serverBuffer->size().width());
+ setHeight(std::max(serverBuffer->size().height(), height()));
+ }
+ m_server_buffer_list.append(serverBuffer);
+ render();
+ }
+
+private:
+ QWaylandServerBufferIntegration *m_server_buffer_integration;
+ QList<QWaylandServerBuffer *>m_server_buffer_list;
+ GLuint m_server_buffer_texture;
+ QOpenGLContext *m_context;
+ QOpenGLVertexArrayObject *m_vao;
+ GLuint m_vertexbuffer;
+ GLuint m_texture_coords;
+ QOpenGLShaderProgram *m_shader_program;
+ QOpenGLTexture *m_image_texture;
+};
+
+int main (int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+
+ Window window;
+ window.show();
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/examples/wayland/server-buffer/client/serverbufferrenderer.cpp b/examples/wayland/server-buffer/client/serverbufferrenderer.cpp
new file mode 100644
index 000000000..2f0d204d3
--- /dev/null
+++ b/examples/wayland/server-buffer/client/serverbufferrenderer.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "serverbufferrenderer.h"
+
+#include <QtGui/QOpenGLVertexArrayObject>
+#include <QtGui/QOpenGLShaderProgram>
+
+static const GLfloat uv_coords[] = {
+ 0,0,
+ 0,1,
+ 1,0,
+ 1,1,
+};
+
+static const GLfloat vertex_coords[] = {
+ -1,-1,0,
+ -1,1,0,
+ 1,-1,0,
+ 1,1,0,
+};
+
+static const char vertex_shader[] =
+ "attribute vec3 vertexCoord;"
+ "attribute vec2 textureCoord;"
+ "uniform mat4 transform;"
+ "varying mediump vec2 uv;"
+ "void main() {"
+ " uv = textureCoord;"
+ " gl_Position = transform * vec4(vertexCoord,1);"
+ "}";
+
+static const char fragment_shader[] =
+ "varying mediump vec2 uv;"
+ "uniform sampler2D textureSampler;"
+ "void main() {"
+ " gl_FragColor = texture2D(textureSampler, uv);"
+ "}";
+
+ServerBufferRenderer::ServerBufferRenderer(QWaylandServerBuffer *serverBuffer)
+ : QOpenGLFunctions(QOpenGLContext::currentContext())
+ , m_server_buffer(serverBuffer)
+ , m_texture(0)
+ , m_vao(new QOpenGLVertexArrayObject())
+ , m_program(new QOpenGLShaderProgram())
+ , m_vertexbuffer(0)
+ , m_texture_coords(0)
+
+{
+ Q_ASSERT(serverBuffer);
+ if (serverBuffer->userData()) {
+ qWarning("ServerBufferRenderer: Will over QWaylandServerBuffers %p userdata %p", serverBuffer, serverBuffer->userData());
+ }
+ serverBuffer->setUserData(this);
+ m_vao->create();
+ m_vao->bind();
+
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader);
+ if (!m_program->link()) {
+ qDebug() << m_program->log();
+ }
+
+ glGenTextures(1,&m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ serverBuffer->bindTextureToBuffer();
+
+ glGenBuffers(1, &m_vertexbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_coords), vertex_coords, GL_STATIC_DRAW);
+ m_program->setAttributeBuffer("vertexCoord", GL_FLOAT, 0, 3, 0);
+
+ glGenBuffers(1, &m_texture_coords);
+ glBindBuffer(GL_ARRAY_BUFFER, m_texture_coords);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(uv_coords), uv_coords, GL_STATIC_DRAW);
+ m_program->setAttributeBuffer("textureCoord", GL_FLOAT, 0, 2, 0);
+
+ m_program->enableAttributeArray("vertexCoord");
+ m_program->enableAttributeArray("textureCoord");
+
+ m_vao->release();
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+void ServerBufferRenderer::render(const QMatrix4x4 &transform)
+{
+ m_vao->bind();
+
+ m_program->bind();
+ m_program->setUniformValue("transform", transform);
+
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ m_vao->release();
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
diff --git a/examples/wayland/server-buffer/client/serverbufferrenderer.h b/examples/wayland/server-buffer/client/serverbufferrenderer.h
new file mode 100644
index 000000000..7e8999b1c
--- /dev/null
+++ b/examples/wayland/server-buffer/client/serverbufferrenderer.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SERVERBUFFERRENDERER_H
+#define SERVERBUFFERRENDERER_H
+
+#include <QtWaylandClient/private/qwaylandserverbufferintegration_p.h>
+#include <QtGui/QOpenGLFunctions>
+#include <QMatrix4x4>
+QT_BEGIN_NAMESPACE
+
+class QOpenGLVertexArrayObject;
+class QOpenGLShaderProgram;
+
+class ServerBufferRenderer : public QOpenGLFunctions
+{
+public:
+ ServerBufferRenderer(QWaylandServerBuffer *serverBuffer);
+
+ void render(const QMatrix4x4 &transform);
+private:
+ QWaylandServerBuffer *m_server_buffer;
+ GLuint m_texture;
+
+ QOpenGLVertexArrayObject *m_vao;
+ QOpenGLShaderProgram *m_program;
+
+ GLuint m_vertexbuffer;
+ GLuint m_texture_coords;
+};
+
+QT_END_NAMESPACE
+#endif
diff --git a/examples/wayland/server-buffer/compositor/compositor.pro b/examples/wayland/server-buffer/compositor/compositor.pro
new file mode 100644
index 000000000..9f7751a09
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/compositor.pro
@@ -0,0 +1,23 @@
+QT += core-private gui-private quick-private compositor-private
+
+LIBS += -lwayland-server
+
+SOURCES += \
+ main.cpp \
+ serverbufferitem.cpp
+HEADERS += \
+ serverbufferitem.h \
+
+OTHER_FILES = \
+ qml/main.qml \
+ images/background.jpg \
+
+RESOURCES += compositor.qrc
+
+CONFIG +=wayland-scanner
+WAYLANDSERVERSOURCES += ../share-buffer.xml
+
+CONFIG += link_pkgconfig
+PKGCONFIG += wayland-server
+
+DEFINES += QT_COMPOSITOR_QUICK
diff --git a/examples/wayland/server-buffer/compositor/compositor.qrc b/examples/wayland/server-buffer/compositor/compositor.qrc
new file mode 100644
index 000000000..dbbbfb1cf
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/compositor.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/background.jpg</file>
+ <file>qml/main.qml</file>
+ <file>qml/ServerBufferContainer.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/wayland/server-buffer/compositor/images/background.jpg b/examples/wayland/server-buffer/compositor/images/background.jpg
new file mode 100644
index 000000000..445567fbd
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/images/background.jpg
Binary files differ
diff --git a/examples/wayland/server-buffer/compositor/main.cpp b/examples/wayland/server-buffer/compositor/main.cpp
new file mode 100644
index 000000000..9f86539fd
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/main.cpp
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandquickcompositor.h"
+#include "qwaylandsurface.h"
+#include "qwaylandsurfaceitem.h"
+
+#include <QGuiApplication>
+#include <QTimer>
+#include <QPainter>
+#include <QMouseEvent>
+#include <QOpenGLContext>
+
+#include <QQmlContext>
+
+#include <QQuickItem>
+#include <QQuickView>
+
+#include "qwayland-server-share-buffer.h"
+#include <QtCompositor/private/qwlcompositor_p.h>
+#include <QtCompositor/private/qwlserverbufferintegration_p.h>
+
+#include "serverbufferitem.h"
+
+#include <QtGui/private/qdistancefield_p.h>
+
+class QmlCompositor
+ : public QQuickView
+ , public QWaylandQuickCompositor
+ , public QtWaylandServer::qt_share_buffer
+{
+ Q_OBJECT
+
+public:
+ QmlCompositor()
+ : QWaylandQuickCompositor(this, 0, DefaultExtensions | SubSurfaceExtension)
+ , QtWaylandServer::qt_share_buffer(QWaylandCompositor::handle()->wl_display(), 1)
+ , m_server_buffer_32_bit(0)
+ , m_server_buffer_item_32_bit(0)
+ , m_server_buffer_8_bit(0)
+ , m_server_buffer_item_8_bit(0)
+ {
+ setSource(QUrl("qrc:/qml/main.qml"));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+ setColor(Qt::black);
+ create();
+ grabWindow();
+ addDefaultShell();
+
+ connect(this, SIGNAL(afterRendering()), this, SLOT(sendCallbacks()));
+
+ connect(this, SIGNAL(sceneGraphInitialized()), this, SLOT(initiateServerBuffer()),Qt::DirectConnection);
+ connect(this, SIGNAL(serverBuffersCreated()), this, SLOT(createServerBufferItems()));
+ }
+
+ Q_INVOKABLE QWaylandSurfaceItem *item(QWaylandSurface *surf)
+ {
+ return static_cast<QWaylandSurfaceItem *>(surf->views().first());
+ }
+
+signals:
+ void windowAdded(QVariant window);
+ void windowDestroyed(QVariant window);
+ void windowResized(QVariant window);
+ void serverBufferItemCreated(QVariant);
+ void serverBuffersCreated();
+
+public slots:
+ void destroyClientForWindow(QVariant window)
+ {
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(qvariant_cast<QObject *>(window));
+ destroyClientForSurface(surface);
+ }
+
+private slots:
+ void surfaceMapped() {
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+ emit windowAdded(QVariant::fromValue(surface));
+ }
+
+ void surfaceUnmapped() {
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+ emit windowDestroyed(QVariant::fromValue(surface));
+ }
+
+ void surfaceDestroyed(QObject *object) {
+ QWaylandSurface *surface = static_cast<QWaylandSurface *>(object);
+ emit windowDestroyed(QVariant::fromValue(surface));
+ }
+
+ void sendCallbacks() {
+ sendFrameCallbacks(surfaces());
+ }
+
+ void initiateServerBuffer()
+ {
+ if (!QWaylandCompositor::handle()->serverBufferIntegration())
+ return;
+
+ openglContext()->makeCurrent(this);
+
+ QtWayland::ServerBufferIntegration *sbi = QWaylandCompositor::handle()->serverBufferIntegration();
+ if (!sbi) {
+ qWarning("Could not find a Server Buffer Integration");
+ return;
+ }
+ if (sbi->supportsFormat(QtWayland::ServerBuffer::RGBA32)) {
+ QImage image(100,100,QImage::Format_ARGB32_Premultiplied);
+ image.fill(QColor(0x55,0x0,0x55,0x01));
+ {
+ QPainter p(&image);
+ QPen pen = p.pen();
+ pen.setWidthF(3);
+ pen.setColor(Qt::red);
+ p.setPen(pen);
+ p.drawLine(0,0,100,100);
+ pen.setColor(Qt::green);
+ p.setPen(pen);
+ p.drawLine(100,0,0,100);
+ pen.setColor(Qt::blue);
+ p.setPen(pen);
+ p.drawLine(25,15,75,15);
+ }
+ image = image.convertToFormat(QImage::Format_RGBA8888);
+
+ m_server_buffer_32_bit = sbi->createServerBuffer(image.size(),QtWayland::ServerBuffer::RGBA32);
+
+ GLuint texture_32_bit;
+ glGenTextures(1, &texture_32_bit);
+ glBindTexture(GL_TEXTURE_2D, texture_32_bit);
+ m_server_buffer_32_bit->bindTextureToBuffer();
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.width(), image.height(), GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &texture_32_bit);
+
+ }
+
+ if (sbi->supportsFormat(QtWayland::ServerBuffer::A8)) {
+ QRawFont defaultRaw = QRawFont::fromFont(QFont(), QFontDatabase::Latin);
+ QVector<quint32> index = defaultRaw.glyphIndexesForString(QStringLiteral("R"));
+ QDistanceField distanceField(defaultRaw, index.front(), true);
+ QImage img = distanceField.toImage(QImage::Format_Indexed8);
+
+ m_server_buffer_8_bit = sbi->createServerBuffer(img.size(), QtWayland::ServerBuffer::A8);
+ GLuint texture_8_bit;
+ glGenTextures(1, &texture_8_bit);
+ glBindTexture(GL_TEXTURE_2D, texture_8_bit);
+ m_server_buffer_8_bit->bindTextureToBuffer();
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.width(), img.height(), GL_ALPHA, GL_UNSIGNED_BYTE, img.constBits());
+ }
+ emit serverBuffersCreated();
+ }
+
+ void createServerBufferItems()
+ {
+ if (m_server_buffer_32_bit) {
+ m_server_buffer_item_32_bit = new ServerBufferItem(m_server_buffer_32_bit);
+ m_server_buffer_item_32_bit->setUseTextureAlpha(true);
+ emit serverBufferItemCreated(QVariant::fromValue(m_server_buffer_item_32_bit));
+ }
+ if (m_server_buffer_8_bit) {
+ m_server_buffer_item_8_bit = new ServerBufferItem(m_server_buffer_8_bit);
+ m_server_buffer_item_8_bit->setUseTextureAlpha(true);
+ emit serverBufferItemCreated(QVariant::fromValue(m_server_buffer_item_8_bit));
+ }
+ }
+protected:
+ void resizeEvent(QResizeEvent *event)
+ {
+ QQuickView::resizeEvent(event);
+ QWaylandCompositor::setOutputGeometry(QRect(0, 0, width(), height()));
+ }
+
+ void surfaceCreated(QWaylandSurface *surface) {
+ connect(surface, SIGNAL(mapped()), this, SLOT(surfaceMapped()));
+ connect(surface,SIGNAL(unmapped()), this,SLOT(surfaceUnmapped()));
+ }
+
+ void share_buffer_bind_resource(Resource *resource) Q_DECL_OVERRIDE
+ {
+ if (m_server_buffer_32_bit) {
+ struct ::wl_client *client = resource->handle->client;
+ struct ::wl_resource *buffer = m_server_buffer_32_bit->resourceForClient(client);
+ send_cross_buffer(resource->handle, buffer);
+
+ }
+ if (m_server_buffer_8_bit) {
+ struct ::wl_client *client = resource->handle->client;
+ struct ::wl_resource *buffer = m_server_buffer_8_bit->resourceForClient(client);
+ send_cross_buffer(resource->handle, buffer);
+
+ }
+ }
+
+private:
+ QtWayland::ServerBuffer *m_server_buffer_32_bit;
+ ServerBufferItem *m_server_buffer_item_32_bit;
+ QtWayland::ServerBuffer *m_server_buffer_8_bit;
+ ServerBufferItem *m_server_buffer_item_8_bit;
+};
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ if (!app.arguments().contains(QStringLiteral("--invert"))) {
+ qDebug() << "iverting";
+ qputenv("QT_COMPOSITOR_NEGATE_INVERTED_Y", "1");
+ }
+
+ qmlRegisterType<ServerBufferItem>();
+
+ QmlCompositor compositor;
+ compositor.setTitle(QLatin1String("QML Compositor"));
+ compositor.setGeometry(0, 0, 1024, 768);
+ compositor.show();
+
+ compositor.rootContext()->setContextProperty("compositor", &compositor);
+
+ QObject::connect(&compositor, SIGNAL(windowAdded(QVariant)), compositor.rootObject(), SLOT(windowAdded(QVariant)));
+ QObject::connect(&compositor, SIGNAL(windowResized(QVariant)), compositor.rootObject(), SLOT(windowResized(QVariant)));
+ QObject::connect(&compositor, SIGNAL(serverBufferItemCreated(QVariant)), compositor.rootObject(), SLOT(serverBufferItemCreated(QVariant)));
+
+ app.exec();
+ qDebug() << "ending" << glGetError();
+}
+
+#include "main.moc"
diff --git a/examples/wayland/server-buffer/compositor/qml/ServerBufferContainer.qml b/examples/wayland/server-buffer/compositor/qml/ServerBufferContainer.qml
new file mode 100644
index 000000000..7c7306e36
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/qml/ServerBufferContainer.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: container
+
+ Item {
+ id: bufferContainer
+ property var serverBuffer
+ property int depth: serverBuffer == null ? 0 : serverBuffer.depth
+ width: serverBuffer == null ? 0 : serverBuffer.width
+ height: serverBuffer == null ? 0 : serverBuffer.height
+ }
+
+ width: bufferContainer.width
+ height: bufferContainer.height + text.height
+
+ Rectangle {
+ anchors.top: bufferContainer.bottom
+ width: parent.width
+ height: text.paintedHeight
+ color: "light grey"
+ Text {
+ id: text
+ anchors.fill: parent
+ text: bufferContainer.depth == 8 ? "8 bit Server Side buffer" : "32 bit Server Side buffer\nHorizontal line should be blue"
+ z: bufferContainer.z + 1
+ wrapMode: Text.WordWrap
+ }
+ }
+
+ function setServerBuffer(serverBuffer) {
+ serverBuffer.parent = bufferContainer;
+ bufferContainer.serverBuffer = serverBuffer
+ }
+}
diff --git a/examples/wayland/server-buffer/compositor/qml/main.qml b/examples/wayland/server-buffer/compositor/qml/main.qml
new file mode 100644
index 000000000..c9d62be55
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/qml/main.qml
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtCompositor 1.0
+
+Item {
+ id: root
+
+ property var serverBufferContainerComponent : Qt.createComponent("qrc:/qml/ServerBufferContainer.qml")
+
+ Image {
+ id: background
+ anchors.fill: parent
+ fillMode: Image.Tile
+ source: "qrc:/images/background.jpg"
+ smooth: true
+ }
+
+ Row {
+ id: row
+ anchors.fill: parent
+ }
+
+ function windowAdded(window) {
+ var item = compositor.item(window);
+ item.parent = root;
+ item.surfaceDestroyed.connect(item.destroy);
+ }
+
+ function windowResized(window) {
+ }
+
+ function removeWindow(window) {
+ }
+
+ function serverBufferItemCreated(serverBufferItem) {
+ console.log("ServerBuffer item" + serverBufferItem);
+ if (serverBufferContainerComponent.status != Component.Ready) {
+ console.log("Error loading component:", component.errorString());
+ return;
+ }
+ var container = serverBufferContainerComponent.createObject(row);
+ container.setServerBuffer(serverBufferItem);
+ }
+}
diff --git a/examples/wayland/server-buffer/compositor/serverbufferitem.cpp b/examples/wayland/server-buffer/compositor/serverbufferitem.cpp
new file mode 100644
index 000000000..4a47c279d
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/serverbufferitem.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "serverbufferitem.h"
+
+#include "serverbuffertextureprovider.h"
+
+#include <QtQuick/QSGSimpleTextureNode>
+#include <QtQuick/QQuickWindow>
+
+#include <QtCompositor/private/qwlserverbufferintegration_p.h>
+
+QT_BEGIN_NAMESPACE
+
+ServerBufferItem::ServerBufferItem(QtWayland::ServerBuffer *serverBuffer, QQuickItem *parent)
+ : QQuickItem(parent)
+ , m_server_buffer(serverBuffer)
+ , m_provider(new ServerBufferTextureProvider)
+ , m_useTextureAlpha(false)
+{
+ setFlag(QQuickItem::ItemHasContents);
+ setWidth(serverBuffer->size().width());
+ setHeight(serverBuffer->size().height());
+ update();
+}
+
+ServerBufferItem::~ServerBufferItem()
+{
+}
+
+bool ServerBufferItem::isYInverted() const
+{
+ return m_server_buffer->isYInverted();
+}
+
+int ServerBufferItem::depth() const
+{
+ return m_server_buffer->format() == QtWayland::ServerBuffer::RGBA32 ? 32 : 8;
+}
+
+QSGTextureProvider *ServerBufferItem::textureProvider() const
+{
+ return m_provider;
+}
+
+void ServerBufferItem::updateTexture()
+{
+ if (m_provider->texture())
+ return;
+
+ QQuickWindow::CreateTextureOptions opt = QQuickWindow::TextureHasAlphaChannel;
+ GLuint texture;
+ glGenTextures(1,&texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ m_server_buffer->bindTextureToBuffer();
+ m_provider->setTexture(window()->createTextureFromId(texture, m_server_buffer->size(), opt));
+}
+
+QSGNode *ServerBufferItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ updateTexture();
+ QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);
+
+ if (!node) {
+ node = new QSGSimpleTextureNode();
+ }
+
+ node->setTexture(m_provider->texture());
+
+ if (isYInverted()) {
+ node->setRect(0, height(), width(), -height());
+ } else {
+ node->setRect(0, 0, width(), height());
+ }
+
+ return node;
+}
+
+void ServerBufferItem::setUseTextureAlpha(bool useTextureAlpha)
+{
+ m_useTextureAlpha = useTextureAlpha;
+
+ if ((flags() & ItemHasContents) != 0) {
+ update();
+ }
+}
+
+QT_END_NAMESPACE
+
diff --git a/examples/wayland/server-buffer/compositor/serverbufferitem.h b/examples/wayland/server-buffer/compositor/serverbufferitem.h
new file mode 100644
index 000000000..31fad4e86
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/serverbufferitem.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SERVERBUFFERITEM_H
+#define SERVERBUFFERITEM_H
+
+#include <QtQuick/QQuickItem>
+#include <QtQuick/qsgtexture.h>
+
+#include <QtQuick/qsgtextureprovider.h>
+
+QT_BEGIN_NAMESPACE
+
+class ServerBufferTextureProvider;
+
+namespace QtWayland {
+class ServerBuffer;
+}
+
+class ServerBufferItem : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QtWayland::ServerBuffer *serverBuffer READ serverBuffer CONSTANT)
+ Q_PROPERTY(bool useTextureAlpha READ useTextureAlpha WRITE setUseTextureAlpha NOTIFY useTextureAlphaChanged)
+ Q_PROPERTY(bool isYInverted READ isYInverted NOTIFY yInvertedChanged)
+ Q_PROPERTY(int depth READ depth CONSTANT)
+
+public:
+ ServerBufferItem(QtWayland::ServerBuffer *serverBuffer, QQuickItem *parent = 0);
+ ~ServerBufferItem();
+
+ QtWayland::ServerBuffer *serverBuffer() const { return m_server_buffer; }
+
+ bool isYInverted() const;
+ int depth() const;
+
+ bool isTextureProvider() const { return true; }
+ QSGTextureProvider *textureProvider() const;
+
+ bool useTextureAlpha() const { return m_useTextureAlpha; }
+ void setUseTextureAlpha(bool useTextureAlpha);
+
+ void setDamagedFlag(bool on);
+
+signals:
+ void useTextureAlphaChanged();
+ void yInvertedChanged();
+ void serverBufferChanged();
+
+protected:
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
+
+private:
+ void updateTexture();
+ QtWayland::ServerBuffer *m_server_buffer;
+ ServerBufferTextureProvider *m_provider;
+ bool m_useTextureAlpha;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/examples/wayland/server-buffer/compositor/serverbuffertextureprovider.h b/examples/wayland/server-buffer/compositor/serverbuffertextureprovider.h
new file mode 100644
index 000000000..76ff5a4ac
--- /dev/null
+++ b/examples/wayland/server-buffer/compositor/serverbuffertextureprovider.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Compositor.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SERVERBUFFERTEXTUREPROVIDER_H
+#define SERVERBUFFERTEXTUREPROVIDER_H
+
+#include <QtQuick/QSGTextureProvider>
+
+QT_BEGIN_NAMESPACE
+
+class ServerBufferTextureProvider : public QSGTextureProvider
+{
+public:
+ ServerBufferTextureProvider() : t(0) { }
+ ~ServerBufferTextureProvider() { delete t; }
+
+ QSGTexture *texture() const {
+ if (t) {
+ t->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+ t->setVerticalWrapMode(QSGTexture::ClampToEdge);
+ t->setFiltering(QSGTexture::Linear);
+ }
+ return t;
+ }
+
+ void setTexture(QSGTexture *texture) {
+ if (texture != t) {
+ t = texture;
+ emit textureChanged();
+ }
+ }
+
+ bool smooth;
+private:
+ QSGTexture *t;
+};
+
+QT_END_NAMESPACE
+
+#endif //SERVERBUFFERTEXTUREPROVIDER_H
diff --git a/examples/wayland/server-buffer/server-buffer.pro b/examples/wayland/server-buffer/server-buffer.pro
new file mode 100644
index 000000000..16c556251
--- /dev/null
+++ b/examples/wayland/server-buffer/server-buffer.pro
@@ -0,0 +1,3 @@
+TEMPLATE=subdirs
+
+SUBDIRS += client compositor
diff --git a/examples/wayland/server-buffer/share-buffer.xml b/examples/wayland/server-buffer/share-buffer.xml
new file mode 100644
index 000000000..57a1fd2c5
--- /dev/null
+++ b/examples/wayland/server-buffer/share-buffer.xml
@@ -0,0 +1,46 @@
+<protocol name="share_buffer">
+
+ <copyright>
+ Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+ Contact: http://www.qt-project.org/legal
+
+ This file is part of the plugins of the Qt Toolkit.
+
+ $QT_BEGIN_LICENSE:BSD$
+ You may use this file under the terms of the BSD license as follows:
+
+ "Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+ of its contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+
+ $QT_END_LICENSE$
+ </copyright>
+
+ <interface name="qt_share_buffer" version="1">
+ <event name="cross_buffer">
+ <arg name="buffer" type="object" interface="qt_server_buffer"/>
+ </event>
+ </interface>
+</protocol>
diff --git a/examples/wayland/wayland.pro b/examples/wayland/wayland.pro
new file mode 100644
index 000000000..d633fb924
--- /dev/null
+++ b/examples/wayland/wayland.pro
@@ -0,0 +1,13 @@
+TEMPLATE=subdirs
+
+#Only build compositor examples if we are building
+#the QtCompositor API
+contains(CONFIG, wayland-compositor) {
+ SUBDIRS += qwindow-compositor
+
+ qtHaveModule(quick) {
+ SUBDIRS += qml-compositor
+ }
+
+ SUBDIRS += server-buffer
+}