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

KDE's Doxygen guidelines are available online.