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
13namespace KWayland
14{
15namespace Client
16{
17class Q_DECL_HIDDEN Keyboard::Private
18{
19public:
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
31private:
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
45Keyboard::Private::Private(Keyboard *q)
46 : q(q)
47{
48}
49
50void 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
58const wl_keyboard_listener Keyboard::Private::s_listener = {.keymap: keymapCallback, .enter: enterCallback, .leave: leaveCallback, .key: keyCallback, .modifiers: modifiersCallback, .repeat_info: repeatInfoCallback};
59
60Keyboard::Keyboard(QObject *parent)
61 : QObject(parent)
62 , d(new Private(this))
63{
64}
65
66Keyboard::~Keyboard()
67{
68 release();
69}
70
71void Keyboard::release()
72{
73 d->keyboard.release();
74}
75
76void Keyboard::destroy()
77{
78 d->keyboard.destroy();
79}
80
81void Keyboard::setup(wl_keyboard *keyboard)
82{
83 d->setup(keyboard);
84}
85
86void 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
93void 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
100void 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
108void Keyboard::Private::leave(uint32_t serial)
109{
110 enteredSurface.clear();
111 Q_EMIT q->left(serial);
112}
113
114void 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
129void 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
139void 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
153void 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
162Surface *Keyboard::enteredSurface()
163{
164 return d->enteredSurface.data();
165}
166
167Surface *Keyboard::enteredSurface() const
168{
169 return d->enteredSurface.data();
170}
171
172bool Keyboard::isValid() const
173{
174 return d->keyboard.isValid();
175}
176
177bool Keyboard::isKeyRepeatEnabled() const
178{
179 return d->repeatInfo.charactersPerSecond > 0;
180}
181
182qint32 Keyboard::keyRepeatDelay() const
183{
184 return d->repeatInfo.delay;
185}
186
187qint32 Keyboard::keyRepeatRate() const
188{
189 return d->repeatInfo.charactersPerSecond;
190}
191
192Keyboard::operator wl_keyboard *()
193{
194 return d->keyboard;
195}
196
197Keyboard::operator wl_keyboard *() const
198{
199 return d->keyboard;
200}
201
202}
203}
204
205#include "moc_keyboard.cpp"
206

source code of kwayland/src/client/keyboard.cpp