From 933d69af3061e9fdfe9e9ca1ea61055aac2c0482 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 9 Dec 2015 14:38:30 +0100 Subject: Subsurface implementation, with C++ API This adds support for subsurfaces to QWaylandCompositor and QWaylandSurface. Task-number: QTBUG-49809 Change-Id: I2fa9ee4dcd1f48a2a28dab536f9cd6edc716e42b Reviewed-by: Giulio Camuffo --- .../compositor_api/qwaylandcompositor.cpp | 14 ++++++- src/compositor/compositor_api/qwaylandcompositor.h | 1 + .../compositor_api/qwaylandcompositor_p.h | 8 ++-- src/compositor/compositor_api/qwaylandsurface.cpp | 47 ++++++++++++++++++++++ src/compositor/compositor_api/qwaylandsurface.h | 4 ++ src/compositor/compositor_api/qwaylandsurface_p.h | 27 +++++++++++++ 6 files changed, 96 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index 9aec337bd..5480b1cf1 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -158,6 +158,7 @@ void QWaylandCompositorPrivate::init() socket_name = arguments.at(socketArg + 1).toLocal8Bit(); wl_compositor::init(display, 3); + wl_subcompositor::init(display, 1); data_device_manager = new QtWayland::DataDeviceManager(q); @@ -270,7 +271,7 @@ void QWaylandCompositorPrivate::addPolishObject(QObject *object) */ -void QWaylandCompositorPrivate::compositor_create_surface(Resource *resource, uint32_t id) +void QWaylandCompositorPrivate::compositor_create_surface(wl_compositor::Resource *resource, uint32_t id) { Q_Q(QWaylandCompositor); QWaylandClient *client = QWaylandClient::fromWlClient(q, resource->client()); @@ -292,11 +293,20 @@ void QWaylandCompositorPrivate::compositor_create_surface(Resource *resource, ui emit q->surfaceCreated(surface); } -void QWaylandCompositorPrivate::compositor_create_region(Resource *resource, uint32_t id) +void QWaylandCompositorPrivate::compositor_create_region(wl_compositor::Resource *resource, uint32_t id) { new QtWayland::Region(resource->client(), id); } +void QWaylandCompositorPrivate::subcompositor_get_subsurface(wl_subcompositor::Resource *resource, uint32_t id, wl_resource *surface, wl_resource *parent) +{ + Q_Q(QWaylandCompositor); + QWaylandSurface *childSurface = QWaylandSurface::fromResource(surface); + QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent); + QWaylandSurfacePrivate::get(childSurface)->initSubsurface(parentSurface, resource->client(), id, 1); + emit q->subsurfaceChanged(childSurface, parentSurface); +} + /*! \internal Used to create a fallback QWaylandSurface when no surface was diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h index cae7b4582..789832762 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.h +++ b/src/compositor/compositor_api/qwaylandcompositor.h @@ -122,6 +122,7 @@ Q_SIGNALS: void createSurface(QWaylandClient *client, uint id, int version); void surfaceCreated(QWaylandSurface *surface); void surfaceAboutToBeDestroyed(QWaylandSurface *surface); + void subsurfaceChanged(QWaylandSurface *child, QWaylandSurface *parent); void defaultOutputChanged(); void defaultInputDeviceChanged(); diff --git a/src/compositor/compositor_api/qwaylandcompositor_p.h b/src/compositor/compositor_api/qwaylandcompositor_p.h index fb0f803ed..942634af5 100644 --- a/src/compositor/compositor_api/qwaylandcompositor_p.h +++ b/src/compositor/compositor_api/qwaylandcompositor_p.h @@ -69,7 +69,7 @@ namespace QtWayland { class QWindowSystemEventHandler; class QWaylandSurface; -class Q_COMPOSITOR_EXPORT QWaylandCompositorPrivate : public QObjectPrivate, public QtWaylandServer::wl_compositor +class Q_COMPOSITOR_EXPORT QWaylandCompositorPrivate : public QObjectPrivate, public QtWaylandServer::wl_compositor, public QtWaylandServer::wl_subcompositor { public: static QWaylandCompositorPrivate *get(QWaylandCompositor *compositor) { return compositor->d_func(); } @@ -105,8 +105,10 @@ public: inline void addOutput(QWaylandOutput *output); inline void removeOutput(QWaylandOutput *output); protected: - void compositor_create_surface(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; - void compositor_create_region(Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + void compositor_create_surface(wl_compositor::Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + void compositor_create_region(wl_compositor::Resource *resource, uint32_t id) Q_DECL_OVERRIDE; + + void subcompositor_get_subsurface(wl_subcompositor::Resource *resource, uint32_t id, struct ::wl_resource *surface, struct ::wl_resource *parent); virtual QWaylandSurface *createDefaultSurface(); protected: diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 9391164cf..ed028824f 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -130,6 +130,7 @@ QWaylandSurfacePrivate::QWaylandSurfacePrivate() , mapped(false) , isInitialized(false) , contentOrientation(Qt::PrimaryOrientation) + , subsurface(0) { pending.buffer = 0; pending.newlyAttached = false; @@ -777,4 +778,50 @@ void QWaylandSurfacePrivate::derefView(QWaylandView *view) } } +void QWaylandSurfacePrivate::initSubsurface(QWaylandSurface *parent, wl_client *client, int id, int version) +{ + Q_Q(QWaylandSurface); + QWaylandSurface *oldParent = 0; // TODO: implement support for switching parents + + subsurface = new Subsurface(this); + subsurface->init(client, id, version); + subsurface->parentSurface = parent->d_func(); + emit q->parentChanged(parent, oldParent); + emit parent->childAdded(q); +} + +void QWaylandSurfacePrivate::Subsurface::subsurface_set_position(wl_subsurface::Resource *resource, int32_t x, int32_t y) +{ + Q_UNUSED(resource); + position = QPoint(x,y); + emit surface->q_func()->subsurfacePositionChanged(position); + +} + +void QWaylandSurfacePrivate::Subsurface::subsurface_place_above(wl_subsurface::Resource *resource, struct wl_resource *sibling) +{ + Q_UNUSED(resource); + emit surface->q_func()->subsurfacePlaceAbove(QWaylandSurface::fromResource(sibling)); +} + +void QWaylandSurfacePrivate::Subsurface::subsurface_place_below(wl_subsurface::Resource *resource, struct wl_resource *sibling) +{ + Q_UNUSED(resource); + emit surface->q_func()->subsurfacePlaceBelow(QWaylandSurface::fromResource(sibling)); +} + +void QWaylandSurfacePrivate::Subsurface::subsurface_set_sync(wl_subsurface::Resource *resource) +{ + Q_UNUSED(resource); + // TODO: sync/desync implementation + qDebug() << Q_FUNC_INFO; +} + +void QWaylandSurfacePrivate::Subsurface::subsurface_set_desync(wl_subsurface::Resource *resource) +{ + Q_UNUSED(resource); + // TODO: sync/desync implementation + qDebug() << Q_FUNC_INFO; +} + QT_END_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index d3fe4f15e..bb034080a 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -129,12 +129,16 @@ Q_SIGNALS: void mappedChanged(); void damaged(const QRegion &rect); void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); + void childAdded(QWaylandSurface *child); void sizeChanged(); void offsetForNextFrame(const QPoint &offset); void contentOrientationChanged(); void pong(); void surfaceDestroyed(); void originChanged(); + void subsurfacePositionChanged(const QPoint &position); + void subsurfacePlaceAbove(QWaylandSurface *sibling); + void subsurfacePlaceBelow(QWaylandSurface *sibling); void configure(bool hasBuffer); void redraw(); diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h index 1f3676bd9..de71b7fe3 100644 --- a/src/compositor/compositor_api/qwaylandsurface_p.h +++ b/src/compositor/compositor_api/qwaylandsurface_p.h @@ -112,6 +112,11 @@ public: static void removeUninitializedSurface(QWaylandSurfacePrivate *surface); static bool hasUninitializedSurface(); #endif + + void initSubsurface(QWaylandSurface *parent, struct ::wl_client *client, int id, int version); + bool isSubsurface() const { return subsurface; } + QWaylandSurfacePrivate *parentSurface() const { return subsurface ? subsurface->parentSurface : nullptr; } + protected: void surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; @@ -170,6 +175,28 @@ protected: //member variables Qt::ScreenOrientation contentOrientation; QWindow::Visibility visibility; + class Subsurface : public QtWaylandServer::wl_subsurface + { + public: + Subsurface(QWaylandSurfacePrivate *s) : surface(s) {} + QWaylandSurfacePrivate *surfaceFromResource(); + + protected: + void subsurface_set_position(wl_subsurface::Resource *resource, int32_t x, int32_t y); + void subsurface_place_above(wl_subsurface::Resource *resource, struct wl_resource *sibling); + void subsurface_place_below(wl_subsurface::Resource *resource, struct wl_resource *sibling); + void subsurface_set_sync(wl_subsurface::Resource *resource); + void subsurface_set_desync(wl_subsurface::Resource *resource); + + private: + friend class QWaylandSurfacePrivate; + QWaylandSurfacePrivate *surface; + QWaylandSurfacePrivate *parentSurface; + QPoint position; + }; + + Subsurface *subsurface; + #ifndef QT_NO_DEBUG static QList uninitializedSurfaces; #endif -- cgit v1.2.3