1 /*
2     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 #pragma once
8 
9 #include "surface_interface.h"
10 #include "utils.h"
11 // Qt
12 #include <QHash>
13 #include <QVector>
14 // Wayland
15 #include "qwayland-server-wayland.h"
16 
17 namespace KWaylandServer
18 {
19 class IdleInhibitorV1Interface;
20 class SurfaceRole;
21 class ViewportInterface;
22 
23 struct SurfaceState {
24     void mergeInto(SurfaceState *target);
25 
26     QRegion damage = QRegion();
27     QRegion bufferDamage = QRegion();
28     QRegion opaque = QRegion();
29     QRegion input = infiniteRegion();
30     bool inputIsSet = false;
31     bool opaqueIsSet = false;
32     bool bufferIsSet = false;
33     bool shadowIsSet = false;
34     bool blurIsSet = false;
35     bool contrastIsSet = false;
36     bool slideIsSet = false;
37     bool childrenChanged = false;
38     bool bufferScaleIsSet = false;
39     bool bufferTransformIsSet = false;
40     qint32 bufferScale = 1;
41     OutputInterface::Transform bufferTransform = OutputInterface::Transform::Normal;
42     wl_list frameCallbacks;
43     QPoint offset = QPoint();
44     QPointer<ClientBuffer> buffer;
45     QPointer<ShadowInterface> shadow;
46     QPointer<BlurInterface> blur;
47     QPointer<ContrastInterface> contrast;
48     QPointer<SlideInterface> slide;
49 
50     // Subsurfaces are stored in two lists. The below list contains subsurfaces that
51     // are below their parent surface; the above list contains subsurfaces that are
52     // placed above the parent surface.
53     QList<SubSurfaceInterface *> below;
54     QList<SubSurfaceInterface *> above;
55 
56     struct {
57         QRectF sourceGeometry = QRectF();
58         QSize destinationSize = QSize();
59         bool sourceGeometryIsSet = false;
60         bool destinationSizeIsSet = false;
61     } viewport;
62 };
63 
64 class SurfaceInterfacePrivate : public QtWaylandServer::wl_surface
65 {
66 public:
get(SurfaceInterface * surface)67     static SurfaceInterfacePrivate *get(SurfaceInterface *surface)
68     {
69         return surface->d.data();
70     }
71 
72     explicit SurfaceInterfacePrivate(SurfaceInterface *q);
73     ~SurfaceInterfacePrivate() override;
74 
75     void addChild(SubSurfaceInterface *subsurface);
76     void removeChild(SubSurfaceInterface *subsurface);
77     bool raiseChild(SubSurfaceInterface *subsurface, SurfaceInterface *anchor);
78     bool lowerChild(SubSurfaceInterface *subsurface, SurfaceInterface *anchor);
79     void setShadow(const QPointer<ShadowInterface> &shadow);
80     void setBlur(const QPointer<BlurInterface> &blur);
81     void setContrast(const QPointer<ContrastInterface> &contrast);
82     void setSlide(const QPointer<SlideInterface> &slide);
83     void installPointerConstraint(LockedPointerV1Interface *lock);
84     void installPointerConstraint(ConfinedPointerV1Interface *confinement);
85     void installIdleInhibitor(IdleInhibitorV1Interface *inhibitor);
86 
87     void commitToCache();
88     void commitFromCache();
89 
90     void commitSubSurface();
91     QMatrix4x4 buildSurfaceToBufferMatrix();
92     void applyState(SurfaceState *next);
93 
94     bool computeEffectiveMapped() const;
95     void updateEffectiveMapped();
96 
97     CompositorInterface *compositor;
98     SurfaceInterface *q;
99     SurfaceRole *role = nullptr;
100     SurfaceState current;
101     SurfaceState pending;
102     SurfaceState cached;
103     SubSurfaceInterface *subSurface = nullptr;
104     QMatrix4x4 surfaceToBufferMatrix;
105     QMatrix4x4 bufferToSurfaceMatrix;
106     QSize bufferSize;
107     QSize surfaceSize;
108     QRegion inputRegion;
109     ClientBuffer *bufferRef = nullptr;
110     bool mapped = false;
111     bool hasCacheState = false;
112 
113     QVector<OutputInterface *> outputs;
114 
115     LockedPointerV1Interface *lockedPointer = nullptr;
116     ConfinedPointerV1Interface *confinedPointer = nullptr;
117     QHash<OutputInterface *, QMetaObject::Connection> outputDestroyedConnections;
118     QHash<OutputInterface *, QMetaObject::Connection> outputBoundConnections;
119 
120     QVector<IdleInhibitorV1Interface *> idleInhibitors;
121     ViewportInterface *viewportExtension = nullptr;
122     ClientConnection *client = nullptr;
123 
124 protected:
125     void surface_destroy_resource(Resource *resource) override;
126     void surface_destroy(Resource *resource) override;
127     void surface_attach(Resource *resource, struct ::wl_resource *buffer, int32_t x, int32_t y) override;
128     void surface_damage(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) override;
129     void surface_frame(Resource *resource, uint32_t callback) override;
130     void surface_set_opaque_region(Resource *resource, struct ::wl_resource *region) override;
131     void surface_set_input_region(Resource *resource, struct ::wl_resource *region) override;
132     void surface_commit(Resource *resource) override;
133     void surface_set_buffer_transform(Resource *resource, int32_t transform) override;
134     void surface_set_buffer_scale(Resource *resource, int32_t scale) override;
135     void surface_damage_buffer(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) override;
136 
137 private:
138     QMetaObject::Connection constrainsOneShotConnection;
139     QMetaObject::Connection constrainsUnboundConnection;
140 };
141 
142 } // namespace KWaylandServer
143