File indexing completed on 2024-04-14 04:51:48
0001 /** 0002 * SPDX-FileCopyrightText: 2017 Holger Kaelberer <holger.k@elberer.de> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "remotekeyboardplugin.h" 0008 #include "plugin_remotekeyboard_debug.h" 0009 #include <KPluginFactory> 0010 #include <QDebug> 0011 #include <QKeySequence> 0012 #include <QString> 0013 #include <QVariantMap> 0014 0015 K_PLUGIN_CLASS_WITH_JSON(RemoteKeyboardPlugin, "kdeconnect_remotekeyboard.json") 0016 0017 // Mapping of Qt::Key to internal codes, corresponds to the mapping in mousepadplugin 0018 QMap<int, int> specialKeysMap = { 0019 // 0, // Invalid 0020 {Qt::Key_Backspace, 1}, 0021 {Qt::Key_Tab, 2}, 0022 // XK_Linefeed, // 3 0023 {Qt::Key_Left, 4}, 0024 {Qt::Key_Up, 5}, 0025 {Qt::Key_Right, 6}, 0026 {Qt::Key_Down, 7}, 0027 {Qt::Key_PageUp, 8}, 0028 {Qt::Key_PageDown, 9}, 0029 {Qt::Key_Home, 10}, 0030 {Qt::Key_End, 11}, 0031 {Qt::Key_Return, 12}, 0032 {Qt::Key_Enter, 12}, 0033 {Qt::Key_Delete, 13}, 0034 {Qt::Key_Escape, 14}, 0035 {Qt::Key_SysReq, 15}, 0036 {Qt::Key_ScrollLock, 16}, 0037 // 0, // 17 0038 // 0, // 18 0039 // 0, // 19 0040 // 0, // 20 0041 {Qt::Key_F1, 21}, 0042 {Qt::Key_F2, 22}, 0043 {Qt::Key_F3, 23}, 0044 {Qt::Key_F4, 24}, 0045 {Qt::Key_F5, 25}, 0046 {Qt::Key_F6, 26}, 0047 {Qt::Key_F7, 27}, 0048 {Qt::Key_F8, 28}, 0049 {Qt::Key_F9, 29}, 0050 {Qt::Key_F10, 30}, 0051 {Qt::Key_F11, 31}, 0052 {Qt::Key_F12, 32}, 0053 }; 0054 0055 RemoteKeyboardPlugin::RemoteKeyboardPlugin(QObject *parent, const QVariantList &args) 0056 : KdeConnectPlugin(parent, args) 0057 , m_remoteState(false) 0058 { 0059 } 0060 0061 void RemoteKeyboardPlugin::receivePacket(const NetworkPacket &np) 0062 { 0063 if (np.type() == PACKET_TYPE_MOUSEPAD_ECHO) { 0064 if (!np.has(QStringLiteral("isAck")) || !np.has(QStringLiteral("key"))) { 0065 qCWarning(KDECONNECT_PLUGIN_REMOTEKEYBOARD) << "Invalid packet of type" << PACKET_TYPE_MOUSEPAD_ECHO; 0066 return; 0067 } 0068 // qCWarning(KDECONNECT_PLUGIN_REMOTEKEYBOARD) << "Received keypress" << np; 0069 Q_EMIT keyPressReceived(np.get<QString>(QStringLiteral("key")), 0070 np.get<int>(QStringLiteral("specialKey"), 0), 0071 np.get<int>(QStringLiteral("shift"), false), 0072 np.get<int>(QStringLiteral("ctrl"), false), 0073 np.get<int>(QStringLiteral("alt"), 0)); 0074 } else if (np.type() == PACKET_TYPE_MOUSEPAD_KEYBOARDSTATE) { 0075 // qCWarning(KDECONNECT_PLUGIN_REMOTEKEYBOARD) << "Received keyboardstate" << np; 0076 if (m_remoteState != np.get<bool>(QStringLiteral("state"))) { 0077 m_remoteState = np.get<bool>(QStringLiteral("state")); 0078 Q_EMIT remoteStateChanged(m_remoteState); 0079 } 0080 } 0081 } 0082 0083 void RemoteKeyboardPlugin::sendKeyPress(const QString &key, int specialKey, bool shift, bool ctrl, bool alt, bool sendAck) const 0084 { 0085 NetworkPacket np(PACKET_TYPE_MOUSEPAD_REQUEST, 0086 {{QStringLiteral("key"), key}, 0087 {QStringLiteral("specialKey"), specialKey}, 0088 {QStringLiteral("shift"), shift}, 0089 {QStringLiteral("ctrl"), ctrl}, 0090 {QStringLiteral("alt"), alt}, 0091 {QStringLiteral("sendAck"), sendAck}}); 0092 sendPacket(np); 0093 } 0094 0095 void RemoteKeyboardPlugin::sendQKeyEvent(const QVariantMap &keyEvent, bool sendAck) const 0096 { 0097 if (!keyEvent.contains(QStringLiteral("key"))) { 0098 return; 0099 } 0100 const int key = keyEvent.value(QStringLiteral("key")).toInt(); 0101 int k = translateQtKey(key); 0102 int modifiers = keyEvent.value(QStringLiteral("modifiers")).toInt(); 0103 0104 // Qt will be calling xkb_state_key_get_utf8 to create this string. 0105 // As documented, it will be giving us weird strings with Ctrl combinations: 0106 // https://xkbcommon.org/doc/current/group__keysyms.html 0107 // Instead, just use QKeySequence to tell us which key that is and move on 0108 QString text = keyEvent.value(QStringLiteral("text")).toString(); 0109 if (!text.isEmpty() && !text[0].isLetterOrNumber() && text != QLatin1String(" ")) { 0110 text = QKeySequence(key).toString().toLower(); 0111 } 0112 0113 sendKeyPress(text, k, modifiers & Qt::ShiftModifier, modifiers & Qt::ControlModifier, modifiers & Qt::AltModifier, sendAck); 0114 } 0115 0116 int RemoteKeyboardPlugin::translateQtKey(int qtKey) const 0117 { 0118 return specialKeysMap.value(qtKey, 0); 0119 } 0120 0121 QString RemoteKeyboardPlugin::dbusPath() const 0122 { 0123 return QLatin1String("/modules/kdeconnect/devices/%1/remotekeyboard").arg(device()->id()); 0124 } 0125 0126 #include "moc_remotekeyboardplugin.cpp" 0127 #include "remotekeyboardplugin.moc"