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