KWayland

keyboard.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 Martin Gräßlin <[email protected]>
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(k);
55  wl_keyboard_add_listener(keyboard, &s_listener, this);
56 }
57 
58 const wl_keyboard_listener Keyboard::Private::s_listener = {keymapCallback, enterCallback, leaveCallback, keyCallback, modifiersCallback, 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 
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(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, 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(modsDepressed, modsLatched, 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(charactersPerSecond, 0);
158  k->repeatInfo.delay = qMax(delay, 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 }
virtual void release(quint64 objid)
Wrapper for the wl_surface interface.
Definition: surface.h:43
virtual QVariant get(ScriptableExtension *callerPrincipal, quint64 objId, const QString &propName)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 03:56:21 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.