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 | #include "keyboard.h" |
7 | #include "surface.h" |
8 | #include "wayland_pointer_p.h" |
9 | #include <QPointer> |
10 | // wayland |
11 | #include <wayland-client-protocol.h> |
12 | |
13 | namespace KWayland |
14 | { |
15 | namespace Client |
16 | { |
17 | class Q_DECL_HIDDEN Keyboard::Private |
18 | { |
19 | public: |
20 | Private(Keyboard *q); |
21 | void setup(wl_keyboard *k); |
22 | |
23 | WaylandPointer<wl_keyboard, wl_keyboard_release> keyboard; |
24 | QPointer<Surface> enteredSurface; |
25 | |
26 | struct { |
27 | qint32 charactersPerSecond = 0; |
28 | qint32 delay = 0; |
29 | } repeatInfo; |
30 | |
31 | private: |
32 | void enter(uint32_t serial, wl_surface *surface, wl_array *keys); |
33 | void leave(uint32_t serial); |
34 | static void keymapCallback(void *data, wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size); |
35 | static void enterCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface, wl_array *keys); |
36 | static void leaveCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface); |
37 | static void keyCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state); |
38 | static void |
39 | modifiersCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t modsDepressed, uint32_t modsLatched, uint32_t modsLocked, uint32_t group); |
40 | static void repeatInfoCallback(void *data, wl_keyboard *keyboard, int32_t charactersPerSecond, int32_t delay); |
41 | Keyboard *q; |
42 | static const wl_keyboard_listener s_listener; |
43 | }; |
44 | |
45 | Keyboard::Private::Private(Keyboard *q) |
46 | : q(q) |
47 | { |
48 | } |
49 | |
50 | void Keyboard::Private::setup(wl_keyboard *k) |
51 | { |
52 | Q_ASSERT(k); |
53 | Q_ASSERT(!keyboard); |
54 | keyboard.setup(pointer: k); |
55 | wl_keyboard_add_listener(wl_keyboard: keyboard, listener: &s_listener, data: this); |
56 | } |
57 | |
58 | const wl_keyboard_listener Keyboard::Private::s_listener = {.keymap: keymapCallback, .enter: enterCallback, .leave: leaveCallback, .key: keyCallback, .modifiers: modifiersCallback, .repeat_info: repeatInfoCallback}; |
59 | |
60 | Keyboard::Keyboard(QObject *parent) |
61 | : QObject(parent) |
62 | , d(new Private(this)) |
63 | { |
64 | } |
65 | |
66 | Keyboard::~Keyboard() |
67 | { |
68 | release(); |
69 | } |
70 | |
71 | void Keyboard::release() |
72 | { |
73 | d->keyboard.release(); |
74 | } |
75 | |
76 | void Keyboard::destroy() |
77 | { |
78 | d->keyboard.destroy(); |
79 | } |
80 | |
81 | void Keyboard::setup(wl_keyboard *keyboard) |
82 | { |
83 | d->setup(keyboard); |
84 | } |
85 | |
86 | void Keyboard::Private::enterCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface, wl_array *keys) |
87 | { |
88 | auto k = reinterpret_cast<Private *>(data); |
89 | Q_ASSERT(k->keyboard == keyboard); |
90 | k->enter(serial, surface, keys); |
91 | } |
92 | |
93 | void Keyboard::Private::enter(uint32_t serial, wl_surface *surface, wl_array *keys) |
94 | { |
95 | Q_UNUSED(keys) |
96 | enteredSurface = Surface::get(native: surface); |
97 | Q_EMIT q->entered(serial); |
98 | } |
99 | |
100 | void Keyboard::Private::leaveCallback(void *data, wl_keyboard *keyboard, uint32_t serial, wl_surface *surface) |
101 | { |
102 | Q_UNUSED(surface) |
103 | auto k = reinterpret_cast<Private *>(data); |
104 | Q_ASSERT(k->keyboard == keyboard); |
105 | k->leave(serial); |
106 | } |
107 | |
108 | void Keyboard::Private::leave(uint32_t serial) |
109 | { |
110 | enteredSurface.clear(); |
111 | Q_EMIT q->left(serial); |
112 | } |
113 | |
114 | void Keyboard::Private::keyCallback(void *data, wl_keyboard *keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) |
115 | { |
116 | Q_UNUSED(serial) |
117 | auto k = reinterpret_cast<Keyboard::Private *>(data); |
118 | Q_ASSERT(k->keyboard == keyboard); |
119 | auto toState = [state] { |
120 | if (state == WL_KEYBOARD_KEY_STATE_RELEASED) { |
121 | return KeyState::Released; |
122 | } else { |
123 | return KeyState::Pressed; |
124 | } |
125 | }; |
126 | Q_EMIT k->q->keyChanged(key, state: toState(), time); |
127 | } |
128 | |
129 | void Keyboard::Private::keymapCallback(void *data, wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) |
130 | { |
131 | auto k = reinterpret_cast<Keyboard::Private *>(data); |
132 | Q_ASSERT(k->keyboard == keyboard); |
133 | if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { |
134 | return; |
135 | } |
136 | Q_EMIT k->q->keymapChanged(fd, size); |
137 | } |
138 | |
139 | void Keyboard::Private::modifiersCallback(void *data, |
140 | wl_keyboard *keyboard, |
141 | uint32_t serial, |
142 | uint32_t modsDepressed, |
143 | uint32_t modsLatched, |
144 | uint32_t modsLocked, |
145 | uint32_t group) |
146 | { |
147 | Q_UNUSED(serial) |
148 | auto k = reinterpret_cast<Keyboard::Private *>(data); |
149 | Q_ASSERT(k->keyboard == keyboard); |
150 | Q_EMIT k->q->modifiersChanged(depressed: modsDepressed, latched: modsLatched, locked: modsLocked, group); |
151 | } |
152 | |
153 | void Keyboard::Private::repeatInfoCallback(void *data, wl_keyboard *keyboard, int32_t charactersPerSecond, int32_t delay) |
154 | { |
155 | auto k = reinterpret_cast<Keyboard::Private *>(data); |
156 | Q_ASSERT(k->keyboard == keyboard); |
157 | k->repeatInfo.charactersPerSecond = qMax(a: charactersPerSecond, b: 0); |
158 | k->repeatInfo.delay = qMax(a: delay, b: 0); |
159 | Q_EMIT k->q->keyRepeatChanged(); |
160 | } |
161 | |
162 | Surface *Keyboard::enteredSurface() |
163 | { |
164 | return d->enteredSurface.data(); |
165 | } |
166 | |
167 | Surface *Keyboard::enteredSurface() const |
168 | { |
169 | return d->enteredSurface.data(); |
170 | } |
171 | |
172 | bool Keyboard::isValid() const |
173 | { |
174 | return d->keyboard.isValid(); |
175 | } |
176 | |
177 | bool Keyboard::isKeyRepeatEnabled() const |
178 | { |
179 | return d->repeatInfo.charactersPerSecond > 0; |
180 | } |
181 | |
182 | qint32 Keyboard::keyRepeatDelay() const |
183 | { |
184 | return d->repeatInfo.delay; |
185 | } |
186 | |
187 | qint32 Keyboard::keyRepeatRate() const |
188 | { |
189 | return d->repeatInfo.charactersPerSecond; |
190 | } |
191 | |
192 | Keyboard::operator wl_keyboard *() |
193 | { |
194 | return d->keyboard; |
195 | } |
196 | |
197 | Keyboard::operator wl_keyboard *() const |
198 | { |
199 | return d->keyboard; |
200 | } |
201 | |
202 | } |
203 | } |
204 | |
205 | #include "moc_keyboard.cpp" |
206 | |