GCC Code Coverage Report


Directory: ./
File: server/keyboard.cpp
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 77 78 98.7%
Branches: 19 34 55.9%

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 "keyboard.h"
21 #include "keyboard_p.h"
22
23 #include "client.h"
24 #include "display.h"
25 #include "seat.h"
26 #include "surface.h"
27 #include "surface_p.h"
28
29 #include <QVector>
30 #include <cstring>
31
32 #include <wayland-server.h>
33
34 namespace Wrapland::Server
35 {
36
37
2/4
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
98 Keyboard::Private::Private(Client* client,
38 uint32_t version,
39 uint32_t id,
40 Seat* _seat,
41 Keyboard* q_ptr)
42 49 : Wayland::Resource<Keyboard>(client, version, id, &wl_keyboard_interface, &s_interface, q_ptr)
43 49 , seat(_seat)
44 49 , q_ptr{q_ptr}
45 49 {
46 49 }
47
48 const struct wl_keyboard_interface Keyboard::Private::s_interface {
49 destroyCallback,
50 };
51
52 71 void Keyboard::Private::sendLeave(quint32 serial, Surface* surface)
53 {
54
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 58 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
71 if (surface && surface->d_ptr->resource) {
55 13 send<wl_keyboard_send_leave>(serial, surface->d_ptr->resource);
56 13 }
57 71 }
58
59 58 void Keyboard::Private::sendEnter(quint32 serial, Surface* surface)
60 {
61 wl_array keys;
62 58 wl_array_init(&keys);
63 58 auto const& states = seat->keyboards().pressed_keys();
64
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 3 times.
61 for (auto const btn : states) {
65
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 auto key = static_cast<uint32_t*>(wl_array_add(&keys, sizeof(uint32_t)));
66 3 *key = btn;
67 }
68
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 send<wl_keyboard_send_enter>(serial, surface->d_ptr->resource, &keys);
69
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 wl_array_release(&keys);
70
71
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 sendModifiers();
72 58 }
73 49
74 2 void Keyboard::Private::sendKeymap(int fd, quint32 size)
75 {
76 2 send<wl_keyboard_send_keymap>(WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, size);
77 51 }
78
79 59 void Keyboard::Private::sendModifiers(quint32 serial,
80 quint32 depressed,
81 quint32 latched,
82 quint32 locked,
83 quint32 group)
84 {
85 59 send<wl_keyboard_send_modifiers>(serial, depressed, latched, locked, group);
86 59 }
87
88 58 void Keyboard::Private::sendModifiers()
89 {
90 58 auto const mods = seat->keyboards().get_modifiers();
91 58 sendModifiers(mods.serial, mods.depressed, mods.latched, mods.locked, mods.group);
92 58 }
93
94 49 Keyboard::Keyboard(Client* client, uint32_t version, uint32_t id, Seat* seat)
95 49 : QObject(nullptr)
96
2/4
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 , d_ptr(new Private(client, version, id, seat, this))
97 49 {
98
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
95 connect(client, &Client::disconnected, this, [this] { disconnect(d_ptr->destroyConnection); });
99 49 }
100
101 2 void Keyboard::setKeymap(char const* content)
102 {
103 2 auto tmpf = std::tmpfile();
104
105
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (auto rc = std::fputs(content, tmpf); rc < 0) {
106 qCWarning(WRAPLAND_SERVER, "Failed to set keyboard keymap with %d.", rc);
107 // TODO(romangg): Handle error by closing file here and returning?
108 }
109
110 2 std::rewind(tmpf);
111 2 d_ptr->sendKeymap(fileno(tmpf), strlen(content));
112 2 d_ptr->keymap = file_wrap(tmpf);
113 2 d_ptr->needs_keymap_update = false;
114 2 }
115
116 69 void Keyboard::setFocusedSurface(quint32 serial, Surface* surface)
117 {
118 69 d_ptr->sendLeave(serial, d_ptr->focusedSurface);
119 69 disconnect(d_ptr->destroyConnection);
120 69 d_ptr->focusedSurface = surface;
121
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 58 times.
69 if (!d_ptr->focusedSurface) {
122 11 return;
123 }
124 58 d_ptr->destroyConnection = connect(
125 60 d_ptr->focusedSurface, &Surface::resourceDestroyed, this, [this] {
126 2 d_ptr->sendLeave(d_ptr->client->display()->handle->nextSerial(), d_ptr->focusedSurface);
127 2 d_ptr->focusedSurface = nullptr;
128 2 });
129
130 58 d_ptr->sendEnter(serial, d_ptr->focusedSurface);
131 58 d_ptr->client->flush();
132 69 }
133
134 10 void Keyboard::key(uint32_t serial, uint32_t key, key_state state)
135 {
136
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 Q_ASSERT(d_ptr->focusedSurface);
137 20 d_ptr->send<wl_keyboard_send_key>(serial,
138 10 d_ptr->seat->timestamp(),
139 key,
140 10 state == key_state::pressed ? WL_KEYBOARD_KEY_STATE_PRESSED
141 : WL_KEYBOARD_KEY_STATE_RELEASED);
142 10 }
143
144 1 void Keyboard::updateModifiers(quint32 serial,
145 quint32 depressed,
146 quint32 latched,
147 quint32 locked,
148 quint32 group)
149 {
150
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 Q_ASSERT(d_ptr->focusedSurface);
151 1 d_ptr->sendModifiers(serial, depressed, latched, locked, group);
152 1 }
153
154 50 void Keyboard::repeatInfo(qint32 charactersPerSecond, qint32 delay)
155 {
156 50 d_ptr->send<wl_keyboard_send_repeat_info, WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION>(
157 charactersPerSecond, delay);
158 50 }
159
160 3 Surface* Keyboard::focusedSurface() const
161 {
162 3 return d_ptr->focusedSurface;
163 }
164
165 64 Client* Keyboard::client() const
166 {
167 64 return d_ptr->client->handle;
168 }
169
170 }
171