summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2012-01-04 08:33:28 +0100
committerJørgen Lind <jorgen.lind@nokia.com>2012-01-04 10:34:40 +0100
commitd5ea033df8cf0a2dec49fce639d84e7dd0a2fced (patch)
tree15d92a4990b612e73450d110a6cc820df8cdee2e /src
parent62bba49c83849ca5904357de45c888f9fab3106a (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')
-rw-r--r--src/compositor/compositor_api/waylandcompositor.cpp5
-rw-r--r--src/compositor/compositor_api/waylandcompositor.h2
-rw-r--r--src/compositor/compositor_api/waylandsurface.cpp78
-rw-r--r--src/compositor/compositor_api/waylandsurface.h21
-rw-r--r--src/compositor/compositor_api/waylandsurfaceitem.cpp67
-rw-r--r--src/compositor/compositor_api/waylandsurfaceitem.h3
-rw-r--r--src/compositor/wayland_wrapper/wayland_wrapper.pri7
-rw-r--r--src/compositor/wayland_wrapper/wlcompositor.cpp9
-rw-r--r--src/compositor/wayland_wrapper/wlcompositor.h3
-rw-r--r--src/compositor/wayland_wrapper/wlextendedsurface.cpp6
-rw-r--r--src/compositor/wayland_wrapper/wlextendedsurface.h24
-rw-r--r--src/compositor/wayland_wrapper/wlsubsurface.cpp168
-rw-r--r--src/compositor/wayland_wrapper/wlsubsurface.h129
-rw-r--r--src/compositor/wayland_wrapper/wlsurface.cpp56
-rw-r--r--src/compositor/wayland_wrapper/wlsurface.h7
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp3
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h3
-rw-r--r--src/plugins/platforms/wayland/qwaylandextendedsurface.h1
-rw-r--r--src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp1
-rw-r--r--src/plugins/platforms/wayland/qwaylandsubsurface.cpp79
-rw-r--r--src/plugins/platforms/wayland/qwaylandsubsurface.h73
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp24
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.h4
-rw-r--r--src/plugins/platforms/wayland/wayland.pro7
24 files changed, 751 insertions, 29 deletions
diff --git a/src/compositor/compositor_api/waylandcompositor.cpp b/src/compositor/compositor_api/waylandcompositor.cpp
index 3f84f7c84..73ddf236f 100644
--- a/src/compositor/compositor_api/waylandcompositor.cpp
+++ b/src/compositor/compositor_api/waylandcompositor.cpp
@@ -186,3 +186,8 @@ void WaylandCompositor::changeCursor(const QImage &image, int hotspotX, int hots
Q_UNUSED(hotspotY);
qDebug() << "changeCursor" << image.size() << hotspotX << hotspotY;
}
+
+void WaylandCompositor::enableSubSurfaceExtension()
+{
+ m_compositor->enableSubSurfaceExtension();
+}
diff --git a/src/compositor/compositor_api/waylandcompositor.h b/src/compositor/compositor_api/waylandcompositor.h
index a38c3df47..b38458577 100644
--- a/src/compositor/compositor_api/waylandcompositor.h
+++ b/src/compositor/compositor_api/waylandcompositor.h
@@ -91,6 +91,8 @@ public:
virtual void changeCursor(const QImage &image, int hotspotX, int hotspotY);
+ void enableSubSurfaceExtension();
+
private:
static void retainedSelectionChanged(QMimeData *mimeData, void *param);
diff --git a/src/compositor/compositor_api/waylandsurface.cpp b/src/compositor/compositor_api/waylandsurface.cpp
index 003a6d451..60d2684ea 100644
--- a/src/compositor/compositor_api/waylandsurface.cpp
+++ b/src/compositor/compositor_api/waylandsurface.cpp
@@ -3,16 +3,35 @@
#include <private/qobject_p.h>
#include "wayland_wrapper/wlsurface.h"
+#include "wayland_wrapper/wlextendedsurface.h"
+#include "wayland_wrapper/wlsubsurface.h"
+
+#ifdef QT_COMPOSITOR_QUICK
+#include "waylandsurfaceitem.h"
+#endif
class WaylandSurfacePrivate : public QObjectPrivate
{
public:
WaylandSurfacePrivate(Wayland::Surface *srfc)
: surface(srfc)
+#ifdef QT_COMPOSITOR_QUICK
+ , surface_item(0)
+#endif
{}
+ ~WaylandSurfacePrivate()
+ {
+#ifdef QT_COMPOSITOR_QUICK
+ if (surface_item)
+ surface_item->setSurface(0);
+#endif
+ }
+
Wayland::Surface *surface;
- QRect geometry;
+#ifdef QT_COMPOSITOR_QUICK
+ WaylandSurfaceItem *surface_item;
+#endif
};
WaylandSurface::WaylandSurface(Wayland::Surface *surface)
@@ -21,6 +40,24 @@ WaylandSurface::WaylandSurface(Wayland::Surface *surface)
}
+WaylandSurface *WaylandSurface::parentSurface() const
+{
+ Q_D(const WaylandSurface);
+ if (d->surface->subSurface()) {
+ return d->surface->subSurface()->parent()->waylandSurface();
+ }
+ return 0;
+}
+
+QLinkedList<WaylandSurface *> WaylandSurface::subSurfaces() const
+{
+ Q_D(const WaylandSurface);
+ if (d->surface->subSurface()) {
+ return d->surface->subSurface()->subSurfaces();
+ }
+ return QLinkedList<WaylandSurface *>();
+}
+
WaylandSurface::Type WaylandSurface::type() const
{
Q_D(const WaylandSurface);
@@ -42,13 +79,13 @@ bool WaylandSurface::visible() const
QRect WaylandSurface::geometry() const
{
Q_D(const WaylandSurface);
- return d->geometry;
+ return d->surface->geometry();
}
void WaylandSurface::setGeometry(const QRect &geometry)
{
Q_D(WaylandSurface);
- d->geometry = geometry;
+ d->surface->setGeometry(geometry);
}
QImage WaylandSurface::image() const
@@ -76,6 +113,20 @@ Wayland::Surface * WaylandSurface::handle() const
return d->surface;
}
+#ifdef QT_COMPOSITOR_QUICK
+WaylandSurfaceItem *WaylandSurface::surfaceItem() const
+{
+ Q_D(const WaylandSurface);
+ return d->surface_item;
+}
+
+void WaylandSurface::setSurfaceItem(WaylandSurfaceItem *surfaceItem)
+{
+ Q_D(WaylandSurface);
+ d->surface_item = surfaceItem;
+}
+#endif //QT_COMPOSITOR_QUICK
+
qint64 WaylandSurface::processId() const
{
Q_D(const WaylandSurface);
@@ -100,6 +151,27 @@ void WaylandSurface::setWindowProperty(const QString &name, const QVariant &valu
d->surface->setWindowProperty(name, value);
}
+QPoint WaylandSurface::mapToParent(const QPoint &pos) const
+{
+ return pos + geometry().topLeft();
+}
+
+QPoint WaylandSurface::mapTo(WaylandSurface *parent, const QPoint &pos) const
+{
+ QPoint p = pos;
+ if (parent) {
+ const WaylandSurface * surface = this;
+ while (surface != parent) {
+ Q_ASSERT_X(surface, "WaylandSurface::mapTo(WaylandSurface *parent, const QPoint &pos)",
+ "parent must be in parent hierarchy");
+ p = surface->mapToParent(p);
+ surface = surface->parentSurface();
+ }
+ }
+ return p;
+
+}
+
void WaylandSurface::sendMousePressEvent(const QPoint &pos, Qt::MouseButton button)
{
Q_D(WaylandSurface);
diff --git a/src/compositor/compositor_api/waylandsurface.h b/src/compositor/compositor_api/waylandsurface.h
index 45c308a6b..89befeafc 100644
--- a/src/compositor/compositor_api/waylandsurface.h
+++ b/src/compositor/compositor_api/waylandsurface.h
@@ -54,15 +54,21 @@
class WaylandSurfacePrivate;
+#ifdef QT_COMPOSITOR_QUICK
+class WaylandSurfaceItem;
+#endif
+
namespace Wayland {
class Surface;
class SurfacePrivate;
+class ExtendedSurface;
}
class Q_COMPOSITOR_EXPORT WaylandSurface : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(WaylandSurface)
+ Q_PROPERTY(QRect geometry READ geometry WRITE setGeometry NOTIFY geometryChanged)
public:
enum Type {
Invalid,
@@ -73,6 +79,9 @@ public:
WaylandSurface(Wayland::Surface *surface);
+ WaylandSurface *parentSurface() const;
+ QLinkedList<WaylandSurface *> subSurfaces() const;
+
Type type() const;
bool isYInverted() const;
@@ -105,19 +114,31 @@ public:
void setInputFocus();
Wayland::Surface *handle() const;
+
+#ifdef QT_COMPOSITOR_QUICK
+ WaylandSurfaceItem *surfaceItem() const;
+ void setSurfaceItem(WaylandSurfaceItem *surfaceItem);
+#endif
+
qint64 processId() const;
QByteArray authenticationToken() const;
QVariantMap windowProperties() const;
void setWindowProperty(const QString &name, const QVariant &value);
+ QPoint mapToParent(const QPoint &) const;
+ QPoint mapTo(WaylandSurface *, const QPoint &) const;
+
signals:
void mapped();
void unmapped();
void damaged(const QRect &rect);
+ void parentChanged(WaylandSurface *newParent, WaylandSurface *oldParent);
+ void geometryChanged();
void windowPropertyChanged(const QString &name, const QVariant &value);
friend class Wayland::Surface;
friend class Wayland::SurfacePrivate;
+ friend class Wayland::ExtendedSurface;
};
#endif // WAYLANDSURFACE_H
diff --git a/src/compositor/compositor_api/waylandsurfaceitem.cpp b/src/compositor/compositor_api/waylandsurfaceitem.cpp
index 67d478432..4d3687ceb 100644
--- a/src/compositor/compositor_api/waylandsurfaceitem.cpp
+++ b/src/compositor/compositor_api/waylandsurfaceitem.cpp
@@ -41,6 +41,9 @@
#include "waylandsurfaceitem.h"
#include "waylandsurface.h"
+#include "wlsurface.h"
+#include "wlextendedsurface.h"
+
#include <QtGui/QKeyEvent>
#include <QtQuick/QSGSimpleTextureNode>
@@ -62,13 +65,6 @@ public:
bool smooth;
};
-void WaylandSurfaceItem::surfaceDamaged(const QRect &)
-{
- m_damaged = true;
- emit textureChanged();
- update();
-}
-
WaylandSurfaceItem::WaylandSurfaceItem(QQuickItem *parent)
: QQuickItem(parent)
, m_surface(0)
@@ -95,7 +91,12 @@ void WaylandSurfaceItem::init(WaylandSurface *surface)
if (!surface)
return;
+ if (m_surface) {
+ m_surface->setSurfaceItem(0);
+ }
+
m_surface = surface;
+ m_surface->setSurfaceItem(this);
setWidth(surface->geometry().width());
setHeight(surface->geometry().height());
@@ -104,8 +105,12 @@ void WaylandSurfaceItem::init(WaylandSurface *surface)
setFlag(ItemHasContents);
setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
connect(surface, SIGNAL(mapped(const QSize &)), this, SLOT(surfaceMapped(const QSize &)));
+ connect(surface, SIGNAL(unmapped()), this, SLOT(surfaceUnmapped()));
connect(surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
connect(surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
+ connect(surface, SIGNAL(parentChanged(WaylandSurface*,WaylandSurface*)),
+ this, SLOT(parentChanged(WaylandSurface*,WaylandSurface*)));
+ connect(surface, SIGNAL(geometryChanged()), this, SLOT(updateGeometry()));
m_damaged = false;
@@ -113,6 +118,9 @@ void WaylandSurfaceItem::init(WaylandSurface *surface)
WaylandSurfaceItem::~WaylandSurfaceItem()
{
+ if (m_surface) {
+ m_surface->setSurfaceItem(0);
+ }
m_texture->deleteLater();
}
@@ -194,10 +202,14 @@ QPoint WaylandSurfaceItem::toSurface(const QPointF &pos) const
return pos.toPoint();
}
-void WaylandSurfaceItem::surfaceMapped(const QSize &size)
+void WaylandSurfaceItem::surfaceMapped(const QSize &)
+{
+ setPaintEnabled(true);
+}
+
+void WaylandSurfaceItem::surfaceUnmapped()
{
- setWidth(size.width());
- setHeight(size.height());
+ setPaintEnabled(false);
}
void WaylandSurfaceItem::surfaceDestroyed(QObject *)
@@ -205,6 +217,34 @@ void WaylandSurfaceItem::surfaceDestroyed(QObject *)
m_surface = 0;
}
+void WaylandSurfaceItem::surfaceDamaged(const QRect &)
+{
+ m_damaged = true;
+ emit textureChanged();
+ update();
+}
+
+void WaylandSurfaceItem::parentChanged(WaylandSurface *newParent, WaylandSurface *oldParent)
+{
+ Q_UNUSED(oldParent);
+
+ WaylandSurfaceItem *item = newParent? newParent->surfaceItem():0;
+ setParentItem(item);
+
+ if (newParent) {
+ setPaintEnabled(true);
+ setVisible(true);
+ setOpacity(1);
+ setEnabled(true);
+ }
+}
+
+void WaylandSurfaceItem::updateGeometry()
+{
+ setPos(m_surface->geometry().topLeft());
+ setSize(m_surface->geometry().size());
+}
+
bool WaylandSurfaceItem::paintEnabled() const
{
return m_paintEnabled;
@@ -218,9 +258,10 @@ void WaylandSurfaceItem::setPaintEnabled(bool enabled)
QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
- if (!m_surface)
+ if (!m_surface) {
+ delete oldNode;
return 0;
- QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);
+ }
if (m_damaged) {
QSGTexture *oldTexture = m_texture;
@@ -234,6 +275,7 @@ QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDa
} else {
m_texture = canvas()->createTextureFromImage(m_surface->image());
}
+
delete oldTexture;
m_damaged = false;
}
@@ -243,6 +285,7 @@ QSGNode *WaylandSurfaceItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDa
m_provider->smooth = smooth();
}
+ QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);
if (!m_texture || !m_paintEnabled) {
delete oldNode;
return 0;
diff --git a/src/compositor/compositor_api/waylandsurfaceitem.h b/src/compositor/compositor_api/waylandsurfaceitem.h
index a66a2cead..e08cda3ba 100644
--- a/src/compositor/compositor_api/waylandsurfaceitem.h
+++ b/src/compositor/compositor_api/waylandsurfaceitem.h
@@ -100,8 +100,11 @@ public slots:
private slots:
void surfaceMapped(const QSize &size);
+ void surfaceUnmapped();
void surfaceDestroyed(QObject *object);
void surfaceDamaged(const QRect &);
+ void parentChanged(WaylandSurface *newParent, WaylandSurface *oldParent);
+ void updateGeometry();
signals:
void textureChanged();
diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri
index cf841f914..6340f5c3f 100644
--- a/src/compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri
@@ -1,5 +1,6 @@
WAYLANDSOURCES += \
$$PWD/../../../extensions/surface-extension.xml \
+ $$PWD/../../../extensions/sub-surface-extension.xml \
$$PWD/../../../extensions/output-extension.xml
@@ -16,7 +17,8 @@ HEADERS += \
$$PWD/wldataoffer.h \
$$PWD/wldatasource.h \
$$PWD/wlextendedsurface.h \
- $$PWD/wlextendedoutput.h
+ $$PWD/wlextendedoutput.h \
+ $$PWD/wlsubsurface.h
SOURCES += \
$$PWD/wlcompositor.cpp \
@@ -31,5 +33,6 @@ SOURCES += \
$$PWD/wldataoffer.cpp \
$$PWD/wldatasource.cpp \
$$PWD/wlextendedsurface.cpp \
- $$PWD/wlextendedoutput.cpp
+ $$PWD/wlextendedoutput.cpp \
+ $$PWD/wlsubsurface.cpp
diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp
index abfcac63f..b998c9120 100644
--- a/src/compositor/wayland_wrapper/wlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/wlcompositor.cpp
@@ -49,6 +49,7 @@
#include "wldatadevice.h"
#include "wlextendedoutput.h"
#include "wlextendedsurface.h"
+#include "wlsubsurface.h"
#include <QWindow>
#include <QSocketNotifier>
@@ -120,6 +121,7 @@ Compositor::Compositor(WaylandCompositor *qt_compositor)
, m_retainNotify(0)
, m_outputExtension(0)
, m_surfaceExtension(0)
+ , m_subSurfaceExtension(0)
{
compositor = this;
qDebug() << "Compositor instance is" << this;
@@ -339,6 +341,13 @@ void Compositor::initializeWindowManagerProtocol()
m_windowManagerIntegration->initialize(m_display);
}
+void Compositor::enableSubSurfaceExtension()
+{
+ if (!m_subSurfaceExtension) {
+ m_subSurfaceExtension = new SubSurfaceExtensionGlobal(this);
+ }
+}
+
bool Compositor::setDirectRenderSurface(Surface *surface)
{
#ifdef QT_COMPOSITOR_WAYLAND_GL
diff --git a/src/compositor/wayland_wrapper/wlcompositor.h b/src/compositor/wayland_wrapper/wlcompositor.h
index 4404ff81e..a26e23aab 100644
--- a/src/compositor/wayland_wrapper/wlcompositor.h
+++ b/src/compositor/wayland_wrapper/wlcompositor.h
@@ -64,6 +64,7 @@ class InputDevice;
class DataDeviceManager;
class OutputExtensionGlobal;
class SurfaceExtensionGlobal;
+class SubSurfaceExtensionGlobal;
class Q_COMPOSITOR_EXPORT Compositor : public QObject
{
@@ -100,6 +101,7 @@ public:
GraphicsHardwareIntegration *graphicsHWIntegration() const;
void initializeHardwareIntegration();
void initializeWindowManagerProtocol();
+ void enableSubSurfaceExtension();
bool setDirectRenderSurface(Surface *surface);
Surface *directRenderSurface() const {return m_directRenderSurface;}
@@ -181,6 +183,7 @@ private:
OutputExtensionGlobal *m_outputExtension;
SurfaceExtensionGlobal *m_surfaceExtension;
+ SubSurfaceExtensionGlobal *m_subSurfaceExtension;
static void bind_func(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
diff --git a/src/compositor/wayland_wrapper/wlextendedsurface.cpp b/src/compositor/wayland_wrapper/wlextendedsurface.cpp
index 85bdd8e33..68f6d0573 100644
--- a/src/compositor/wayland_wrapper/wlextendedsurface.cpp
+++ b/src/compositor/wayland_wrapper/wlextendedsurface.cpp
@@ -87,6 +87,11 @@ ExtendedSurface::ExtendedSurface(struct wl_client *client, uint32_t id, Surface
this);
}
+ExtendedSurface::~ExtendedSurface()
+{
+
+}
+
void ExtendedSurface::sendGenericProperty(const char *name, const QVariant &variant)
{
QByteArray byteValue;
@@ -106,6 +111,7 @@ void ExtendedSurface::sendOnScreenVisibllity(bool visible)
wl_resource_post_event(m_extended_surface_resource,WL_EXTENDED_SURFACE_ONSCREEN_VISIBILITY,visibleInt);
}
+
void ExtendedSurface::update_generic_property(wl_client *client, wl_resource *extended_surface_resource, const char *name, wl_array *value)
{
Q_UNUSED(client);
diff --git a/src/compositor/wayland_wrapper/wlextendedsurface.h b/src/compositor/wayland_wrapper/wlextendedsurface.h
index d32289615..46dc03c18 100644
--- a/src/compositor/wayland_wrapper/wlextendedsurface.h
+++ b/src/compositor/wayland_wrapper/wlextendedsurface.h
@@ -43,12 +43,16 @@
#include "wayland-surface-extension-server-protocol.h"
+#include "wlsurface.h"
+
#include <QtCore/QVariant>
+#include <QtCore/QLinkedList>
+
+class WaylandSurface;
namespace Wayland {
class Compositor;
-class Surface;
class SurfaceExtensionGlobal
{
@@ -72,10 +76,17 @@ class ExtendedSurface
{
public:
ExtendedSurface(struct wl_client *client, uint32_t id, Surface *surface);
+ ~ExtendedSurface();
void sendGenericProperty(const char *name, const QVariant &variant);
void sendOnScreenVisibllity(bool visible);
+ void setSubSurface(ExtendedSurface *subSurface,int x, int y);
+ void removeSubSurface(ExtendedSurface *subSurfaces);
+ ExtendedSurface *parent() const;
+ void setParent(ExtendedSurface *parent);
+ QLinkedList<WaylandSurface *> subSurfaces() const;
+
private:
struct wl_resource *m_extended_surface_resource;
Surface *m_surface;
@@ -84,6 +95,17 @@ private:
struct wl_resource *resource,
const char *name,
struct wl_array *value);
+ static void map_sub_surface(struct wl_client *client,
+ struct wl_resource *extended_surface_resource,
+ struct wl_resource *sub_surface_resource,
+ int32_t x,
+ int32_t y);
+ static void move_sub_surface(struct wl_client *client,
+ struct wl_resource *extended_surface_resource,
+ struct wl_resource *sub_surface_resource,
+ int32_t x,
+ int32_t y);
+
static const struct wl_extended_surface_interface extended_surface_interface;
};
diff --git a/src/compositor/wayland_wrapper/wlsubsurface.cpp b/src/compositor/wayland_wrapper/wlsubsurface.cpp
new file mode 100644
index 000000000..e8b8ab6e3
--- /dev/null
+++ b/src/compositor/wayland_wrapper/wlsubsurface.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** 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 "wlsubsurface.h"
+
+#include "wlcompositor.h"
+
+namespace Wayland {
+
+SubSurfaceExtensionGlobal::SubSurfaceExtensionGlobal(Compositor *compositor)
+ : m_compositor(compositor)
+{
+ wl_display_add_global(m_compositor->wl_display(),
+ &wl_sub_surface_extension_interface,
+ this,
+ SubSurfaceExtensionGlobal::bind_func);
+}
+
+void SubSurfaceExtensionGlobal::bind_func(wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+ Q_UNUSED(version);
+ wl_client_add_object(client, &wl_sub_surface_extension_interface,&sub_surface_extension_interface,id,data);
+}
+
+void SubSurfaceExtensionGlobal::get_sub_surface_aware_surface(wl_client *client, wl_resource *sub_surface_extension_resource, uint32_t id, wl_resource *surface_resource)
+{
+ Q_UNUSED(sub_surface_extension_resource);
+ Surface *surface = reinterpret_cast<Surface *>(surface_resource);
+ new SubSurface(client,id,surface);
+}
+
+const struct wl_sub_surface_extension_interface SubSurfaceExtensionGlobal::sub_surface_extension_interface = {
+ SubSurfaceExtensionGlobal::get_sub_surface_aware_surface
+};
+
+SubSurface::SubSurface(wl_client *client, uint32_t id, Surface *surface)
+ : m_surface(surface)
+ , m_parent(0)
+{
+ surface->setSubSurface(this);
+ m_sub_surface_resource = wl_client_add_object(client,
+ &wl_sub_surface_interface,
+ &sub_surface_interface,
+ id,
+ this);
+}
+
+SubSurface::~SubSurface()
+{
+ if (m_parent) {
+ m_parent->removeSubSurface(this);
+ }
+}
+
+void SubSurface::setSubSurface(SubSurface *subSurface, int x, int y)
+{
+// Q_ASSERT(!m_sub_surfaces.contains(subSurface->m_surface->handle()));
+ m_sub_surfaces.append(subSurface->m_surface->handle());
+ subSurface->setParent(this);
+ QRect rect = m_surface->geometry();
+ rect.moveTo(x,y);
+ subSurface->m_surface->setGeometry(rect);
+}
+
+void SubSurface::removeSubSurface(SubSurface *subSurfaces)
+{
+ Q_ASSERT(m_sub_surfaces.contains(subSurfaces->m_surface->handle()));
+ m_sub_surfaces.removeOne(subSurfaces->m_surface->handle());
+}
+
+SubSurface *SubSurface::parent() const
+{
+ return m_parent;
+}
+
+void SubSurface::setParent(SubSurface *parent)
+{
+ if (m_parent == parent)
+ return;
+
+ WaylandSurface *oldParent = 0;
+ WaylandSurface *newParent = 0;
+
+ if (m_parent) {
+ oldParent = m_parent->m_surface->handle();
+ m_parent->removeSubSurface(this);
+ }
+ if (parent) {
+ newParent = parent->m_surface->handle();
+ }
+ m_parent = parent;
+
+ m_surface->handle()->parentChanged(newParent,oldParent);
+}
+
+QLinkedList<WaylandSurface *> SubSurface::subSurfaces() const
+{
+ return m_sub_surfaces;
+}
+
+void SubSurface::attach_sub_surface(wl_client *client, wl_resource *sub_surface_parent_resource, wl_resource *sub_surface_child_resource, int32_t x, int32_t y)
+{
+ Q_UNUSED(client);
+ SubSurface *parent_sub_surface = static_cast<SubSurface *>(sub_surface_parent_resource->data);
+ SubSurface *child_sub_surface = static_cast<SubSurface *>(sub_surface_child_resource->data);
+ parent_sub_surface->setSubSurface(child_sub_surface,x,y);
+}
+
+void SubSurface::move_sub_surface(wl_client *client, wl_resource *sub_surface_parent_resource, wl_resource *sub_surface_child_resource, int32_t x, int32_t y)
+{
+ Q_UNUSED(client);
+ SubSurface *parent_sub_surface = static_cast<SubSurface *>(sub_surface_parent_resource->data);
+ SubSurface *child_sub_surface = static_cast<SubSurface *>(sub_surface_child_resource->data);
+}
+
+void SubSurface::raise(wl_client *client, wl_resource *sub_surface_parent_resource, wl_resource *sub_surface_child_resource)
+{
+}
+
+void SubSurface::lower(wl_client *client, wl_resource *sub_surface_parent_resource, wl_resource *sub_surface_child_resource)
+{
+}
+
+const struct wl_sub_surface_interface SubSurface::sub_surface_interface = {
+ SubSurface::attach_sub_surface,
+ SubSurface::move_sub_surface,
+ SubSurface::raise,
+ SubSurface::lower
+};
+
+}
diff --git a/src/compositor/wayland_wrapper/wlsubsurface.h b/src/compositor/wayland_wrapper/wlsubsurface.h
new file mode 100644
index 000000000..947cd02ca
--- /dev/null
+++ b/src/compositor/wayland_wrapper/wlsubsurface.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#ifndef WLSUBSURFACE_H
+#define WLSUBSURFACE_H
+
+#include "wlsurface.h"
+
+#include "wayland-sub-surface-extension-server-protocol.h"
+
+#include <QtCore/QLinkedList>
+
+class Compositor;
+class WaylandSurface;
+
+namespace Wayland {
+
+class SubSurfaceExtensionGlobal
+{
+public:
+ SubSurfaceExtensionGlobal(Compositor *compositor);
+
+private:
+ Compositor *m_compositor;
+
+ static void bind_func(struct wl_client *client, void *data,
+ uint32_t version, uint32_t id);
+ static void get_sub_surface_aware_surface(struct wl_client *client,
+ struct wl_resource *sub_surface_extension_resource,
+ uint32_t id,
+ struct wl_resource *surface_resource);
+
+ static const struct wl_sub_surface_extension_interface sub_surface_extension_interface;
+};
+
+class SubSurface
+{
+public:
+ SubSurface(struct wl_client *client, uint32_t id, Surface *surface);
+ ~SubSurface();
+
+ void setSubSurface(SubSurface *subSurface, int x, int y);
+ void removeSubSurface(SubSurface *subSurfaces);
+
+ SubSurface *parent() const;
+ void setParent(SubSurface *parent);
+
+ QLinkedList<WaylandSurface *> subSurfaces() const;
+
+ Surface *surface() const;
+ WaylandSurface *waylandSurface() const;
+
+private:
+ struct wl_resource *m_sub_surface_resource;
+ Surface *m_surface;
+
+ SubSurface *m_parent;
+ QLinkedList<WaylandSurface *> m_sub_surfaces;
+
+ static void attach_sub_surface(struct wl_client *client,
+ struct wl_resource *sub_surface_parent_resource,
+ struct wl_resource *sub_surface_child_resource,
+ int32_t x,
+ int32_t y);
+ static void move_sub_surface(struct wl_client *client,
+ struct wl_resource *sub_surface_parent_resource,
+ struct wl_resource *sub_surface_child_resource,
+ int32_t x,
+ int32_t y);
+ static void raise(struct wl_client *client,
+ struct wl_resource *sub_surface_parent_resource,
+ struct wl_resource *sub_surface_child_resource);
+ static void lower(struct wl_client *client,
+ struct wl_resource *sub_surface_parent_resource,
+ struct wl_resource *sub_surface_child_resource);
+ static const struct wl_sub_surface_interface sub_surface_interface;
+};
+
+inline Surface *SubSurface::surface() const
+{
+ return m_surface;
+}
+
+inline WaylandSurface *SubSurface::waylandSurface() const
+{
+ return m_surface->handle();
+}
+
+
+}
+
+#endif // WLSUBSURFACE_H
diff --git a/src/compositor/wayland_wrapper/wlsurface.cpp b/src/compositor/wayland_wrapper/wlsurface.cpp
index 21f2d3167..30b0bd09c 100644
--- a/src/compositor/wayland_wrapper/wlsurface.cpp
+++ b/src/compositor/wayland_wrapper/wlsurface.cpp
@@ -46,6 +46,7 @@
#include "wlshmbuffer.h"
#include "wlinputdevice.h"
#include "wlextendedsurface.h"
+#include "wlsubsurface.h"
#include <QtCore/QDebug>
@@ -203,11 +204,13 @@ public:
: q_ptr(surface)
, client(client)
, compositor(compositor)
+ , qtSurface(new WaylandSurface(surface))
, directRenderBuffer(0)
, processId(0)
, textureBuffer(0)
, surfaceBuffer(0)
, extendedSurface(0)
+ , subSurface(0)
{
@@ -236,8 +239,11 @@ public:
struct wl_list frame_callback_list;
ExtendedSurface *extendedSurface;
+ SubSurface *subSurface;
SurfaceBuffer bufferPool[buffer_pool_size];
+
+ QRect geometry;
private:
Surface *q_ptr;
};
@@ -278,7 +284,7 @@ Surface::Surface(struct wl_client *client, Compositor *compositor)
: d_ptr(new SurfacePrivate(this,client,compositor))
{
base()->resource.client = client;
- d_ptr->qtSurface = new WaylandSurface(this);
+
}
Surface::~Surface()
@@ -309,6 +315,9 @@ bool Surface::isYInverted() const
#ifdef QT_COMPOSITOR_WAYLAND_GL
Q_D(const Surface);
+ if (!d->surfaceBuffer)
+ return false;
+
if (d->compositor->graphicsHWIntegration() && !d->surfaceBuffer->bufferIsDestroyed()) {
if (type() == WaylandSurface::Texture) {
return d->compositor->graphicsHWIntegration()->isYInverted(d->surfaceBuffer->handle());
@@ -368,11 +377,31 @@ QImage Surface::image() const
return QImage();
}
+QRect Surface::geometry() const
+{
+ Q_D(const Surface);
+ return d->geometry;
+}
+
+void Surface::setGeometry(const QRect &rect)
+{
+ Q_D(Surface);
+ bool emitChange = false;
+ if (rect != d->geometry)
+ emitChange = true;
+ d->geometry = rect;
+ if (emitChange)
+ d->qtSurface->geometryChanged();
+}
+
#ifdef QT_COMPOSITOR_WAYLAND_GL
GLuint Surface::textureId(QOpenGLContext *context) const
{
Q_D(const Surface);
+ if (!d->surfaceBuffer) {
+ return 0;
+ }
if (d->compositor->graphicsHWIntegration() && type() == WaylandSurface::Texture
&& !d->surfaceBuffer->textureCreated()) {
Surface *that = const_cast<Surface *>(this);
@@ -408,7 +437,7 @@ void Surface::attach(struct wl_buffer *buffer)
Q_ASSERT(newBuffer);
}
- bool emitMap = !d->surfaceBuffer && buffer;
+ bool emitMap = !d->surfaceBuffer && buffer && (!d->subSurface || !d->subSurface->parent());
bool emitUnmap = d->surfaceBuffer && !buffer;
if (d->surfaceBuffer && d->surfaceBuffer != d->directRenderBuffer) {
@@ -418,6 +447,17 @@ void Surface::attach(struct wl_buffer *buffer)
d->surfaceBuffer = 0;
}
d->surfaceBuffer = newBuffer;
+ int width = 0;
+ int height = 0;
+ if (d->surfaceBuffer) {
+ width = d->surfaceBuffer->width();
+ height = d->surfaceBuffer->height();
+ }
+ QRect geo = geometry();
+ geo.setWidth(width);
+ geo.setHeight(height);
+ setGeometry(geo);
+
if (emitMap) {
d->qtSurface->mapped();
} else if (emitUnmap) {
@@ -515,6 +555,18 @@ ExtendedSurface *Surface::extendedSurface() const
return d->extendedSurface;
}
+void Surface::setSubSurface(SubSurface *subSurface)
+{
+ Q_D(Surface);
+ d->subSurface = subSurface;
+}
+
+SubSurface *Surface::subSurface() const
+{
+ Q_D(const Surface);
+ return d->subSurface;
+}
+
void Surface::sendMousePressEvent(int x, int y, Qt::MouseButton button)
{
Q_D(Surface);
diff --git a/src/compositor/wayland_wrapper/wlsurface.h b/src/compositor/wayland_wrapper/wlsurface.h
index 425e3ce88..905ee535e 100644
--- a/src/compositor/wayland_wrapper/wlsurface.h
+++ b/src/compositor/wayland_wrapper/wlsurface.h
@@ -64,6 +64,7 @@ namespace Wayland {
class Compositor;
class Buffer;
class ExtendedSurface;
+class SubSurface;
class SurfacePrivate;
@@ -83,6 +84,9 @@ public:
QImage image() const;
+ QRect geometry() const;
+ void setGeometry(const QRect &rect);
+
#ifdef QT_COMPOSITOR_WAYLAND_GL
GLuint textureId(QOpenGLContext *context) const;
#endif
@@ -121,6 +125,9 @@ public:
void setExtendedSurface(ExtendedSurface *extendedSurface);
ExtendedSurface *extendedSurface() const;
+ void setSubSurface(SubSurface *subSurface);
+ SubSurface *subSurface() const;
+
static const struct wl_surface_interface surface_interface;
protected:
QScopedPointer<SurfacePrivate> d_ptr;
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 &region, 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