diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2012-01-04 08:33:28 +0100 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2012-01-04 10:34:40 +0100 |
commit | d5ea033df8cf0a2dec49fce639d84e7dd0a2fced (patch) | |
tree | 15d92a4990b612e73450d110a6cc820df8cdee2e /src/plugins/platforms/wayland | |
parent | 62bba49c83849ca5904357de45c888f9fab3106a (diff) |
Implement subsurfaces extension
This allows you to have subwindows in the compositor.
We tried to experiment with composing subsurfaces client side, but the
architecture did not feel very lean. This however, requires the
compositor to compose each surface before drawing the surface. The
example compositors render the subsurfaces into the wl_surfaces texture.
This might not be a good idea.
Change-Id: I6e186b62d7b490de7f4e6c6f22fcf6c1e0a70df3
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'src/plugins/platforms/wayland')
9 files changed, 186 insertions, 9 deletions
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 0d6287722..3f160b794 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -59,6 +59,7 @@ #include "qwaylandextendedoutput.h" #include "qwaylandextendedsurface.h" +#include "qwaylandsubsurface.h" #include <QtCore/QAbstractEventDispatcher> #include <QtGui/private/qguiapplication_p.h> @@ -306,6 +307,8 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id, mOutputExtension = new QWaylandOutputExtension(this,id); } else if (interface == "wl_surface_extension") { mWindowExtension = new QWaylandSurfaceExtension(this,id); + } else if (interface == "wl_sub_surface_extension") { + mSubSurfaceExtension = new QWaylandSubSurfaceExtension(this,id); } } diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h index cce0486c9..416379921 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -60,6 +60,7 @@ class QWaylandWindowManagerIntegration; class QWaylandDataDeviceManager; class QWaylandShell; class QWaylandSurfaceExtension; +class QWaylandSubSurfaceExtension; class QWaylandOutputExtension; class QWaylandDisplay : public QObject { @@ -97,6 +98,7 @@ public: QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler; } QWaylandSurfaceExtension *windowExtension() const { return mWindowExtension; } + QWaylandSubSurfaceExtension *subSurfaceExtension() const { return mSubSurfaceExtension; } QWaylandOutputExtension *outputExtension() const { return mOutputExtension; } struct wl_shm *shm() const { return mShm; } @@ -125,6 +127,7 @@ private: QWaylandInputDevice *mLastKeyboardFocusInputDevice; QWaylandDataDeviceManager *mDndSelectionHandler; QWaylandSurfaceExtension *mWindowExtension; + QWaylandSubSurfaceExtension *mSubSurfaceExtension; QWaylandOutputExtension *mOutputExtension; QSocketNotifier *mReadNotifier; diff --git a/src/plugins/platforms/wayland/qwaylandextendedsurface.h b/src/plugins/platforms/wayland/qwaylandextendedsurface.h index 10d17b9bf..c17df8492 100644 --- a/src/plugins/platforms/wayland/qwaylandextendedsurface.h +++ b/src/plugins/platforms/wayland/qwaylandextendedsurface.h @@ -70,6 +70,7 @@ public: QVariantMap properties() const; QVariant property(const QString &name); QVariant property(const QString &name, const QVariant &defaultValue); + private: QWaylandWindow *m_window; struct wl_extended_surface *m_extended_surface; diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp index 42e0416e0..da9031b5d 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -130,7 +130,6 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion ®ion, cons void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &) { QWaylandShmWindow *waylandWindow = static_cast<QWaylandShmWindow *>(window()->handle()); - Q_ASSERT(waylandWindow->windowType() == QWaylandWindow::Shm); QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format(); diff --git a/src/plugins/platforms/wayland/qwaylandsubsurface.cpp b/src/plugins/platforms/wayland/qwaylandsubsurface.cpp new file mode 100644 index 000000000..13d8c99b6 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandsubsurface.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandsubsurface.h" + +#include "qwaylandwindow.h" + +#include "wayland-sub-surface-extension-client-protocol.h" + +QWaylandSubSurfaceExtension::QWaylandSubSurfaceExtension(QWaylandDisplay *display, uint32_t id) +{ + m_sub_surface_extension = static_cast<struct wl_sub_surface_extension *>( + wl_display_bind(display->wl_display(),id, &wl_sub_surface_extension_interface)); +} + +QWaylandSubSurface *QWaylandSubSurfaceExtension::getSubSurfaceAwareWindow(QWaylandWindow *window) +{ + struct wl_surface *surface = window->wl_surface(); + Q_ASSERT(surface); + struct wl_sub_surface *sub_surface = + wl_sub_surface_extension_get_sub_surface_aware_surface(m_sub_surface_extension,surface); + + return new QWaylandSubSurface(window,sub_surface); + +} + +QWaylandSubSurface::QWaylandSubSurface(QWaylandWindow *window, struct wl_sub_surface *sub_surface) + : m_window(window) + , m_sub_surface(sub_surface) +{ +} + +void QWaylandSubSurface::setParent(const QWaylandWindow *parent) +{ + QWaylandSubSurface *parentSurface = parent? parent->subSurfaceWindow():0; + if (parentSurface) { + int x = m_window->geometry().x(); + int y = m_window->geometry().y(); + wl_sub_surface_attach_sub_surface(parentSurface->m_sub_surface,m_sub_surface,x,y); + } +} diff --git a/src/plugins/platforms/wayland/qwaylandsubsurface.h b/src/plugins/platforms/wayland/qwaylandsubsurface.h new file mode 100644 index 000000000..5c8b2b254 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandsubsurface.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDSUBSURFACE_H +#define QWAYLANDSUBSURFACE_H + +class QWaylandDisplay; +class QWaylandWindow; +class QWaylandSubSurface; + +#include <wayland-client.h> + +class QWaylandSubSurfaceExtension +{ +public: + QWaylandSubSurfaceExtension(QWaylandDisplay *display, uint32_t id); + + QWaylandSubSurface *getSubSurfaceAwareWindow(QWaylandWindow *window); +private: + struct wl_sub_surface_extension *m_sub_surface_extension; +}; + +class QWaylandSubSurface +{ +public: + QWaylandSubSurface(QWaylandWindow *window, struct wl_sub_surface *sub_surface); + + void setParent(const QWaylandWindow *parent); + +private: + QWaylandWindow *m_window; + struct wl_sub_surface *m_sub_surface; +}; + +#endif // QWAYLANDSUBSURFACE_H diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 73ed85096..9e45831b2 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -55,18 +55,18 @@ #endif #include "qwaylandextendedsurface.h" +#include "qwaylandsubsurface.h" #include <QCoreApplication> #include <QtGui/QWindowSystemInterface> -#include <QDebug> - QWaylandWindow::QWaylandWindow(QWindow *window) : QPlatformWindow(window) , mDisplay(QWaylandScreen::waylandScreenFromWindow(window)->display()) , mSurface(mDisplay->createSurface(this)) , mShellSurface(mDisplay->shell()->createShellSurface(this)) , mExtendedWindow(0) + , mSubSurfaceWindow(0) , mBuffer(0) , mWaitingForFrameSync(false) , mFrameCallback(0) @@ -76,14 +76,19 @@ QWaylandWindow::QWaylandWindow(QWindow *window) if (mDisplay->windowExtension()) mExtendedWindow = mDisplay->windowExtension()->getExtendedWindow(this); + if (mDisplay->subSurfaceExtension()) + mSubSurfaceWindow = mDisplay->subSurfaceExtension()->getSubSurfaceAwareWindow(this); #ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT mDisplay->windowManagerIntegration()->mapClientToProcess(qApp->applicationPid()); mDisplay->windowManagerIntegration()->authenticateWithToken(); #endif - //all surfaces are toplevel surfaces for now - wl_shell_surface_set_toplevel(mShellSurface->handle()); + if (parent() && mSubSurfaceWindow) { + mSubSurfaceWindow->setParent(static_cast<const QWaylandWindow *>(parent())); + } else { + wl_shell_surface_set_toplevel(mShellSurface->handle()); + } } QWaylandWindow::~QWaylandWindow() @@ -106,8 +111,10 @@ WId QWaylandWindow::winId() const void QWaylandWindow::setParent(const QPlatformWindow *parent) { - Q_UNUSED(parent); - qWarning("Sub window is not supported"); + const QWaylandWindow *parentWaylandWindow = static_cast<const QWaylandWindow *>(parent); + if (subSurfaceWindow()) { + subSurfaceWindow()->setParent(parentWaylandWindow); + } } void QWaylandWindow::setVisible(bool visible) @@ -192,3 +199,8 @@ QWaylandExtendedSurface *QWaylandWindow::extendedWindow() const { return mExtendedWindow; } + +QWaylandSubSurface *QWaylandWindow::subSurfaceWindow() const +{ + return mSubSurfaceWindow; +} diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h index fb4ac7484..282454baf 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.h +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -51,6 +51,8 @@ class QWaylandDisplay; class QWaylandBuffer; class QWaylandShellSurface; class QWaylandExtendedSurface; +class QWaylandSubSurface; + struct wl_egl_window; class QWaylandWindow : public QPlatformWindow @@ -81,12 +83,14 @@ public: QWaylandShellSurface *shellSurface() const; QWaylandExtendedSurface *extendedWindow() const; + QWaylandSubSurface *subSurfaceWindow() const; protected: QWaylandDisplay *mDisplay; struct wl_surface *mSurface; QWaylandShellSurface *mShellSurface; QWaylandExtendedSurface *mExtendedWindow; + QWaylandSubSurface *mSubSurfaceWindow; QWaylandBuffer *mBuffer; WId mWindowId; diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro index aeef60839..51ad95a9f 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -17,6 +17,7 @@ QT += core-private gui-private platformsupport-private WAYLANDSOURCES += \ $$PWD/../../../../extensions/surface-extension.xml \ + $$PWD/../../../../extensions/sub-surface-extension.xml \ $$PWD/../../../../extensions/output-extension.xml SOURCES = main.cpp \ @@ -37,7 +38,8 @@ SOURCES = main.cpp \ qwaylandshell.cpp \ qwaylandshellsurface.cpp \ qwaylandextendedoutput.cpp \ - qwaylandextendedsurface.cpp + qwaylandextendedsurface.cpp \ + qwaylandsubsurface.cpp HEADERS = qwaylandintegration.h \ qwaylandnativeinterface.h \ @@ -56,7 +58,8 @@ HEADERS = qwaylandintegration.h \ qwaylandshell.h \ qwaylandshellsurface.h \ qwaylandextendedoutput.h \ - qwaylandextendedsurface.h + qwaylandextendedsurface.h \ + qwaylandsubsurface.h INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND LIBS += $$QMAKE_LIBS_WAYLAND |