GCC Code Coverage Report


Directory: ./
File: server/shadow_p.h
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 67 68 98.5%
Branches: 39 64 60.9%

Line Branch Exec Source
1 /********************************************************************
2 Copyright 2020 Adrien Faveraux <ad1rie3@hotmail.fr>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), which shall
10 act as a proxy defined in Section 6 of version 3 of the license.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
20 #pragma once
21
22 #include "shadow.h"
23
24 #include <QMarginsF>
25 #include <QObject>
26
27 #include <cassert>
28 #include <type_traits>
29 #include <wayland-shadow-server-protocol.h>
30
31 #include <wayland-server.h>
32
33 namespace Wrapland::Server
34 {
35
36 class Buffer;
37 class Display;
38
39 constexpr uint32_t ShadowManagerVersion = 2;
40 using ShadowManagerGlobal = Wayland::Global<ShadowManager, ShadowManagerVersion>;
41 using ShadowManagerBind = Wayland::Bind<ShadowManagerGlobal>;
42
43 class ShadowManager::Private : public ShadowManagerGlobal
44 {
45 public:
46 Private(Display* display, ShadowManager* q_ptr);
47
48 private:
49 static void createCallback(ShadowManagerBind* bind, uint32_t id, wl_resource* surface);
50 static void unsetCallback(ShadowManagerBind* bind, wl_resource* surface);
51
52 static const struct org_kde_kwin_shadow_manager_interface s_interface;
53 };
54
55 class Shadow::Private : public Wayland::Resource<Shadow>
56 {
57 public:
58 Private(Client* client, uint32_t version, uint32_t id, Shadow* q_ptr);
59 ~Private() override;
60
61 enum class AttachSide {
62 Left,
63 TopLeft,
64 Top,
65 TopRight,
66 Right,
67 BottomRight,
68 Bottom,
69 BottomLeft,
70 };
71
72 enum class OffsetSide {
73 Left,
74 Top,
75 Right,
76 Bottom,
77 };
78
79 16 struct State {
80 template<AttachSide side>
81 91 std::shared_ptr<Buffer>& get()
82 {
83 if constexpr (side == AttachSide::Left) {
84 11 return left;
85 } else if constexpr (side == AttachSide::TopLeft) {
86 14 return topLeft;
87 } else if constexpr (side == AttachSide::Top) {
88 11 return top;
89 } else if constexpr (side == AttachSide::TopRight) {
90 11 return topRight;
91 } else if constexpr (side == AttachSide::Right) {
92 11 return right;
93 } else if constexpr (side == AttachSide::BottomRight) {
94 11 return bottomRight;
95 } else if constexpr (side == AttachSide::Bottom) {
96 11 return bottom;
97 } else {
98 static_assert(side == AttachSide::BottomLeft);
99 11 return bottomLeft;
100 }
101 }
102
103 // We need this for our QObject connections. Once we use a signal system with good template
104 // support it can be replaced by above templated getter.
105 18 std::shared_ptr<Buffer>& get(AttachSide side)
106 {
107
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
18 if (side == AttachSide::Left) {
108 2 return left;
109 }
110
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 12 times.
16 if (side == AttachSide::TopLeft) {
111 4 return topLeft;
112 }
113
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10 times.
12 if (side == AttachSide::Top) {
114 2 return top;
115 }
116
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
10 if (side == AttachSide::TopRight) {
117 2 return topRight;
118 }
119
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (side == AttachSide::Right) {
120 2 return right;
121 }
122
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (side == AttachSide::BottomRight) {
123 2 return bottomRight;
124 }
125
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (side == AttachSide::Bottom) {
126 2 return bottom;
127 }
128
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 assert(side == AttachSide::BottomLeft);
129 2 return bottomLeft;
130 18 }
131
132 template<OffsetSide side>
133 4 void setOffset(double _offset)
134 {
135 if constexpr (side == OffsetSide::Left) {
136 1 offset.setLeft(_offset);
137 } else if constexpr (side == OffsetSide::Top) {
138 1 offset.setTop(_offset);
139 } else if constexpr (side == OffsetSide::Right) {
140 1 offset.setRight(_offset);
141 } else {
142 static_assert(side == OffsetSide::Bottom);
143 1 offset.setBottom(_offset);
144 }
145 4 offsetIsSet = true;
146 4 }
147
148 template<AttachSide side>
149 16 void commit(State& pending)
150 {
151 16 auto& currentBuf = get<side>();
152 16 auto& pendingBuf = pending.get<side>();
153
154 16 currentBuf = pendingBuf;
155 16 pendingBuf.reset();
156 16 }
157
158 template<AttachSide side>
159 24 void unref()
160 {
161
8/16
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✗ Branch 15 not taken.
24 if (auto buf = get<side>()) {
162 buf.reset();
163 }
164 24 }
165
166 // TODO(romangg): unique_ptr?
167 8 std::shared_ptr<Buffer> left = nullptr;
168 8 std::shared_ptr<Buffer> topLeft = nullptr;
169 8 std::shared_ptr<Buffer> top = nullptr;
170 8 std::shared_ptr<Buffer> topRight = nullptr;
171 8 std::shared_ptr<Buffer> right = nullptr;
172 8 std::shared_ptr<Buffer> bottomRight = nullptr;
173 8 std::shared_ptr<Buffer> bottom = nullptr;
174 8 std::shared_ptr<Buffer> bottomLeft = nullptr;
175
176 QMarginsF offset;
177 8 bool offsetIsSet = false;
178 };
179 State current;
180 State pending;
181
182 private:
183 template<AttachSide side>
184 9 static void attachCallback([[maybe_unused]] wl_client* wlClient,
185 wl_resource* wlResource,
186 wl_resource* wlBuffer)
187 {
188 9 auto priv = get_handle(wlResource)->d_ptr;
189 9 priv->attach<side>(wlBuffer);
190 9 }
191
192 template<OffsetSide side>
193 4 static void offsetCallback([[maybe_unused]] wl_client* wlClient,
194 wl_resource* wlResource,
195 wl_fixed_t wlOffset)
196 {
197 4 auto priv = get_handle(wlResource)->d_ptr;
198 4 priv->pending.setOffset<side>(wl_fixed_to_double(wlOffset));
199 4 }
200
201 static void commitCallback(wl_client* client, wl_resource* resource);
202
203 template<AttachSide side>
204 9 void attach(wl_resource* wlBuffer)
205 {
206 9 auto display = client->display()->handle;
207 9 auto buffer = Buffer::get(display, wlBuffer);
208
209
8/16
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
9 attachConnect(side, buffer.get());
210
8/16
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
9 pending.get<side>() = buffer;
211 9 }
212
213 void attachConnect(AttachSide side, Buffer* buffer);
214 void commit();
215
216 static const struct org_kde_kwin_shadow_interface s_interface;
217 };
218
219 }
220