1 /*
2     SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #ifndef WAYLAND_SERVER_SURFACE_INTERFACE_P_H
7 #define WAYLAND_SERVER_SURFACE_INTERFACE_P_H
8 
9 #include "resource_p.h"
10 #include "surface_interface.h"
11 // Qt
12 #include <QHash>
13 #include <QVector>
14 // Wayland
15 #include <wayland-server.h>
16 
17 namespace KWayland
18 {
19 namespace Server
20 {
21 class IdleInhibitorInterface;
22 class SurfaceRole;
23 
24 class SurfaceInterface::Private : public Resource::Private
25 {
26 public:
27     struct State {
28         QRegion damage = QRegion();
29         QRegion bufferDamage = QRegion();
30         QRegion opaque = QRegion();
31         QRegion input = QRegion();
32         bool inputIsSet = false;
33         bool opaqueIsSet = false;
34         bool bufferIsSet = false;
35         bool shadowIsSet = false;
36         bool blurIsSet = false;
37         bool contrastIsSet = false;
38         bool slideIsSet = false;
39         bool inputIsInfinite = true;
40         bool childrenChanged = false;
41         bool scaleIsSet = false;
42         bool transformIsSet = false;
43         qint32 scale = 1;
44         OutputInterface::Transform transform = OutputInterface::Transform::Normal;
45         QList<wl_resource *> callbacks = QList<wl_resource *>();
46         QPoint offset = QPoint();
47         BufferInterface *buffer = nullptr;
48         // stacking order: bottom (first) -> top (last)
49         QList<QPointer<SubSurfaceInterface>> children;
50         QPointer<ShadowInterface> shadow;
51         QPointer<BlurInterface> blur;
52         QPointer<ContrastInterface> contrast;
53         QPointer<SlideInterface> slide;
54     };
55     Private(SurfaceInterface *q, CompositorInterface *c, wl_resource *parentResource);
56     ~Private() override;
57 
58     void destroy();
59 
60     void addChild(QPointer<SubSurfaceInterface> subsurface);
61     void removeChild(QPointer<SubSurfaceInterface> subsurface);
62     bool raiseChild(QPointer<SubSurfaceInterface> subsurface, SurfaceInterface *sibling);
63     bool lowerChild(QPointer<SubSurfaceInterface> subsurface, SurfaceInterface *sibling);
64     void setShadow(const QPointer<ShadowInterface> &shadow);
65     void setBlur(const QPointer<BlurInterface> &blur);
66     void setContrast(const QPointer<ContrastInterface> &contrast);
67     void setSlide(const QPointer<SlideInterface> &slide);
68     void installPointerConstraint(LockedPointerInterface *lock);
69     void installPointerConstraint(ConfinedPointerInterface *confinement);
70     void installIdleInhibitor(IdleInhibitorInterface *inhibitor);
71 
72     void commitSubSurface();
73     void commit();
74 
75     SurfaceRole *role = nullptr;
76 
77     State current;
78     State pending;
79     State subSurfacePending;
80     QPointer<SubSurfaceInterface> subSurface;
81     QRegion trackedDamage;
82 
83     // workaround for https://bugreports.qt.io/browse/QTBUG-52192
84     // A subsurface needs to be considered mapped even if it doesn't have a buffer attached
85     // Otherwise Qt's sub-surfaces will never be visible and the client will freeze due to
86     // waiting on the frame callback of the never visible surface
87     bool subSurfaceIsMapped = true;
88 
89     QVector<OutputInterface *> outputs;
90 
91     QPointer<LockedPointerInterface> lockedPointer;
92     QPointer<ConfinedPointerInterface> confinedPointer;
93     QHash<OutputInterface *, QMetaObject::Connection> outputDestroyedConnections;
94     QVector<IdleInhibitorInterface *> idleInhibitors;
95 
96     SurfaceInterface *dataProxy = nullptr;
97 
98 private:
99     QMetaObject::Connection constrainsOneShotConnection;
100     QMetaObject::Connection constrainsUnboundConnection;
101 
q_func()102     SurfaceInterface *q_func()
103     {
104         return reinterpret_cast<SurfaceInterface *>(q);
105     }
106     void swapStates(State *source, State *target, bool emitChanged);
107     void damage(const QRect &rect);
108     void damageBuffer(const QRect &rect);
109     void setScale(qint32 scale);
110     void setTransform(OutputInterface::Transform transform);
111     void addFrameCallback(uint32_t callback);
112     void attachBuffer(wl_resource *buffer, const QPoint &offset);
113     void setOpaque(const QRegion &region);
114     void setInput(const QRegion &region, bool isInfinite);
115 
116     static void destroyFrameCallback(wl_resource *r);
117 
118     static void attachCallback(wl_client *client, wl_resource *resource, wl_resource *buffer, int32_t sx, int32_t sy);
119     static void damageCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height);
120     static void frameCallback(wl_client *client, wl_resource *resource, uint32_t callback);
121     static void opaqueRegionCallback(wl_client *client, wl_resource *resource, wl_resource *region);
122     static void inputRegionCallback(wl_client *client, wl_resource *resource, wl_resource *region);
123     static void commitCallback(wl_client *client, wl_resource *resource);
124     // since version 2
125     static void bufferTransformCallback(wl_client *client, wl_resource *resource, int32_t transform);
126     // since version 3
127     static void bufferScaleCallback(wl_client *client, wl_resource *resource, int32_t scale);
128     // since version 4
129     static void damageBufferCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height);
130 
131     static const struct wl_surface_interface s_interface;
132 };
133 
134 }
135 }
136 
137 #endif
138