summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@theqtcompany.com>2015-09-10 12:17:45 +0200
committerPaul Olav Tvete <paul.tvete@theqtcompany.com>2015-09-11 11:38:25 +0000
commit2deffa537c82e2f21e01dff5c8f5ba283dd06032 (patch)
tree50a43a5db178a5798b1729aadf601ec416377f9d /examples
parent12a6bd37916802d06ac331fcbcd487ad6b4fafe6 (diff)
New window compositor example
Start rewriting the QWindow-based compositor example to use QOpenGLWindow and QOpenGLTextureBlitter. Also, make a better separation between the compositor logic and the GUI. Not yet feature complete. Change-Id: I3e4fd839c79bc9dbf055c3a0f9939a68392deea9 Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
Diffstat (limited to 'examples')
-rw-r--r--examples/wayland/qwindow-compositor/compositorwindow.cpp132
-rw-r--r--examples/wayland/qwindow-compositor/compositorwindow.h47
-rw-r--r--examples/wayland/qwindow-compositor/main.cpp33
-rw-r--r--examples/wayland/qwindow-compositor/qwindow-compositor.pro13
-rw-r--r--examples/wayland/qwindow-compositor/qwindowcompositor.cpp522
-rw-r--r--examples/wayland/qwindow-compositor/qwindowcompositor.h130
-rw-r--r--examples/wayland/qwindow-compositor/textureblitter.cpp166
-rw-r--r--examples/wayland/qwindow-compositor/windowcompositor.cpp185
-rw-r--r--examples/wayland/qwindow-compositor/windowcompositor.h (renamed from examples/wayland/qwindow-compositor/textureblitter.h)68
9 files changed, 397 insertions, 899 deletions
diff --git a/examples/wayland/qwindow-compositor/compositorwindow.cpp b/examples/wayland/qwindow-compositor/compositorwindow.cpp
index 7d855016f..95ab1c63b 100644
--- a/examples/wayland/qwindow-compositor/compositorwindow.cpp
+++ b/examples/wayland/qwindow-compositor/compositorwindow.cpp
@@ -39,23 +39,127 @@
****************************************************************************/
#include "compositorwindow.h"
-#include <QTouchEvent>
-CompositorWindow::CompositorWindow(const QSurfaceFormat &format, const QRect &geometry)
- : m_format(format)
+#include <QMouseEvent>
+#include <QOpenGLWindow>
+#include <QOpenGLTexture>
+#include <QOpenGLFunctions>
+#include <QMatrix4x4>
+
+#include "windowcompositor.h"
+#include <QtWaylandCompositor/qwaylandinput.h>
+
+void CompositorWindow::initializeGL()
+{
+ QImage backgroundImage = QImage(QLatin1String(":/background.jpg"));
+ m_backgroundTexture = new QOpenGLTexture(backgroundImage, QOpenGLTexture::DontGenerateMipMaps);
+ m_backgroundImageSize = backgroundImage.size();
+ m_textureBlitter.create();
+}
+
+void CompositorWindow::drawBackground()
+{
+ for (int y = 0; y < height(); y += m_backgroundImageSize.height()) {
+ for (int x = 0; x < width(); x += m_backgroundImageSize.width()) {
+ QMatrix4x4 targetTransform = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(x,y), m_backgroundImageSize), QRect(QPoint(0,0), size()));
+ m_textureBlitter.blit(m_backgroundTexture->textureId(),
+ targetTransform,
+ QOpenGLTextureBlitter::OriginTopLeft);
+ }
+ }
+}
+
+void CompositorWindow::paintGL()
+{
+ m_compositor->startRender();
+ QOpenGLFunctions *functions = context()->functions();
+ functions->glClearColor(1.f, .6f, .0f, 0.5f);
+ functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ m_textureBlitter.bind();
+ drawBackground();
+
+ functions->glEnable(GL_BLEND);
+ functions->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ Q_FOREACH (WindowCompositorView *view, m_compositor->views()) {
+ GLuint textureId = view->getTexture();
+ QWaylandSurface *surface = view->surface();
+ if (surface && surface->isMapped()) {
+ QSize s = surface->size();
+ if (!s.isEmpty()) {
+ QRectF surfaceGeometry(view->requestedPosition(), s);
+ //qDebug() << surface << surface->views().first() << view << s;
+ QOpenGLTextureBlitter::Origin surfaceOrigin =
+ view->currentBuffer().origin() == QWaylandSurface::OriginTopLeft
+ ? QOpenGLTextureBlitter::OriginTopLeft
+ : QOpenGLTextureBlitter::OriginBottomLeft;
+ QMatrix4x4 targetTransform = QOpenGLTextureBlitter::targetTransform(surfaceGeometry, QRect(QPoint(), size()));
+ m_textureBlitter.blit(textureId, targetTransform, surfaceOrigin);
+ }
+ }
+ }
+ functions->glDisable(GL_BLEND);
+
+ m_textureBlitter.release();
+ m_compositor->endRender();
+}
+
+void resizeGL(int w, int h)
+{
+}
+
+WindowCompositorView *CompositorWindow::viewAt(const QPointF &point)
+{
+ WindowCompositorView *ret = 0;
+ Q_FOREACH (WindowCompositorView *view, m_compositor->views()) {
+ QPointF topLeft = view->requestedPosition();
+ QWaylandSurface *surface = view->surface();
+ QRectF geo(topLeft, surface->size());
+ if (geo.contains(point))
+ ret = view;
+ }
+ return ret;
+}
+
+void CompositorWindow::mousePressEvent(QMouseEvent *e)
+{
+ if (m_mouseView.isNull()) {
+ m_mouseView = viewAt(e->localPos());
+ QMouseEvent moveEvent(QEvent::MouseMove, e->localPos(), e->globalPos(), Qt::NoButton, Qt::NoButton, e->modifiers());
+ sendMouseEvent(&moveEvent, m_mouseView);
+ }
+ sendMouseEvent(e, m_mouseView);
+}
+
+void CompositorWindow::mouseReleaseEvent(QMouseEvent *e)
+{
+ sendMouseEvent(e, m_mouseView);
+ if (e->buttons() == Qt::NoButton)
+ m_mouseView = 0;
+}
+
+void CompositorWindow::mouseMoveEvent(QMouseEvent *e)
+{
+ sendMouseEvent(e, m_mouseView);
+}
+
+void CompositorWindow::sendMouseEvent(QMouseEvent *e, QWaylandView *target)
+{
+ if (!target)
+ return;
+
+ QPointF mappedPos = e->localPos() - target->requestedPosition();
+ QMouseEvent viewEvent(e->type(), mappedPos, e->localPos(), e->button(), e->buttons(), e->modifiers());
+ m_compositor->handleMouseEvent(target, &viewEvent);
+}
+
+void CompositorWindow::keyPressEvent(QKeyEvent *e)
{
- setSurfaceType(QWindow::OpenGLSurface);
- setGeometry(geometry);
- setFormat(format);
- create();
- m_context = new QOpenGLContext;
- m_context->setFormat(format);
- m_context->create();
+ m_compositor->defaultInputDevice()->sendKeyPressEvent(e->nativeScanCode());
}
-void CompositorWindow::touchEvent(QTouchEvent *event)
+void CompositorWindow::keyReleaseEvent(QKeyEvent *e)
{
- // Do not want any automatically synthesized mouse events
- // so make sure the touch is always accepted.
- event->accept();
+ m_compositor->defaultInputDevice()->sendKeyReleaseEvent(e->nativeScanCode());
}
diff --git a/examples/wayland/qwindow-compositor/compositorwindow.h b/examples/wayland/qwindow-compositor/compositorwindow.h
index 24c50c535..57395d8ab 100644
--- a/examples/wayland/qwindow-compositor/compositorwindow.h
+++ b/examples/wayland/qwindow-compositor/compositorwindow.h
@@ -41,24 +41,47 @@
#ifndef COMPOSITORWINDOW_H
#define COMPOSITORWINDOW_H
-#include <QWindow>
-#include <QOpenGLContext>
-#include <QSurfaceFormat>
+#include <QOpenGLWindow>
+#include <QPointer>
+#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QtWaylandCompositor/QWaylandView>
-class CompositorWindow : public QWindow
+QT_BEGIN_NAMESPACE
+
+class WindowCompositor;
+class WindowCompositorView;
+class QOpenGLTexture;
+
+class CompositorWindow : public QOpenGLWindow
{
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); }
-
+ CompositorWindow() : m_backgroundTexture(0), m_compositor(0) {}
+ void setCompositor(WindowCompositor *comp) {
+ m_compositor = comp;
+ }
protected:
- void touchEvent(QTouchEvent *event);
+ void initializeGL() Q_DECL_OVERRIDE;
+ void paintGL() Q_DECL_OVERRIDE;
+// void resizeGL(int w, int h) Q_DECL_OVERRIDE;
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mouseMoveEvent(QMouseEvent *e);
+
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
private:
- QOpenGLContext *m_context;
- QSurfaceFormat m_format;
+ WindowCompositorView *viewAt(const QPointF &point);
+ void drawBackground();
+ void sendMouseEvent(QMouseEvent *e, QWaylandView *target);
+
+ QOpenGLTextureBlitter m_textureBlitter;
+ QSize m_backgroundImageSize;
+ QOpenGLTexture *m_backgroundTexture;
+ WindowCompositor *m_compositor;
+ QPointer<QWaylandView> m_mouseView;
};
+QT_END_NAMESPACE
+
#endif // COMPOSITORWINDOW_H
diff --git a/examples/wayland/qwindow-compositor/main.cpp b/examples/wayland/qwindow-compositor/main.cpp
index a87d03f45..7f939a034 100644
--- a/examples/wayland/qwindow-compositor/main.cpp
+++ b/examples/wayland/qwindow-compositor/main.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the Qt Compositor.
+** This file is part of the examples of the Qt Wayland module
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
@@ -38,37 +38,20 @@
**
****************************************************************************/
-#include "compositorwindow.h"
-#include "qwindowcompositor.h"
-
#include <QGuiApplication>
-#include <QStringList>
-#include <QScreen>
-#include <QSurfaceFormat>
+#include "compositorwindow.h"
+#include "windowcompositor.h"
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);
- compositor.create();
+ CompositorWindow window;
+ window.resize(1500,800);
+ WindowCompositor comp(&window);
+ window.setCompositor(&comp);
+ comp.create();
window.show();
return app.exec();
diff --git a/examples/wayland/qwindow-compositor/qwindow-compositor.pro b/examples/wayland/qwindow-compositor/qwindow-compositor.pro
index a924cfd6a..994276d99 100644
--- a/examples/wayland/qwindow-compositor/qwindow-compositor.pro
+++ b/examples/wayland/qwindow-compositor/qwindow-compositor.pro
@@ -1,25 +1,18 @@
QT += gui gui-private core-private waylandcompositor waylandcompositor-private
LIBS += -L ../../lib
-#include (../../src/qt-compositor/qt-compositor.pri)
HEADERS += \
compositorwindow.h \
- qwindowcompositor.h \
- textureblitter.h
+ windowcompositor.h
SOURCES += main.cpp \
compositorwindow.cpp \
- qwindowcompositor.cpp \
- textureblitter.cpp
+ windowcompositor.cpp
-# to make QtCompositor/... style includes working without installing
+# to make QtWaylandCompositor/... 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 += waylandcompositor and uncomment
-# the following line
-#include(../../src/compositor/compositor.pri)
RESOURCES += qwindow-compositor.qrc
diff --git a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp b/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
deleted file mode 100644
index c8502ec86..000000000
--- a/examples/wayland/qwindow-compositor/qwindowcompositor.cpp
+++ /dev/null
@@ -1,522 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Compositor.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "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 <QtWaylandCompositor/qwaylandinput.h>
-#include <QtWaylandCompositor/qwaylandbufferref.h>
-#include <QtWaylandCompositor/qwaylandview.h>
-#include <QtWaylandCompositor/qwaylandoutput.h>
-#include <QtWaylandCompositor/qwaylandoutputspace.h>
-
-#include <QtWaylandCompositor/QWaylandShellSurface>
-#include <QtWaylandCompositor/private/qwlextendedsurface_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Surface : public QWaylandSurface
-{
-public:
- Surface(QWaylandCompositor *compositor, QWaylandClient *client, uint id, int version)
- : QWaylandSurface(compositor, client, id, version)
- , shellSurface(Q_NULLPTR)
- , extSurface(Q_NULLPTR)
- , hasSentOnScreen(false)
- { }
-
- QWaylandShellSurface *shellSurface;
- QtWayland::ExtendedSurface *extSurface;
- bool hasSentOnScreen;
-};
-
-class SurfaceView : public QWaylandView
-{
-public:
- SurfaceView()
- : QWaylandView(Q_NULLPTR)
- , m_texture(0)
- {}
-
- ~SurfaceView()
- {
- if (m_texture)
- glDeleteTextures(1, &m_texture);
- }
-
- GLuint updateTextureToCurrentBuffer()
- {
- if (advance()) {
- if (m_texture)
- glDeleteTextures(1, &m_texture);
-
- glGenTextures(1, &m_texture);
- glBindTexture(GL_TEXTURE_2D, m_texture);
- currentBuffer().bindToTexture();
- }
- return m_texture;
- }
-
-private:
- GLuint m_texture;
-};
-
-QWindowCompositor::QWindowCompositor(CompositorWindow *window)
- : QWaylandCompositor()
- , m_window(window)
- , m_backgroundTexture(0)
- , m_textureBlitter(0)
- , m_renderScheduler(this)
- , m_draggingWindow(0)
- , m_dragKeyIsPressed(false)
- , m_cursorHotspotX(0)
- , m_cursorHotspotY(0)
- , m_modifiers(Qt::NoModifier)
- , m_shell(new QWaylandShell(this))
-{
- m_window->makeCurrent();
-
- m_textureBlitter = new TextureBlitter();
- m_backgroundImage = makeBackgroundImage(QLatin1String(":/background.jpg"));
-
- QOpenGLFunctions *functions = m_window->context()->functions();
- functions->glGenFramebuffers(1, &m_surface_fbo);
-
- connect(m_shell, &QWaylandShell::createShellSurface, this, &QWindowCompositor::onCreateShellSurface);
-
- QtWayland::SurfaceExtensionGlobal *extSurfGlob = new QtWayland::SurfaceExtensionGlobal(this);
- connect(extSurfGlob, &QtWayland::SurfaceExtensionGlobal::extendedSurfaceReady, this, &QWindowCompositor::extendedSurfaceCreated);
-
-}
-
-QWindowCompositor::~QWindowCompositor()
-{
- delete m_textureBlitter;
-}
-
-void QWindowCompositor::create()
-{
- QWaylandCompositor::create();
-
- new QWaylandOutput(defaultOutputSpace(), m_window);
-
- m_renderScheduler.setSingleShot(true);
- connect(&m_renderScheduler, &QTimer::timeout, this, &QWindowCompositor::render);
- connect(this, &QWaylandCompositor::createSurface, this, &QWindowCompositor::onCreateSurface);
- connect(this, &QWaylandCompositor::surfaceCreated, this, &QWindowCompositor::onSurfaceCreated);
- connect(defaultInputDevice(), &QWaylandInputDevice::cursorSurfaceRequest, this, &QWindowCompositor::adjustCursorSurface);
-
- m_window->installEventFilter(this);
-
- setRetainedSelectionEnabled(true);
-}
-
-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_visibleSurfaces.isEmpty() ? 0 : m_visibleSurfaces.last());
-}
-
-void QWindowCompositor::surfaceDestroyed()
-{
- QWaylandSurface *surface = static_cast<QWaylandSurface *>(sender());
- ensureKeyboardFocusSurface(surface);
- m_renderScheduler.start(0);
-}
-
-void QWindowCompositor::surfaceMappedChanged()
-{
- QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
- if (surface->isMapped())
- surfaceMapped(surface);
- else
- surfaceUnmapped(surface);
-}
-void QWindowCompositor::surfaceMapped(QWaylandSurface *surface)
-{
- Q_ASSERT(!m_visibleSurfaces.contains(surface));
- QWaylandShellSurface *shellSurface = QWaylandShellSurface::findIn(surface);
- QPoint pos;
- if (!shellSurface || (shellSurface->surfaceType() != QWaylandShellSurface::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);
- QWaylandView *view = surface->views().first();
- view->setRequestedPosition(pos);
- }
- if (shellSurface && shellSurface->surfaceType() == QWaylandShellSurface::Popup) {
- QWaylandView *view = shellSurface->view();
- view->setRequestedPosition(shellSurface->transientParent()->views().first()->requestedPosition() + shellSurface->transientOffset());
- }
-
- m_visibleSurfaces.append(surface);
-
- if (!surface->isCursorSurface())
- defaultInputDevice()->setKeyboardFocus(surface);
-
- m_renderScheduler.start(0);
-}
-
-void QWindowCompositor::surfaceUnmapped(QWaylandSurface *surface)
-{
- m_visibleSurfaces.removeOne(surface);
-
- ensureKeyboardFocusSurface(surface);
- m_renderScheduler.start(0);
-}
-
-void QWindowCompositor::surfaceCommittedSlot()
-{
- 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::onCreateSurface(QWaylandClient *client, uint id, int version)
-{
- new Surface(this, client, id, version);
-}
-
-void QWindowCompositor::onSurfaceCreated(QWaylandSurface *surface)
-{
- connect(surface, &QWaylandSurface::surfaceDestroyed, this, &QWindowCompositor::surfaceDestroyed);
- connect(surface, &QWaylandSurface::mappedChanged, this, &QWindowCompositor::surfaceMappedChanged);
- connect(surface, &QWaylandSurface::redraw, this, &QWindowCompositor::surfaceCommittedSlot);
-}
-
-void QWindowCompositor::onCreateShellSurface(QWaylandSurface *s, QWaylandClient *client, uint id)
-{
- Surface *surface = static_cast<Surface *>(s);
- SurfaceView *newView = new SurfaceView();
- newView->setSurface(surface);
- newView->setOutput(output(m_window));
- QWaylandShellSurface *shellSurface = new QWaylandShellSurface(m_shell, surface, newView, client, id);
- surface->shellSurface = shellSurface;
- m_renderScheduler.start(0);
-}
-
-void QWindowCompositor::extendedSurfaceCreated(QtWayland::ExtendedSurface *extendedSurface, QWaylandSurface *surface)
-{
- Surface *s = static_cast<Surface *>(surface);
- Q_ASSERT(!s->extSurface);
- s->extSurface = extendedSurface;
-}
-
-void QWindowCompositor::updateCursor(bool hasBuffer)
-{
- Q_UNUSED(hasBuffer)
- if (!m_cursorView.surface())
- return;
-
- m_cursorView.advance();
-
- QImage image = m_cursorView.currentBuffer().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(QWaylandView *view, const QPointF &pos) const
-{
- return pos - view->requestedPosition();
-}
-
-void QWindowCompositor::adjustCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY)
-{
- if ((m_cursorView.surface() != surface)) {
- if (m_cursorView.surface())
- disconnect(m_cursorView.surface(), &QWaylandSurface::configure, this, &QWindowCompositor::updateCursor);
- if (surface)
- connect(surface, &QWaylandSurface::configure, this, &QWindowCompositor::updateCursor);
- }
-
- m_cursorView.setSurface(surface);
- m_cursorHotspotX = hotspotX;
- m_cursorHotspotY = hotspotY;
-}
-
-QWaylandView *QWindowCompositor::viewAt(const QPointF &point, QPointF *local)
-{
- for (int i = m_visibleSurfaces.size() - 1; i >= 0; --i) {
- QWaylandSurface *surface = m_visibleSurfaces.at(i);
- foreach (QWaylandView *view, surface->views()) {
- QRectF geo(view->requestedPosition(), surface->size());
- if (geo.contains(point)) {
- if (local)
- *local = toView(view, point);
- return view;
- }
- }
- }
- return 0;
-}
-
-void QWindowCompositor::render()
-{
- m_window->makeCurrent();
- defaultOutput()->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()),
- m_window->size(),
- 0, false, true);
-
- foreach (QWaylandSurface *surface, m_visibleSurfaces) {
- if (!surface->isMapped())
- continue;
- drawSubSurface(QPoint(), surface);
- }
-
- m_textureBlitter->release();
- defaultOutput()->sendFrameCallbacks();
-
- // 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 *s)
-{
- Surface *surface = static_cast<Surface *>(s);
- SurfaceView *view = Q_NULLPTR;
- if (surface->shellSurface && surface->shellSurface->view())
- view = static_cast<SurfaceView *>(surface->shellSurface->view());
- else if (surface->views().size())
- view = static_cast<SurfaceView *>(surface->views().first());
-
- if (!view)
- return;
-
- GLuint texture = view->updateTextureToCurrentBuffer();
- bool invert_y = view->currentBuffer().origin() == QWaylandSurface::OriginTopLeft;
- QPoint pos = view->requestedPosition().toPoint() + offset;
- QRect geo(pos, surface->size());
- bool onscreen = (QRect(QPoint(0, 0), m_window->size()).contains(pos));
- if (surface->extSurface && onscreen != surface->hasSentOnScreen) {
- surface->extSurface->sendOnScreenVisibilityChange(onscreen);
- surface->hasSentOnScreen = onscreen;
- }
-
- if (surface->isMapped() && onscreen) {
- m_textureBlitter->drawTexture(texture, geo, m_window->size(), 0, false, invert_y);
- }
-}
-
-bool QWindowCompositor::eventFilter(QObject *obj, QEvent *event)
-{
- if (obj != m_window)
- return false;
-
- QWaylandInputDevice *input = defaultInputDevice();
-
- switch (event->type()) {
- case QEvent::FocusOut:
- m_dragKeyIsPressed = false;
- 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);
- QWaylandView *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_visibleSurfaces.removeOne(target->surface());
- m_visibleSurfaces.append(target->surface());
- m_renderScheduler.start(0);
- }
- input->sendMousePressEvent(me->button());
- }
- return true;
- }
- case QEvent::MouseButtonRelease: {
- QWaylandView *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());
- }
- return true;
- }
- case QEvent::MouseMove: {
- QMouseEvent *me = static_cast<QMouseEvent *>(event);
- if (m_draggingWindow) {
- m_draggingWindow->setRequestedPosition(me->localPos() - m_drag_diff);
- m_renderScheduler.start(0);
- } else {
- QPointF local;
- QWaylandView *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:
- {
- QWaylandView *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->sendMouseMoveEvent(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
deleted file mode 100644
index 30ee33238..000000000
--- a/examples/wayland/qwindow-compositor/qwindowcompositor.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Compositor.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QWINDOWCOMPOSITOR_H
-#define QWINDOWCOMPOSITOR_H
-
-#include <QtWaylandCompositor/QWaylandCompositor>
-#include <QtWaylandCompositor/QWaylandSurface>
-#include <QtWaylandCompositor/QWaylandView>
-#include "textureblitter.h"
-#include "compositorwindow.h"
-
-#include <QtGui/private/qopengltexturecache_p.h>
-#include <QObject>
-#include <QTimer>
-
-QT_BEGIN_NAMESPACE
-
-namespace QtWayland {
- class ExtendedSurface;
-}
-
-class QWaylandView;
-class QWaylandShell;
-class QOpenGLTexture;
-
-class QWindowCompositor : public QWaylandCompositor
-{
- Q_OBJECT
-public:
- QWindowCompositor(CompositorWindow *window);
- ~QWindowCompositor();
-
- void create() Q_DECL_OVERRIDE;
-private slots:
- void surfaceMappedChanged();
- void surfaceDestroyed();
- void surfaceCommittedSlot();
- void surfacePosChanged();
-
- void render();
- void onCreateSurface(QWaylandClient *client, uint id, int version);
- void onSurfaceCreated(QWaylandSurface *surface);
- void onCreateShellSurface(QWaylandSurface *s, QWaylandClient *client, uint id);
-
-protected:
- QWaylandSurface *createDefaultSurfaceType() Q_DECL_OVERRIDE;
- void surfaceCommitted(QWaylandSurface *surface);
-
- QWaylandView* viewAt(const QPointF &point, QPointF *local = 0);
-
- bool eventFilter(QObject *obj, QEvent *event);
- QPointF toView(QWaylandView *view, const QPointF &pos) const;
-
- void adjustCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY);
-
- void ensureKeyboardFocusSurface(QWaylandSurface *oldSurface);
- QImage makeBackgroundImage(const QString &fileName);
-
-private slots:
- void extendedSurfaceCreated(QtWayland::ExtendedSurface *extSurface, QWaylandSurface *surface);
- void updateCursor(bool hasBuffer);
-
-private:
- void surfaceMapped(QWaylandSurface *surface);
- void surfaceUnmapped(QWaylandSurface *surface);
- void drawSubSurface(const QPoint &offset, QWaylandSurface *surface);
-
- CompositorWindow *m_window;
- QImage m_backgroundImage;
- QOpenGLTexture *m_backgroundTexture;
- QList<QWaylandSurface *> m_visibleSurfaces;
- TextureBlitter *m_textureBlitter;
- GLuint m_surface_fbo;
- QTimer m_renderScheduler;
-
- //Dragging windows around
- QWaylandView *m_draggingWindow;
- bool m_dragKeyIsPressed;
- QPointF m_drag_diff;
-
- //Cursor
- QWaylandView m_cursorView;
- int m_cursorHotspotX;
- int m_cursorHotspotY;
-
- Qt::KeyboardModifiers m_modifiers;
- QWaylandShell *m_shell;
-};
-
-QT_END_NAMESPACE
-
-#endif // QWINDOWCOMPOSITOR_H
diff --git a/examples/wayland/qwindow-compositor/textureblitter.cpp b/examples/wayland/qwindow-compositor/textureblitter.cpp
deleted file mode 100644
index a9acfc026..000000000
--- a/examples/wayland/qwindow-compositor/textureblitter.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the Qt Compositor.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "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/windowcompositor.cpp b/examples/wayland/qwindow-compositor/windowcompositor.cpp
new file mode 100644
index 000000000..ac637e623
--- /dev/null
+++ b/examples/wayland/qwindow-compositor/windowcompositor.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** 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 The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "windowcompositor.h"
+
+#include <QMouseEvent>
+#include <QKeyEvent>
+#include <QTouchEvent>
+
+#include <QtWaylandCompositor/QWaylandOutputSpace>
+#include <QtWaylandCompositor/QWaylandShellSurface>
+#include <QtWaylandCompositor/qwaylandinput.h>
+
+#include <QDebug>
+
+GLuint WindowCompositorView::getTexture() {
+ if (advance()) {
+ if (m_texture)
+ glDeleteTextures(1, &m_texture);
+
+ glGenTextures(1, &m_texture);
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ currentBuffer().bindToTexture();
+ }
+ return m_texture;
+}
+
+WindowCompositor::WindowCompositor(QWindow *window)
+ : QWaylandCompositor()
+ , m_window(window)
+ , m_shell(new QWaylandShell(this))
+{
+ connect(m_shell, &QWaylandShell::createShellSurface, this, &WindowCompositor::onCreateShellSurface);
+}
+
+WindowCompositor::~WindowCompositor()
+{
+}
+
+void WindowCompositor::create()
+{
+ QWaylandCompositor::create();
+ new QWaylandOutput(defaultOutputSpace(), m_window);
+
+ connect(this, &QWaylandCompositor::surfaceCreated, this, &WindowCompositor::onSurfaceCreated);
+ connect(defaultInputDevice(), &QWaylandInputDevice::cursorSurfaceRequest, this, &WindowCompositor::adjustCursorSurface);
+}
+
+void WindowCompositor::onSurfaceCreated(QWaylandSurface *surface)
+{
+ qDebug() << "onSurfaceCreated" << surface;
+
+ connect(surface, &QWaylandSurface::surfaceDestroyed, this, &WindowCompositor::surfaceDestroyed);
+ connect(surface, &QWaylandSurface::mappedChanged, this, &WindowCompositor::surfaceMappedChanged);
+ connect(surface, &QWaylandSurface::redraw, this, &WindowCompositor::triggerRender);
+}
+
+void WindowCompositor::surfaceMappedChanged()
+{
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+ qDebug() << "surfaceMappedChanged()" << surface << surface->isMapped();
+ if (surface->isMapped()) {\
+ if (!surface->isCursorSurface())
+ defaultInputDevice()->setKeyboardFocus(surface);
+ }
+ triggerRender();
+}
+
+void WindowCompositor::surfaceDestroyed()
+{
+ // QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+ qDebug() << "surfaceDestroyed()";
+ // Q_FOREACH (QWaylandView *view, surface->views()) {
+ // int n = m_views.removeAll(static_cast<WindowCompositorView*>(view));
+ // qDebug() << n << view;
+ // }
+ triggerRender();
+}
+
+void WindowCompositor::viewSurfaceDestroyed()
+{
+ WindowCompositorView *view = qobject_cast<WindowCompositorView*>(sender());
+ int n = m_views.removeAll(view);
+ qDebug() << n << view;
+ delete view;
+}
+
+void WindowCompositor::surfaceCommittedSlot()
+{
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(sender());
+
+// qDebug() << "surfaceCommittedSlot()" << surface;
+ triggerRender();
+}
+
+void WindowCompositor::onCreateShellSurface(QWaylandSurface *s, QWaylandClient *client, uint id)
+{
+ qDebug() << "onCreateShellSurface" << s << client << id;
+ QWaylandSurface *surface = s;
+
+ WindowCompositorView *view = new WindowCompositorView;
+ view->setSurface(surface);
+ view->setOutput(output(m_window));
+ m_views << view;
+ connect(view, &QWaylandView::surfaceDestroyed, this, &WindowCompositor::viewSurfaceDestroyed);
+ connect(view, &QWaylandView::requestedPositionChanged, this, &WindowCompositor::triggerRender);
+
+ QWaylandShellSurface *shellSurface = new QWaylandShellSurface(m_shell, surface, view, client, id);
+}
+
+void WindowCompositor::triggerRender()
+{
+ m_window->requestUpdate();
+}
+
+void WindowCompositor::startRender()
+{
+ defaultOutput()->frameStarted();
+ cleanupGraphicsResources();
+}
+
+void WindowCompositor::endRender()
+{
+ defaultOutput()->sendFrameCallbacks();
+}
+
+void WindowCompositor::adjustCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY)
+{
+ //qDebug() << "adjustCursorSurface" << surface << hotspotY << hotspotY;
+}
+
+void WindowCompositor::handleMouseEvent(QWaylandView *target, QMouseEvent *me)
+{
+ QWaylandInputDevice *input = defaultInputDevice();
+ switch (me->type()) {
+ case QEvent::MouseButtonPress:
+ input->sendMousePressEvent(me->button());
+ break;
+ case QEvent::MouseButtonRelease:
+ input->sendMouseReleaseEvent(me->button());
+ break;
+ case QEvent::MouseMove:
+ input->sendMouseMoveEvent(target, me->localPos(), me->globalPos());
+ default:
+ break;
+ }
+}
diff --git a/examples/wayland/qwindow-compositor/textureblitter.h b/examples/wayland/qwindow-compositor/windowcompositor.h
index b46d354e0..31ddf7374 100644
--- a/examples/wayland/qwindow-compositor/textureblitter.h
+++ b/examples/wayland/qwindow-compositor/windowcompositor.h
@@ -3,7 +3,7 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the Qt Compositor.
+** This file is part of the examples of the Qt Wayland module
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
@@ -38,34 +38,62 @@
**
****************************************************************************/
-#ifndef TEXTUREBLITTER_H
-#define TEXTUREBLITTER_H
+#ifndef WINDOWCOMPOSITOR_H
+#define WINDOWCOMPOSITOR_H
-#include <QtGui/QMatrix4x4>
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/QWaylandSurface>
+#include <QtWaylandCompositor/QWaylandView>
+#include <QTimer>
QT_BEGIN_NAMESPACE
-class QOpenGLShaderProgram;
-class TextureBlitter
+class QWaylandShell;
+
+class WindowCompositorView : public QWaylandView
{
+ Q_OBJECT
public:
- TextureBlitter();
- ~TextureBlitter();
- void bind();
- void release();
- void drawTexture(int textureId, const QRectF &sourceGeometry,
- const QSize &targetRect, int depth,
- bool targethasInvertedY, bool sourceHasInvertedY);
-
+ WindowCompositorView() : m_texture(0) {}
+ GLuint getTexture();
private:
- QOpenGLShaderProgram *m_shaderProgram;
- QMatrix4x4 m_transformMatrix;
+ GLuint m_texture;
+};
+
+class WindowCompositor : public QWaylandCompositor
+{
+ Q_OBJECT
+public:
+ WindowCompositor(QWindow *window);
+ ~WindowCompositor();
+ void create() Q_DECL_OVERRIDE;
+
+ void startRender();
+ void endRender();
- int m_matrixLocation;
- int m_vertexCoordEntry;
- int m_textureCoordEntry;
+ QList<WindowCompositorView*> views() const { return m_views; }
+
+ void handleMouseEvent(QWaylandView *target, QMouseEvent *me);
+protected:
+ void adjustCursorSurface(QWaylandSurface *surface, int hotspotX, int hotspotY);
+
+private slots:
+ void surfaceMappedChanged();
+ void surfaceDestroyed();
+ void surfaceCommittedSlot();
+ void viewSurfaceDestroyed();
+
+ void triggerRender();
+
+ void onSurfaceCreated(QWaylandSurface *surface);
+ void onCreateShellSurface(QWaylandSurface *s, QWaylandClient *client, uint id);
+private:
+ QWindow *m_window;
+ QList<WindowCompositorView*> m_views;
+ QWaylandShell *m_shell;
};
+
QT_END_NAMESPACE
-#endif // TEXTUREBLITTER_H
+#endif // WINDOWCOMPOSITOR_H