GCC Code Coverage Report


Directory: ./
File: server/seat.cpp
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 127 138 92.0%
Branches: 30 56 53.6%

Line Branch Exec Source
1 /********************************************************************
2 Copyright © 2020 Roman Gilg <subdiff@gmail.com>
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 #include "seat.h"
21 #include "seat_p.h"
22
23 #include "client.h"
24 #include "data_device.h"
25 #include "data_source.h"
26 #include "display.h"
27 #include "primary_selection.h"
28 #include "surface.h"
29
30 #include <config-wrapland.h>
31 #include <cstdint>
32
33 #ifndef WL_SEAT_NAME_SINCE_VERSION
34 #define WL_SEAT_NAME_SINCE_VERSION 2
35 #endif
36
37 namespace Wrapland::Server
38 {
39
40 927 Seat::Private::Private(Seat* q_ptr, Display* display)
41 309 : SeatGlobal(q_ptr, display, &wl_seat_interface, &s_interface)
42
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 , drags{q_ptr}
43
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 , data_devices{q_ptr}
44
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 , primary_selection_devices{q_ptr}
45
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 , text_inputs{q_ptr}
46 309 , q_ptr{q_ptr}
47 309 {
48
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 309 times.
309 display->globals.seats.push_back(q_ptr);
49 309 }
50
51 618 Seat::Private::~Private()
52 618 {
53
3/4
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 300 times.
309 if (display()) {
54
2/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 remove_all(display()->handle->globals.seats, q_ptr);
55 9 }
56 618 }
57
58 const struct wl_seat_interface Seat::Private::s_interface = {
59 cb<getPointerCallback>,
60 cb<getKeyboardCallback>,
61 cb<getTouchCallback>,
62 resourceDestroyCallback,
63 };
64
65 309 Seat::Seat(Display* display)
66
2/4
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 309 times.
✗ Branch 3 not taken.
309 : d_ptr(new Private(this, display))
67 309 {
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 309 times.
309 d_ptr->create();
69 309 }
70
71 618 Seat::~Seat() = default;
72
73 278 void Seat::Private::bindInit(SeatBind* bind)
74 {
75 278 send<wl_seat_send_capabilities>(bind, getCapabilities());
76 278 send<wl_seat_send_name, WL_SEAT_NAME_SINCE_VERSION>(bind, name.c_str());
77 278 }
78
79 59 void Seat::Private::sendName()
80 {
81 59 send<wl_seat_send_name, WL_SEAT_NAME_SINCE_VERSION>(name.c_str());
82 368 }
83
84 721 uint32_t Seat::Private::getCapabilities() const
85 {
86 721 uint32_t capabilities = 0;
87
2/2
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 322 times.
1030 if (pointers) {
88 322 capabilities |= WL_SEAT_CAPABILITY_POINTER;
89 322 }
90
2/2
✓ Branch 0 taken 191 times.
✓ Branch 1 taken 530 times.
721 if (keyboards) {
91 530 capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
92 530 }
93
2/2
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 221 times.
721 if (touches) {
94 221 capabilities |= WL_SEAT_CAPABILITY_TOUCH;
95 221 }
96 721 return capabilities;
97 309 }
98
99 443 void Seat::Private::sendCapabilities()
100 {
101 443 send<wl_seat_send_capabilities>(getCapabilities());
102 443 }
103
104 194 void Seat::setHasKeyboard(bool has)
105 {
106 194 d_ptr->set_capability(WL_SEAT_CAPABILITY_KEYBOARD, d_ptr->keyboards, has);
107 194 }
108
109 146 void Seat::setHasPointer(bool has)
110 {
111 146 d_ptr->set_capability(WL_SEAT_CAPABILITY_POINTER, d_ptr->pointers, has);
112 146 }
113
114 117 void Seat::setHasTouch(bool has)
115 {
116 117 d_ptr->set_capability(WL_SEAT_CAPABILITY_TOUCH, d_ptr->touches, has);
117 117 }
118
119 228 pointer_pool& Seat::pointers() const
120 {
121
1/2
✓ Branch 0 taken 228 times.
✗ Branch 1 not taken.
228 assert(hasPointer());
122
123 // We already check with the assert.
124 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
125 228 return *d_ptr->pointers;
126 }
127
128 160 keyboard_pool& Seat::keyboards() const
129 {
130
1/2
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
160 assert(hasKeyboard());
131
132 // We already check with the assert.
133 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
134 160 return *d_ptr->keyboards;
135 }
136
137 10 touch_pool& Seat::touches() const
138 {
139
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 assert(hasTouch());
140
141 // We already check with the assert.
142 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
143 10 return *d_ptr->touches;
144 }
145
146 349 text_input_pool& Seat::text_inputs() const
147 {
148 349 return d_ptr->text_inputs;
149 }
150
151 242 drag_pool& Seat::drags() const
152 {
153 242 return d_ptr->drags;
154 }
155
156 59 void Seat::setName(std::string const& name)
157 {
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (d_ptr->name == name) {
159 return;
160 }
161 59 d_ptr->name = name;
162 59 d_ptr->sendName();
163 59 }
164
165 65 void Seat::Private::getPointerCallback(SeatBind* bind, uint32_t id)
166 {
167 65 auto priv = bind->global()->handle->d_ptr.get();
168 65 auto& manager = priv->pointers;
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65 times.
65 if (!manager) {
170 // If we have no pointer capability we ignore the created resource.
171 if (!(priv->prior_caps & WL_SEAT_CAPABILITY_POINTER)) {
172 bind->post_error(WL_SEAT_ERROR_MISSING_CAPABILITY,
173 "Seat never had the pointer capability");
174 }
175 return;
176 }
177 65 manager.value().create_device(bind->client->handle, bind->version, id);
178 65 }
179
180 49 void Seat::Private::getKeyboardCallback(SeatBind* bind, uint32_t id)
181 {
182 49 auto priv = bind->global()->handle->d_ptr.get();
183 49 auto& manager = priv->keyboards;
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
49 if (!manager) {
185 // If we have no keyboard capability we ignore the created resource.
186 if (!(priv->prior_caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
187 bind->post_error(WL_SEAT_ERROR_MISSING_CAPABILITY,
188 "Seat never had the keyboard capability");
189 }
190 return;
191 }
192 49 manager.value().create_device(bind->client->handle, bind->version, id);
193 49 }
194
195 12 void Seat::Private::getTouchCallback(SeatBind* bind, uint32_t id)
196 {
197 12 auto priv = bind->global()->handle->d_ptr.get();
198 12 auto& manager = priv->touches;
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 if (!manager) {
200 // If we have no touch capability we ignore the created resource.
201 if (!(priv->prior_caps & WL_SEAT_CAPABILITY_TOUCH)) {
202 bind->post_error(WL_SEAT_ERROR_MISSING_CAPABILITY,
203 "Seat never had the touch capability");
204 }
205 return;
206 }
207 12 manager.value().create_device(bind->client->handle, bind->version, id);
208 12 }
209
210 2 std::string Seat::name() const
211 {
212 2 return d_ptr->name;
213 }
214
215 246 bool Seat::hasPointer() const
216 {
217 246 return d_ptr->pointers.has_value();
218 }
219
220 344 bool Seat::hasKeyboard() const
221 {
222 344 return d_ptr->keyboards.has_value();
223 }
224
225 20 bool Seat::hasTouch() const
226 {
227 20 return d_ptr->touches.has_value();
228 }
229
230 131 uint32_t Seat::timestamp() const
231 {
232 131 return d_ptr->timestamp;
233 }
234
235 141 void Seat::setTimestamp(uint32_t time)
236 {
237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (d_ptr->timestamp == time) {
238 return;
239 }
240 141 d_ptr->timestamp = time;
241 141 Q_EMIT timestampChanged(time);
242 141 }
243
244 113 void Seat::setFocusedKeyboardSurface(Surface* surface)
245 {
246
1/2
✓ Branch 0 taken 113 times.
✗ Branch 1 not taken.
113 assert(hasKeyboard());
247
248 // We already check with the assert.
249 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
250 113 auto& keys = d_ptr->keyboards.value();
251
252
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 1 times.
113 if (surface == keys.get_focus().surface) {
253 1 return;
254 }
255
256 // Data sharing devices receive a potential selection directly before keyboard enter.
257 112 d_ptr->data_devices.set_focused_surface(surface);
258 112 d_ptr->primary_selection_devices.set_focused_surface(surface);
259
260 112 keys.set_focused_surface(surface);
261
262 // Focused text input surface follows keyboard.
263 112 d_ptr->text_inputs.set_focused_surface(surface);
264 113 }
265
266 176 input_method_v2* Seat::get_input_method_v2() const
267 {
268 176 return d_ptr->input_method;
269 }
270
271 13 data_source* Seat::selection() const
272 {
273 13 return d_ptr->data_devices.focus.source;
274 }
275
276 10 void Seat::setSelection(data_source* source)
277 {
278 10 d_ptr->data_devices.set_selection(source);
279 10 }
280
281 3 primary_selection_source* Seat::primarySelection() const
282 {
283 3 return d_ptr->primary_selection_devices.focus.source;
284 }
285
286 2 void Seat::setPrimarySelection(primary_selection_source* source)
287 {
288 2 d_ptr->primary_selection_devices.set_selection(source);
289 2 }
290
291 }
292