KWayland

keyboard_interface.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_interface.h"
7 #include "display.h"
8 #include "keyboard_interface_p.h"
9 #include "seat_interface.h"
10 #include "surface_interface.h"
11 // Qt
12 #include <QTemporaryFile>
13 #include <QVector>
14 // Wayland
15 #include <wayland-server.h>
16 
17 #include <unistd.h>
18 
19 namespace KWayland
20 {
21 namespace Server
22 {
23 KeyboardInterface::Private::Private(SeatInterface *s, wl_resource *parentResource, KeyboardInterface *q)
24  : Resource::Private(q, s, parentResource, &wl_keyboard_interface, &s_interface)
25  , seat(s)
26 {
27 }
28 
29 void KeyboardInterface::Private::focusChildSurface(const QPointer<SurfaceInterface> &childSurface, quint32 serial)
30 {
31  if (focusedChildSurface == childSurface) {
32  return;
33  }
34  sendLeave(focusedChildSurface.data(), serial);
35  focusedChildSurface = childSurface;
36  sendEnter(focusedChildSurface.data(), serial);
37 }
38 
39 void KeyboardInterface::Private::sendLeave(SurfaceInterface *surface, quint32 serial)
40 {
41  if (surface && resource && surface->resource()) {
42  wl_keyboard_send_leave(resource, serial, surface->resource());
43  }
44 }
45 
46 void KeyboardInterface::Private::sendEnter(SurfaceInterface *surface, quint32 serial)
47 {
48  wl_array keys;
49  wl_array_init(&keys);
50  const auto states = seat->pressedKeys();
51  for (auto it = states.constBegin(); it != states.constEnd(); ++it) {
52  uint32_t *k = reinterpret_cast<uint32_t *>(wl_array_add(&keys, sizeof(uint32_t)));
53  *k = *it;
54  }
55  wl_keyboard_send_enter(resource, serial, surface->resource(), &keys);
56  wl_array_release(&keys);
57 
58  sendModifiers();
59 }
60 
61 #ifndef K_DOXYGEN
62 const struct wl_keyboard_interface KeyboardInterface::Private::s_interface {
63  resourceDestroyedCallback
64 };
65 #endif
66 
67 KeyboardInterface::KeyboardInterface(SeatInterface *parent, wl_resource *parentResource)
68  : Resource(new Private(parent, parentResource, this))
69 {
70 }
71 
72 KeyboardInterface::~KeyboardInterface() = default;
73 
74 void KeyboardInterface::setKeymap(int fd, quint32 size)
75 {
76  Q_D();
77  d->sendKeymap(fd, size);
78 }
79 
80 void KeyboardInterface::setKeymap(const QByteArray &content)
81 {
83  if (!tmp->open()) {
84  return;
85  }
86  unlink(tmp->fileName().toUtf8().constData());
87  if (!tmp->resize(content.size())) {
88  return;
89  }
90  uchar *address = tmp->map(0, content.size());
91  if (!address) {
92  return;
93  }
94  if (qstrncpy(reinterpret_cast<char *>(address), content.constData(), content.size() + 1) == nullptr) {
95  return;
96  }
97  tmp->unmap(address);
98  Q_D();
99  d->sendKeymap(tmp->handle(), content.size());
100  d->keymap.swap(tmp);
101 }
102 
103 void KeyboardInterface::Private::sendKeymap(int fd, quint32 size)
104 {
105  if (!resource) {
106  return;
107  }
108  wl_keyboard_send_keymap(resource, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, size);
109 }
110 
111 void KeyboardInterface::Private::sendModifiers(quint32 depressed, quint32 latched, quint32 locked, quint32 group, quint32 serial)
112 {
113  if (!resource) {
114  return;
115  }
116  wl_keyboard_send_modifiers(resource, serial, depressed, latched, locked, group);
117 }
118 
119 void KeyboardInterface::Private::sendModifiers()
120 {
121  sendModifiers(seat->depressedModifiers(), seat->latchedModifiers(), seat->lockedModifiers(), seat->groupModifiers(), seat->lastModifiersSerial());
122 }
123 
124 void KeyboardInterface::setFocusedSurface(SurfaceInterface *surface, quint32 serial)
125 {
126  Q_D();
127  d->sendLeave(d->focusedChildSurface, serial);
128  disconnect(d->destroyConnection);
129  d->focusedChildSurface.clear();
130  d->focusedSurface = surface;
131  if (!d->focusedSurface) {
132  return;
133  }
134  d->destroyConnection = connect(d->focusedSurface, &Resource::aboutToBeUnbound, this, [this] {
135  Q_D();
136  if (d->resource) {
137  wl_keyboard_send_leave(d->resource, d->global->display()->nextSerial(), d->focusedSurface->resource());
138  }
139  d->focusedSurface = nullptr;
140  d->focusedChildSurface.clear();
141  });
142  d->focusedChildSurface = QPointer<SurfaceInterface>(surface);
143 
144  d->sendEnter(d->focusedSurface, serial);
145  d->client->flush();
146 }
147 
148 void KeyboardInterface::keyPressed(quint32 key, quint32 serial)
149 {
150  Q_D();
151  if (!d->resource) {
152  return;
153  }
154  Q_ASSERT(d->focusedSurface);
155  wl_keyboard_send_key(d->resource, serial, d->seat->timestamp(), key, WL_KEYBOARD_KEY_STATE_PRESSED);
156 }
157 
158 void KeyboardInterface::keyReleased(quint32 key, quint32 serial)
159 {
160  Q_D();
161  if (!d->resource) {
162  return;
163  }
164  Q_ASSERT(d->focusedSurface);
165  wl_keyboard_send_key(d->resource, serial, d->seat->timestamp(), key, WL_KEYBOARD_KEY_STATE_RELEASED);
166 }
167 
168 void KeyboardInterface::updateModifiers(quint32 depressed, quint32 latched, quint32 locked, quint32 group, quint32 serial)
169 {
170  Q_D();
171  Q_ASSERT(d->focusedSurface);
172  d->sendModifiers(depressed, latched, locked, group, serial);
173 }
174 
175 void KeyboardInterface::repeatInfo(qint32 charactersPerSecond, qint32 delay)
176 {
177  Q_D();
178  if (!d->resource) {
179  return;
180  }
181  if (wl_resource_get_version(d->resource) < WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) {
182  // only supported since version 4
183  return;
184  }
185  wl_keyboard_send_repeat_info(d->resource, charactersPerSecond, delay);
186 }
187 
188 SurfaceInterface *KeyboardInterface::focusedSurface() const
189 {
190  Q_D();
191  return d->focusedSurface;
192 }
193 
194 KeyboardInterface::Private *KeyboardInterface::d_func() const
195 {
196  return reinterpret_cast<Private *>(d.data());
197 }
198 
199 }
200 }
PostalAddress address(const QVariant &location)
const char * constData() const const
int size() const const
Resource representing a wl_surface.
Q_D(Todo)
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.