File indexing completed on 2024-05-19 16:35:20
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "display.h" 0007 #include "keyboard_interface_p.h" 0008 #include "seat_interface.h" 0009 #include "seat_interface_p.h" 0010 #include "surface_interface.h" 0011 #include "utils/common.h" 0012 // Qt 0013 #include <QVector> 0014 0015 #include <unistd.h> 0016 0017 namespace KWaylandServer 0018 { 0019 KeyboardInterfacePrivate::KeyboardInterfacePrivate(SeatInterface *s) 0020 : seat(s) 0021 { 0022 } 0023 0024 void KeyboardInterfacePrivate::keyboard_release(Resource *resource) 0025 { 0026 wl_resource_destroy(resource->handle); 0027 } 0028 0029 void KeyboardInterfacePrivate::keyboard_bind_resource(Resource *resource) 0030 { 0031 const ClientConnection *focusedClient = focusedSurface ? focusedSurface->client() : nullptr; 0032 0033 if (resource->version() >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { 0034 send_repeat_info(resource->handle, keyRepeat.charactersPerSecond, keyRepeat.delay); 0035 } 0036 if (!keymap.isNull()) { 0037 sendKeymap(resource); 0038 } 0039 0040 if (focusedClient && focusedClient->client() == resource->client()) { 0041 const QVector<quint32> keys = pressedKeys(); 0042 const QByteArray keysData = QByteArray::fromRawData(reinterpret_cast<const char *>(keys.data()), sizeof(quint32) * keys.count()); 0043 const quint32 serial = seat->display()->nextSerial(); 0044 0045 send_enter(resource->handle, serial, focusedSurface->resource(), keysData); 0046 send_modifiers(resource->handle, serial, modifiers.depressed, modifiers.latched, modifiers.locked, modifiers.group); 0047 } 0048 } 0049 0050 QList<KeyboardInterfacePrivate::Resource *> KeyboardInterfacePrivate::keyboardsForClient(ClientConnection *client) const 0051 { 0052 return resourceMap().values(client->client()); 0053 } 0054 0055 void KeyboardInterfacePrivate::sendLeave(SurfaceInterface *surface, quint32 serial) 0056 { 0057 const QList<Resource *> keyboards = keyboardsForClient(surface->client()); 0058 for (Resource *keyboardResource : keyboards) { 0059 send_leave(keyboardResource->handle, serial, surface->resource()); 0060 } 0061 } 0062 0063 void KeyboardInterfacePrivate::sendEnter(SurfaceInterface *surface, quint32 serial) 0064 { 0065 const auto states = pressedKeys(); 0066 QByteArray data = QByteArray::fromRawData(reinterpret_cast<const char *>(states.constData()), sizeof(quint32) * states.size()); 0067 0068 const QList<Resource *> keyboards = keyboardsForClient(surface->client()); 0069 for (Resource *keyboardResource : keyboards) { 0070 send_enter(keyboardResource->handle, serial, surface->resource(), data); 0071 } 0072 } 0073 0074 void KeyboardInterfacePrivate::sendKeymap(Resource *resource) 0075 { 0076 // From version 7 on, keymaps must be mapped privately, so that 0077 // we can seal the fd and reuse it between clients. 0078 if (resource->version() >= 7 && sharedKeymapFile.effectiveFlags().testFlag(KWin::RamFile::Flag::SealWrite)) { 0079 send_keymap(resource->handle, keymap_format::keymap_format_xkb_v1, sharedKeymapFile.fd(), sharedKeymapFile.size()); 0080 // otherwise give each client its own unsealed copy. 0081 } else { 0082 KWin::RamFile keymapFile("kwin-xkb-keymap", keymap.constData(), keymap.size() + 1); // Include QByteArray null-terminator. 0083 send_keymap(resource->handle, keymap_format::keymap_format_xkb_v1, keymapFile.fd(), keymapFile.size()); 0084 } 0085 } 0086 0087 void KeyboardInterface::setKeymap(const QByteArray &content) 0088 { 0089 if (content.isNull()) { 0090 return; 0091 } 0092 0093 d->keymap = content; 0094 // +1 to include QByteArray null terminator. 0095 d->sharedKeymapFile = KWin::RamFile("kwin-xkb-keymap-shared", content.constData(), content.size() + 1, KWin::RamFile::Flag::SealWrite); 0096 0097 const auto keyboardResources = d->resourceMap(); 0098 for (KeyboardInterfacePrivate::Resource *resource : keyboardResources) { 0099 d->sendKeymap(resource); 0100 } 0101 } 0102 0103 void KeyboardInterfacePrivate::sendModifiers(quint32 depressed, quint32 latched, quint32 locked, quint32 group, quint32 serial) 0104 { 0105 const QList<Resource *> keyboards = keyboardsForClient(focusedSurface->client()); 0106 for (Resource *keyboardResource : keyboards) { 0107 send_modifiers(keyboardResource->handle, serial, depressed, latched, locked, group); 0108 } 0109 } 0110 0111 bool KeyboardInterfacePrivate::updateKey(quint32 key, KeyboardKeyState state) 0112 { 0113 auto it = states.find(key); 0114 if (it == states.end()) { 0115 states.insert(key, state); 0116 return true; 0117 } 0118 if (it.value() == state) { 0119 return false; 0120 } 0121 it.value() = state; 0122 return true; 0123 } 0124 0125 KeyboardInterface::KeyboardInterface(SeatInterface *seat) 0126 : d(new KeyboardInterfacePrivate(seat)) 0127 { 0128 } 0129 0130 KeyboardInterface::~KeyboardInterface() = default; 0131 0132 void KeyboardInterfacePrivate::sendModifiers() 0133 { 0134 sendModifiers(modifiers.depressed, modifiers.latched, modifiers.locked, modifiers.group, modifiers.serial); 0135 } 0136 0137 void KeyboardInterface::setFocusedSurface(SurfaceInterface *surface, quint32 serial) 0138 { 0139 if (d->focusedSurface == surface) { 0140 return; 0141 } 0142 0143 if (d->focusedSurface) { 0144 d->sendLeave(d->focusedSurface, serial); 0145 disconnect(d->destroyConnection); 0146 } 0147 0148 d->focusedSurface = surface; 0149 if (!d->focusedSurface) { 0150 return; 0151 } 0152 d->destroyConnection = connect(d->focusedSurface, &SurfaceInterface::aboutToBeDestroyed, this, [this] { 0153 d->sendLeave(d->focusedSurface, d->seat->display()->nextSerial()); 0154 d->focusedSurface = nullptr; 0155 }); 0156 0157 d->sendEnter(d->focusedSurface, serial); 0158 d->sendModifiers(); 0159 } 0160 0161 QVector<quint32> KeyboardInterfacePrivate::pressedKeys() const 0162 { 0163 QVector<quint32> keys; 0164 for (auto it = states.constBegin(); it != states.constEnd(); ++it) { 0165 if (it.value() == KeyboardKeyState::Pressed) { 0166 keys << it.key(); 0167 } 0168 } 0169 return keys; 0170 } 0171 0172 void KeyboardInterface::sendKey(quint32 key, KeyboardKeyState state, ClientConnection *client) 0173 { 0174 const QList<KeyboardInterfacePrivate::Resource *> keyboards = d->keyboardsForClient(client); 0175 const quint32 serial = d->seat->display()->nextSerial(); 0176 for (KeyboardInterfacePrivate::Resource *keyboardResource : keyboards) { 0177 d->send_key(keyboardResource->handle, serial, d->seat->timestamp().count(), key, quint32(state)); 0178 } 0179 } 0180 0181 void KeyboardInterface::sendKey(quint32 key, KeyboardKeyState state) 0182 { 0183 if (!d->updateKey(key, state)) { 0184 return; 0185 } 0186 0187 if (!d->focusedSurface) { 0188 return; 0189 } 0190 0191 sendKey(key, state, d->focusedSurface->client()); 0192 } 0193 0194 void KeyboardInterface::sendModifiers(quint32 depressed, quint32 latched, quint32 locked, quint32 group) 0195 { 0196 bool changed = false; 0197 if (d->modifiers.depressed != depressed) { 0198 d->modifiers.depressed = depressed; 0199 changed = true; 0200 } 0201 if (d->modifiers.latched != latched) { 0202 d->modifiers.latched = latched; 0203 changed = true; 0204 } 0205 if (d->modifiers.locked != locked) { 0206 d->modifiers.locked = locked; 0207 changed = true; 0208 } 0209 if (d->modifiers.group != group) { 0210 d->modifiers.group = group; 0211 changed = true; 0212 } 0213 if (!changed || !d->focusedSurface) { 0214 return; 0215 } 0216 0217 d->modifiers.serial = d->seat->display()->nextSerial(); 0218 d->sendModifiers(depressed, latched, locked, group, d->modifiers.serial); 0219 } 0220 0221 void KeyboardInterface::setRepeatInfo(qint32 charactersPerSecond, qint32 delay) 0222 { 0223 d->keyRepeat.charactersPerSecond = std::max(charactersPerSecond, 0); 0224 d->keyRepeat.delay = std::max(delay, 0); 0225 const auto keyboards = d->resourceMap(); 0226 for (KeyboardInterfacePrivate::Resource *keyboardResource : keyboards) { 0227 if (keyboardResource->version() >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) { 0228 d->send_repeat_info(keyboardResource->handle, d->keyRepeat.charactersPerSecond, d->keyRepeat.delay); 0229 } 0230 } 0231 } 0232 0233 SurfaceInterface *KeyboardInterface::focusedSurface() const 0234 { 0235 return d->focusedSurface; 0236 } 0237 0238 qint32 KeyboardInterface::keyRepeatDelay() const 0239 { 0240 return d->keyRepeat.delay; 0241 } 0242 0243 qint32 KeyboardInterface::keyRepeatRate() const 0244 { 0245 return d->keyRepeat.charactersPerSecond; 0246 } 0247 0248 }