Warning, file /frameworks/kwindowsystem/autotests/kkeyserver_x11_unittest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE libraries 0002 SPDX-FileCopyrightText: 2017 David Faure <faure@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "kkeyserver_x11.h" 0008 #include <QTest> 0009 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0010 #include <private/qtx11extras_p.h> 0011 #else 0012 #include <QX11Info> 0013 #endif 0014 0015 #include <X11/keysym.h> 0016 #include <xcb/xcb_keysyms.h> 0017 0018 class KKeyServerTest : public QObject 0019 { 0020 Q_OBJECT 0021 private Q_SLOTS: 0022 0023 void initTestCase() 0024 { 0025 m_keySymbols = xcb_key_symbols_alloc(QX11Info::connection()); 0026 0027 // This makes me wonder why we have KKeyServer::modXShift :-) 0028 QCOMPARE(XCB_MOD_MASK_SHIFT, xcb_mod_mask_t(KKeyServer::modXShift())); 0029 } 0030 0031 void cleanupTestCase() 0032 { 0033 if (m_keySymbols) { 0034 xcb_key_symbols_free(m_keySymbols); 0035 } 0036 } 0037 0038 void keyQtToSymX_data() 0039 { 0040 QTest::addColumn<int>("keyQt"); 0041 QTest::addColumn<uint>("modX"); 0042 QTest::addColumn<uint>("additionalState"); // set to XCB_MOD_MASK_SHIFT if shift would indeed be pressed for this shortcut 0043 QTest::addColumn<int>("keySymX"); 0044 0045 const uint numLock = KKeyServer::modXNumLock(); 0046 0047 // clang-format off 0048 // Before adding any testcase below, check what `kcmshell5 keys` records, to make sure it matches 0049 QTest::newRow("a") << int(Qt::Key_A) << uint(0) << numLock << XK_A; 0050 QTest::newRow("CTRL_F1") << int(Qt::ControlModifier|Qt::Key_F1) << KKeyServer::modXCtrl() << numLock << XK_F1; 0051 QTest::newRow("CTRL_1") << int(Qt::ControlModifier|Qt::Key_1) << KKeyServer::modXCtrl() << numLock << XK_1; 0052 QTest::newRow("CTRL_keypad_1") << int(Qt::ControlModifier|Qt::KeypadModifier|Qt::Key_1) << KKeyServer::modXCtrl() << numLock << XK_KP_1; 0053 QTest::newRow("CTRL_keypad_slash") << int(Qt::ControlModifier|Qt::KeypadModifier|Qt::Key_Slash) << KKeyServer::modXCtrl() << numLock << XK_KP_Divide; 0054 QTest::newRow("CTRL_SHIFT_keypad_end") << int(Qt::ControlModifier|Qt::ShiftModifier|Qt::KeypadModifier|Qt::Key_End) << (KKeyServer::modXCtrl()|KKeyServer::modXShift()) << numLock << XK_KP_End; 0055 QTest::newRow("CTRL_keypad_end_no_numlock") << int(Qt::ControlModifier|Qt::KeypadModifier|Qt::Key_End) << (KKeyServer::modXCtrl()) << uint(0) << XK_KP_End; 0056 QTest::newRow("CTRL_ampersand") << int(Qt::ControlModifier|Qt::Key_Ampersand) << KKeyServer::modXCtrl() << uint(XCB_MOD_MASK_SHIFT|numLock) << XK_ampersand; 0057 QTest::newRow("ALT_SHIFT_right") << int(Qt::AltModifier|Qt::ShiftModifier|Qt::Key_Right) << (KKeyServer::modXAlt() | KKeyServer::modXShift()) << numLock << XK_Right; 0058 QTest::newRow("CTRL_SHIFT_right") << int(Qt::ControlModifier|Qt::ShiftModifier|Qt::Key_Right) << (KKeyServer::modXCtrl() | KKeyServer::modXShift()) << numLock << XK_Right; 0059 QTest::newRow("META_SHIFT_print") << int(Qt::MetaModifier|Qt::ShiftModifier|Qt::Key_Print) << (KKeyServer::modXMeta() | KKeyServer::modXShift()) << numLock << XK_Print; 0060 QTest::newRow("ALT_Tab") << int(Qt::AltModifier|Qt::Key_Tab) << (KKeyServer::modXAlt()) << numLock << XK_Tab; 0061 QTest::newRow("ALT_Shift_Tab") << int(Qt::AltModifier|Qt::ShiftModifier|Qt::Key_Tab) << (KKeyServer::modXAlt() | KKeyServer::modXShift()) << numLock << XK_Tab; 0062 // clang-format on 0063 } 0064 0065 void keyQtToSymX() 0066 { 0067 QFETCH(int, keyQt); 0068 QFETCH(uint, modX); 0069 QFETCH(int, keySymX); 0070 int sym; 0071 QVERIFY(KKeyServer::keyQtToSymX(keyQt, &sym)); 0072 QCOMPARE(QString::number(sym, 16), QString::number(keySymX, 16)); 0073 uint mod; 0074 QVERIFY(KKeyServer::keyQtToModX(keyQt, &mod)); 0075 QCOMPARE(mod, modX); 0076 } 0077 0078 void symXToKeyQt_data() 0079 { 0080 keyQtToSymX_data(); 0081 } 0082 0083 void symXToKeyQt() 0084 { 0085 QFETCH(int, keyQt); 0086 QFETCH(uint, modX); 0087 QFETCH(int, keySymX); 0088 int keyCodeQt; 0089 0090 // qDebug() << "modX=" << modX << "keySymX=0x" << QString::number(keySymX, 16) << "keyQt=0x" << QString::number(keyQt, 16); 0091 0092 QVERIFY(KKeyServer::symXModXToKeyQt(keySymX, modX, &keyCodeQt)); 0093 QCOMPARE(keyCodeQt, keyQt); 0094 } 0095 0096 void decodeXcbEvent_data() 0097 { 0098 keyQtToSymX_data(); 0099 } 0100 0101 void decodeXcbEvent() 0102 { 0103 QFETCH(int, keyQt); 0104 QFETCH(uint, modX); 0105 QFETCH(uint, additionalState); 0106 QFETCH(int, keySymX); 0107 0108 xcb_keycode_t *keyCodes = xcb_key_symbols_get_keycode(m_keySymbols, keySymX); 0109 QVERIFY(keyCodes); 0110 const xcb_keycode_t keyCodeX = keyCodes[0]; 0111 QVERIFY(keyCodeX != XCB_NO_SYMBOL); 0112 free(keyCodes); 0113 0114 xcb_key_press_event_t event{XCB_KEY_PRESS, 0115 keyCodeX, 0116 0, 0117 0 /*time*/, 0118 0 /*root*/, 0119 0 /*event*/, 0120 0 /*child*/, 0121 0 /*root_x*/, 0122 0 /*root_y*/, 0123 0 /*event_x*/, 0124 0 /*event_y*/, 0125 uint16_t(modX | additionalState), 0126 0 /*same_screen*/, 0127 0 /*pad0*/}; 0128 0129 int decodedKeyQt; 0130 const bool ok = KKeyServer::xcbKeyPressEventToQt(&event, &decodedKeyQt); 0131 QVERIFY(ok); 0132 if (decodedKeyQt != keyQt) { 0133 qDebug() << "given modX=" << modX << "keySymX=0x" << QString::number(keySymX, 16) << "I expected keyQt=0x" << QString::number(keyQt, 16) 0134 << QKeySequence(keyQt).toString() << "got" << QString::number(decodedKeyQt, 16) << QKeySequence(decodedKeyQt).toString(); 0135 } 0136 QCOMPARE(decodedKeyQt, keyQt); 0137 } 0138 0139 private: 0140 xcb_key_symbols_t *m_keySymbols; 0141 }; 0142 0143 QTEST_MAIN(KKeyServerTest) 0144 0145 #include "kkeyserver_x11_unittest.moc"