--- /dev/null
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** 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 Nokia Corporation 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.
+**
+****************************************************************************/
+
+#include "qtcompositor.h"
+
+#include "waylandsurface.h"
+
+#include <QApplication>
+#include <QTimer>
+#include <QPainter>
+#include <QMouseEvent>
+
+#include <QDeclarativeView>
+
+#ifdef QT_COMPOSITOR_WAYLAND_GL
+#include <QGLContext>
+#include <QGLWidget>
+#endif
+
+#include <QtDeclarative/adaptationlayer.h>
+#include <QSGContext>
+#include <QSGItem>
+#include <QSGTextureManager>
+#include <QSGTextureProvider>
+#include <QSGView>
+
+#include <private/qsgitem_p.h>
+#include <private/qsgrectangle_p.h>
+
+class WaylandSurfaceTextureProvider : public QSGTextureProvider
+{
+ Q_OBJECT
+public:
+ WaylandSurfaceTextureProvider(WaylandSurface *surface);
+ ~WaylandSurfaceTextureProvider();
+
+ QSGTextureRef texture() {
+ return m_textureRef;
+ }
+
+private slots:
+ void surfaceDamaged(const QRect &rect);
+
+private:
+ WaylandSurface *m_surface;
+
+ QSGTexture *m_texture;
+ QSGTextureRef m_textureRef;
+};
+
+WaylandSurfaceTextureProvider::WaylandSurfaceTextureProvider(WaylandSurface *surface)
+ : m_surface(surface)
+ , m_texture(new QSGTexture)
+ , m_textureRef(m_texture)
+{
+ connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
+}
+
+WaylandSurfaceTextureProvider::~WaylandSurfaceTextureProvider()
+{
+}
+
+void WaylandSurfaceTextureProvider::surfaceDamaged(const QRect &)
+{
+ if (m_surface->type() == WaylandSurface::Texture) {
+ m_texture->setTextureId(m_surface->texture());
+ m_texture->setAlphaChannel(false);
+ } else {
+ if (m_texture->status() == QSGTexture::Null) {
+ GLuint textureId;
+ glGenTextures(1, &textureId);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ m_texture->setTextureId(textureId);
+ }
+
+ const QImage image = m_surface->image();
+
+ glBindTexture(GL_TEXTURE_2D, m_texture->textureId());
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, image.width(), image.height(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, image.bits());
+
+ m_texture->setAlphaChannel(image.hasAlphaChannel());
+ }
+
+ m_texture->setTextureSize(m_surface->geometry().size());
+ m_texture->setOwnsTexture(true);
+ m_texture->setHasMipmaps(false);
+ m_texture->setStatus(QSGTexture::Ready);
+
+ emit textureChanged();
+}
+
+class WindowItem : public QSGItem, public QSGTextureProviderInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QSGTextureProviderInterface)
+public:
+ WindowItem(WaylandSurface *surface, QSGItem *parent = 0);
+ ~WindowItem();
+
+ QSGTextureProvider *textureProvider() const
+ {
+ return m_textureProvider;
+ }
+
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+private slots:
+ void surfaceMapped(const QRect &rect);
+
+protected:
+ Node *updatePaintNode(Node *oldNode, UpdatePaintNodeData *);
+
+private:
+ QPoint toSurface(const QPointF &pos) const;
+
+ WaylandSurface *m_surface;
+ WaylandSurfaceTextureProvider *m_textureProvider;
+};
+
+WindowItem::WindowItem(WaylandSurface *surface, QSGItem *parent)
+ : QSGItem(parent)
+ , m_surface(surface)
+ , m_textureProvider(new WaylandSurfaceTextureProvider(surface))
+{
+ setSmooth(true);
+ setFlag(ItemHasContents);
+ setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
+ connect(surface, SIGNAL(mapped(const QRect &)), this, SLOT(surfaceMapped(const QRect &)));
+ connect(m_textureProvider, SIGNAL(textureChanged()), this, SLOT(update()));
+}
+
+WindowItem::~WindowItem()
+{
+ delete m_textureProvider;
+}
+
+void WindowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ m_surface->setInputFocus();
+ m_surface->sendMousePressEvent(toSurface(event->pos()), event->button());
+}
+
+void WindowItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ m_surface->setInputFocus();
+ m_surface->sendMouseMoveEvent(toSurface(event->pos()));
+}
+
+void WindowItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ m_surface->setInputFocus();
+ m_surface->sendMouseReleaseEvent(toSurface(event->pos()), event->button());
+}
+
+QPoint WindowItem::toSurface(const QPointF &pos) const
+{
+ return pos.toPoint();
+}
+
+void WindowItem::surfaceMapped(const QRect &rect)
+{
+ setWidth(rect.width());
+ setHeight(rect.height());
+
+ update();
+}
+
+Node *WindowItem::updatePaintNode(Node *oldNode, UpdatePaintNodeData *)
+{
+ TextureNodeInterface *node = static_cast<TextureNodeInterface *>(oldNode);
+ if (!node) {
+ node = QSGContext::current->createTextureNode();
+ node->setFlag(Node::UsePreprocess, false);
+ node->setTexture(m_textureProvider);
+ }
+
+ m_textureProvider->setHorizontalWrapMode(QSGTextureProvider::ClampToEdge);
+ m_textureProvider->setVerticalWrapMode(QSGTextureProvider::ClampToEdge);
+ m_textureProvider->setFiltering(QSGItemPrivate::get(this)->smooth
+ ? QSGTextureProvider::Linear : QSGTextureProvider::Nearest);
+
+ node->setTargetRect(QRectF(0, 0, width(), height()));
+ node->setSourceRect(QRectF(0, 0, 1, 1));
+ node->update();
+
+ return node;
+}
+
+
+class QmlCompositor : public QSGView, public WaylandCompositor
+{
+ Q_OBJECT
+public:
+ QmlCompositor() : WaylandCompositor(this) {
+ setMouseTracking(true);
+ setSource(QUrl(QLatin1String("qml/QmlCompositor/main.qml")));
+ winId();
+ if (platformWindow()) {
+ platformWindow()->glContext();
+ }
+ }
+
+signals:
+ void windowAdded(QVariant window);
+
+private slots:
+ void surfaceMapped(const QRect &rect) {
+ WaylandSurface *surface = qobject_cast<WaylandSurface *>(sender());
+ surface->setGeometry(rect);
+ }
+
+protected:
+ void surfaceCreated(WaylandSurface *surface) {
+ WindowItem *item = new WindowItem(surface, rootObject());
+ connect(surface, SIGNAL(mapped(const QRect &)), this, SLOT(surfaceMapped(const QRect &)));
+ emit windowAdded(QVariant::fromValue(static_cast<QSGItem *>(item)));
+ }
+
+ void paintEvent(QPaintEvent *event) {
+ QSGView::paintEvent(event);
+ frameFinished();
+ glFinish();
+ }
+};
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QmlCompositor compositor;
+ compositor.show();
+
+ compositor.rootContext()->setContextProperty("compositor", &compositor);
+
+ QObject::connect(&compositor, SIGNAL(windowAdded(QVariant)), compositor.rootObject(), SLOT(windowAdded(QVariant)));
+
+ return app.exec();
+
+}
+
+#include "main.moc"
--- /dev/null
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** 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 Nokia Corporation 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.
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: container
+
+ x: -400;
+ y: 0;
+
+ Behavior on x {
+ enabled: true
+ NumberAnimation { easing.type: Easing.InCubic; duration: 1000; }
+ }
+
+ Behavior on y {
+ enabled: true
+ NumberAnimation { easing.type: Easing.InQuad; duration: 1000; }
+ }
+}
--- /dev/null
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** 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 Nokia Corporation 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.
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+
+ width: 800
+ height: 640
+
+ Image {
+ id: background
+ width: parent.width
+ height: parent.height
+ source: "background.jpg"
+ smooth: true
+ }
+
+ function windowAdded(window) {
+ var windowComponent = Qt.createComponent("Window.qml");
+ var windowContainer = windowComponent.createObject(root);
+
+ window.parent = windowContainer;
+
+ windowContainer.x = spawnX;
+ windowContainer.y = spawnY;
+
+ windowContainer.opacity = 1.0;
+
+ spawnX -= 40;
+ spawnY += 40;
+ }
+
+ property int spawnX: width - 400;
+ property int spawnY: 20;
+}