File indexing completed on 2024-11-10 04:56:14
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "mock_libinput.h" 0010 0011 #include "backends/libinput/device.h" 0012 #include "backends/libinput/events.h" 0013 0014 #include <QTest> 0015 0016 #include <linux/input.h> 0017 0018 Q_DECLARE_METATYPE(libinput_event_type) 0019 Q_DECLARE_METATYPE(libinput_button_state) 0020 0021 using namespace KWin::LibInput; 0022 using namespace std::literals; 0023 0024 class TestLibinputPointerEvent : public QObject 0025 { 0026 Q_OBJECT 0027 private Q_SLOTS: 0028 void init(); 0029 void cleanup(); 0030 0031 void testType_data(); 0032 void testType(); 0033 void testButton_data(); 0034 void testButton(); 0035 void testScrollWheel_data(); 0036 void testScrollWheel(); 0037 void testScrollFinger_data(); 0038 void testScrollFinger(); 0039 void testScrollContinuous_data(); 0040 void testScrollContinuous(); 0041 void testMotion(); 0042 void testAbsoluteMotion(); 0043 0044 private: 0045 libinput_device *m_nativeDevice = nullptr; 0046 Device *m_device = nullptr; 0047 }; 0048 0049 void TestLibinputPointerEvent::init() 0050 { 0051 m_nativeDevice = new libinput_device; 0052 m_nativeDevice->pointer = true; 0053 m_nativeDevice->deviceSize = QSizeF(12.5, 13.8); 0054 m_device = new Device(m_nativeDevice); 0055 } 0056 0057 void TestLibinputPointerEvent::cleanup() 0058 { 0059 delete m_device; 0060 m_device = nullptr; 0061 0062 delete m_nativeDevice; 0063 m_nativeDevice = nullptr; 0064 } 0065 0066 void TestLibinputPointerEvent::testType_data() 0067 { 0068 QTest::addColumn<libinput_event_type>("type"); 0069 0070 QTest::newRow("motion") << LIBINPUT_EVENT_POINTER_MOTION; 0071 QTest::newRow("absolute motion") << LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE; 0072 QTest::newRow("button") << LIBINPUT_EVENT_POINTER_BUTTON; 0073 QTest::newRow("scroll wheel") << LIBINPUT_EVENT_POINTER_SCROLL_WHEEL; 0074 QTest::newRow("scroll finger") << LIBINPUT_EVENT_POINTER_SCROLL_FINGER; 0075 QTest::newRow("scroll continuous") << LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS; 0076 } 0077 0078 void TestLibinputPointerEvent::testType() 0079 { 0080 // this test verifies the initialization of a PointerEvent and the parent Event class 0081 libinput_event_pointer *pointerEvent = new libinput_event_pointer; 0082 QFETCH(libinput_event_type, type); 0083 pointerEvent->type = type; 0084 pointerEvent->device = m_nativeDevice; 0085 0086 std::unique_ptr<Event> event(Event::create(pointerEvent)); 0087 // API of event 0088 QCOMPARE(event->type(), type); 0089 QCOMPARE(event->device(), m_device); 0090 QCOMPARE(event->nativeDevice(), m_nativeDevice); 0091 QCOMPARE((libinput_event *)(*event.get()), pointerEvent); 0092 // verify it's a pointer event 0093 QVERIFY(dynamic_cast<PointerEvent *>(event.get())); 0094 QCOMPARE((libinput_event_pointer *)(*dynamic_cast<PointerEvent *>(event.get())), pointerEvent); 0095 } 0096 0097 void TestLibinputPointerEvent::testButton_data() 0098 { 0099 QTest::addColumn<libinput_button_state>("buttonState"); 0100 QTest::addColumn<KWin::InputRedirection::PointerButtonState>("expectedButtonState"); 0101 QTest::addColumn<quint32>("button"); 0102 QTest::addColumn<quint32>("time"); 0103 0104 QTest::newRow("pressed") << LIBINPUT_BUTTON_STATE_RELEASED << KWin::InputRedirection::PointerButtonReleased << quint32(BTN_RIGHT) << 100u; 0105 QTest::newRow("released") << LIBINPUT_BUTTON_STATE_PRESSED << KWin::InputRedirection::PointerButtonPressed << quint32(BTN_LEFT) << 200u; 0106 } 0107 0108 void TestLibinputPointerEvent::testButton() 0109 { 0110 // this test verifies the button press/release 0111 libinput_event_pointer *pointerEvent = new libinput_event_pointer; 0112 pointerEvent->device = m_nativeDevice; 0113 pointerEvent->type = LIBINPUT_EVENT_POINTER_BUTTON; 0114 QFETCH(libinput_button_state, buttonState); 0115 pointerEvent->buttonState = buttonState; 0116 QFETCH(quint32, button); 0117 pointerEvent->button = button; 0118 QFETCH(quint32, time); 0119 pointerEvent->time = std::chrono::milliseconds(time); 0120 0121 std::unique_ptr<Event> event(Event::create(pointerEvent)); 0122 auto pe = dynamic_cast<PointerEvent *>(event.get()); 0123 QVERIFY(pe); 0124 QCOMPARE(pe->type(), LIBINPUT_EVENT_POINTER_BUTTON); 0125 QTEST(pe->buttonState(), "expectedButtonState"); 0126 QCOMPARE(pe->button(), button); 0127 QCOMPARE(pe->time(), pointerEvent->time); 0128 } 0129 0130 void TestLibinputPointerEvent::testScrollWheel_data() 0131 { 0132 QTest::addColumn<bool>("horizontal"); 0133 QTest::addColumn<bool>("vertical"); 0134 QTest::addColumn<QPointF>("value"); 0135 QTest::addColumn<QPoint>("valueV120"); 0136 QTest::addColumn<quint32>("time"); 0137 0138 QTest::newRow("wheel/horizontal") << true << false << QPointF(3.0, 0.0) << QPoint(120, 0) << 100u; 0139 QTest::newRow("wheel/vertical") << false << true << QPointF(0.0, 2.5) << QPoint(0, 120) << 200u; 0140 QTest::newRow("wheel/both") << true << true << QPointF(1.1, 4.2) << QPoint(120, 120) << 300u; 0141 } 0142 0143 void TestLibinputPointerEvent::testScrollWheel() 0144 { 0145 // this test verifies pointer axis functionality 0146 libinput_event_pointer *pointerEvent = new libinput_event_pointer; 0147 pointerEvent->device = m_nativeDevice; 0148 pointerEvent->type = LIBINPUT_EVENT_POINTER_SCROLL_WHEEL; 0149 QFETCH(bool, horizontal); 0150 QFETCH(bool, vertical); 0151 QFETCH(QPointF, value); 0152 QFETCH(QPoint, valueV120); 0153 QFETCH(quint32, time); 0154 pointerEvent->horizontalAxis = horizontal; 0155 pointerEvent->verticalAxis = vertical; 0156 pointerEvent->horizontalScrollValue = value.x(); 0157 pointerEvent->verticalScrollValue = value.y(); 0158 pointerEvent->horizontalScrollValueV120 = valueV120.x(); 0159 pointerEvent->verticalScrollValueV120 = valueV120.y(); 0160 pointerEvent->time = std::chrono::milliseconds(time); 0161 0162 std::unique_ptr<Event> event(Event::create(pointerEvent)); 0163 auto pe = dynamic_cast<PointerEvent *>(event.get()); 0164 QVERIFY(pe); 0165 QCOMPARE(pe->type(), LIBINPUT_EVENT_POINTER_SCROLL_WHEEL); 0166 QCOMPARE(pe->axis().contains(KWin::InputRedirection::PointerAxisHorizontal), horizontal); 0167 QCOMPARE(pe->axis().contains(KWin::InputRedirection::PointerAxisVertical), vertical); 0168 QCOMPARE(pe->scrollValue(KWin::InputRedirection::PointerAxisHorizontal), value.x()); 0169 QCOMPARE(pe->scrollValue(KWin::InputRedirection::PointerAxisVertical), value.y()); 0170 QCOMPARE(pe->scrollValueV120(KWin::InputRedirection::PointerAxisHorizontal), valueV120.x()); 0171 QCOMPARE(pe->scrollValueV120(KWin::InputRedirection::PointerAxisVertical), valueV120.y()); 0172 QCOMPARE(pe->time(), pointerEvent->time); 0173 } 0174 0175 void TestLibinputPointerEvent::testScrollFinger_data() 0176 { 0177 QTest::addColumn<bool>("horizontal"); 0178 QTest::addColumn<bool>("vertical"); 0179 QTest::addColumn<QPointF>("value"); 0180 QTest::addColumn<quint32>("time"); 0181 0182 QTest::newRow("finger/horizontal") << true << false << QPointF(3.0, 0.0) << 400u; 0183 QTest::newRow("stop finger/horizontal") << true << false << QPointF(0.0, 0.0) << 500u; 0184 QTest::newRow("finger/vertical") << false << true << QPointF(0.0, 2.5) << 600u; 0185 QTest::newRow("stop finger/vertical") << false << true << QPointF(0.0, 0.0) << 700u; 0186 QTest::newRow("finger/both") << true << true << QPointF(1.1, 4.2) << 800u; 0187 QTest::newRow("stop finger/both") << true << true << QPointF(0.0, 0.0) << 900u; 0188 } 0189 0190 void TestLibinputPointerEvent::testScrollFinger() 0191 { 0192 // this test verifies pointer axis functionality 0193 libinput_event_pointer *pointerEvent = new libinput_event_pointer; 0194 pointerEvent->device = m_nativeDevice; 0195 pointerEvent->type = LIBINPUT_EVENT_POINTER_SCROLL_FINGER; 0196 QFETCH(bool, horizontal); 0197 QFETCH(bool, vertical); 0198 QFETCH(QPointF, value); 0199 QFETCH(quint32, time); 0200 pointerEvent->horizontalAxis = horizontal; 0201 pointerEvent->verticalAxis = vertical; 0202 pointerEvent->horizontalScrollValue = value.x(); 0203 pointerEvent->verticalScrollValue = value.y(); 0204 pointerEvent->time = std::chrono::milliseconds(time); 0205 0206 std::unique_ptr<Event> event(Event::create(pointerEvent)); 0207 auto pe = dynamic_cast<PointerEvent *>(event.get()); 0208 QVERIFY(pe); 0209 QCOMPARE(pe->type(), LIBINPUT_EVENT_POINTER_SCROLL_FINGER); 0210 QCOMPARE(pe->axis().contains(KWin::InputRedirection::PointerAxisHorizontal), horizontal); 0211 QCOMPARE(pe->axis().contains(KWin::InputRedirection::PointerAxisVertical), vertical); 0212 QCOMPARE(pe->scrollValue(KWin::InputRedirection::PointerAxisHorizontal), value.x()); 0213 QCOMPARE(pe->scrollValue(KWin::InputRedirection::PointerAxisVertical), value.y()); 0214 QCOMPARE(pe->time(), pointerEvent->time); 0215 } 0216 0217 void TestLibinputPointerEvent::testScrollContinuous_data() 0218 { 0219 QTest::addColumn<bool>("horizontal"); 0220 QTest::addColumn<bool>("vertical"); 0221 QTest::addColumn<QPointF>("value"); 0222 QTest::addColumn<quint32>("time"); 0223 0224 QTest::newRow("continuous/horizontal") << true << false << QPointF(3.0, 0.0) << 1000u; 0225 QTest::newRow("continuous/vertical") << false << true << QPointF(0.0, 2.5) << 1100u; 0226 QTest::newRow("continuous/both") << true << true << QPointF(1.1, 4.2) << 1200u; 0227 } 0228 0229 void TestLibinputPointerEvent::testScrollContinuous() 0230 { 0231 // this test verifies pointer axis functionality 0232 libinput_event_pointer *pointerEvent = new libinput_event_pointer; 0233 pointerEvent->device = m_nativeDevice; 0234 pointerEvent->type = LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS; 0235 QFETCH(bool, horizontal); 0236 QFETCH(bool, vertical); 0237 QFETCH(QPointF, value); 0238 QFETCH(quint32, time); 0239 pointerEvent->horizontalAxis = horizontal; 0240 pointerEvent->verticalAxis = vertical; 0241 pointerEvent->horizontalScrollValue = value.x(); 0242 pointerEvent->verticalScrollValue = value.y(); 0243 pointerEvent->time = std::chrono::milliseconds(time); 0244 0245 std::unique_ptr<Event> event(Event::create(pointerEvent)); 0246 auto pe = dynamic_cast<PointerEvent *>(event.get()); 0247 QVERIFY(pe); 0248 QCOMPARE(pe->type(), LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS); 0249 QCOMPARE(pe->axis().contains(KWin::InputRedirection::PointerAxisHorizontal), horizontal); 0250 QCOMPARE(pe->axis().contains(KWin::InputRedirection::PointerAxisVertical), vertical); 0251 QCOMPARE(pe->scrollValue(KWin::InputRedirection::PointerAxisHorizontal), value.x()); 0252 QCOMPARE(pe->scrollValue(KWin::InputRedirection::PointerAxisVertical), value.y()); 0253 QCOMPARE(pe->time(), pointerEvent->time); 0254 } 0255 0256 void TestLibinputPointerEvent::testMotion() 0257 { 0258 // this test verifies pointer motion (delta) 0259 libinput_event_pointer *pointerEvent = new libinput_event_pointer; 0260 pointerEvent->device = m_nativeDevice; 0261 pointerEvent->type = LIBINPUT_EVENT_POINTER_MOTION; 0262 pointerEvent->delta = QPointF(2.1, 4.5); 0263 pointerEvent->time = 500ms; 0264 0265 std::unique_ptr<Event> event(Event::create(pointerEvent)); 0266 auto pe = dynamic_cast<PointerEvent *>(event.get()); 0267 QVERIFY(pe); 0268 QCOMPARE(pe->type(), LIBINPUT_EVENT_POINTER_MOTION); 0269 QCOMPARE(pe->time(), pointerEvent->time); 0270 QCOMPARE(pe->delta(), QPointF(2.1, 4.5)); 0271 } 0272 0273 void TestLibinputPointerEvent::testAbsoluteMotion() 0274 { 0275 // this test verifies absolute pointer motion 0276 libinput_event_pointer *pointerEvent = new libinput_event_pointer; 0277 pointerEvent->device = m_nativeDevice; 0278 pointerEvent->type = LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE; 0279 pointerEvent->absolutePos = QPointF(6.25, 6.9); 0280 pointerEvent->time = 500ms; 0281 0282 std::unique_ptr<Event> event(Event::create(pointerEvent)); 0283 auto pe = dynamic_cast<PointerEvent *>(event.get()); 0284 QVERIFY(pe); 0285 QCOMPARE(pe->type(), LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE); 0286 QCOMPARE(pe->time(), pointerEvent->time); 0287 QCOMPARE(pe->absolutePos(), QPointF(6.25, 6.9)); 0288 QCOMPARE(pe->absolutePos(QSize(1280, 1024)), QPointF(640, 512)); 0289 } 0290 0291 QTEST_GUILESS_MAIN(TestLibinputPointerEvent) 0292 #include "pointer_event_test.moc"