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 |