1 /*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 // Qt
7 #include <QtTest>
8 // WaylandServer
9 #include "../../src/server/display.h"
10 #include "../../src/server/keyboard_interface.h"
11 #include "../../src/server/pointer_interface.h"
12 #include "../../src/server/seat_interface.h"
13
14 using namespace KWaylandServer;
15
16 class TestWaylandServerSeat : public QObject
17 {
18 Q_OBJECT
19 private Q_SLOTS:
20 void testCapabilities();
21 void testName();
22 void testPointerButton();
23 void testPointerPos();
24 void testRepeatInfo();
25 void testMultiple();
26 };
27
28 static const QString s_socketName = QStringLiteral("kwin-wayland-server-seat-test-0");
29
testCapabilities()30 void TestWaylandServerSeat::testCapabilities()
31 {
32 Display display;
33 display.addSocketName(s_socketName);
34 display.start();
35 SeatInterface *seat = new SeatInterface(&display);
36 QVERIFY(!seat->hasKeyboard());
37 QVERIFY(!seat->hasPointer());
38 QVERIFY(!seat->hasTouch());
39
40 QSignalSpy keyboardSpy(seat, SIGNAL(hasKeyboardChanged(bool)));
41 QVERIFY(keyboardSpy.isValid());
42 seat->setHasKeyboard(true);
43 QCOMPARE(keyboardSpy.count(), 1);
44 QVERIFY(keyboardSpy.last().first().toBool());
45 QVERIFY(seat->hasKeyboard());
46 seat->setHasKeyboard(false);
47 QCOMPARE(keyboardSpy.count(), 2);
48 QVERIFY(!keyboardSpy.last().first().toBool());
49 QVERIFY(!seat->hasKeyboard());
50 seat->setHasKeyboard(false);
51 QCOMPARE(keyboardSpy.count(), 2);
52
53 QSignalSpy pointerSpy(seat, SIGNAL(hasPointerChanged(bool)));
54 QVERIFY(pointerSpy.isValid());
55 seat->setHasPointer(true);
56 QCOMPARE(pointerSpy.count(), 1);
57 QVERIFY(pointerSpy.last().first().toBool());
58 QVERIFY(seat->hasPointer());
59 seat->setHasPointer(false);
60 QCOMPARE(pointerSpy.count(), 2);
61 QVERIFY(!pointerSpy.last().first().toBool());
62 QVERIFY(!seat->hasPointer());
63 seat->setHasPointer(false);
64 QCOMPARE(pointerSpy.count(), 2);
65
66 QSignalSpy touchSpy(seat, SIGNAL(hasTouchChanged(bool)));
67 QVERIFY(touchSpy.isValid());
68 seat->setHasTouch(true);
69 QCOMPARE(touchSpy.count(), 1);
70 QVERIFY(touchSpy.last().first().toBool());
71 QVERIFY(seat->hasTouch());
72 seat->setHasTouch(false);
73 QCOMPARE(touchSpy.count(), 2);
74 QVERIFY(!touchSpy.last().first().toBool());
75 QVERIFY(!seat->hasTouch());
76 seat->setHasTouch(false);
77 QCOMPARE(touchSpy.count(), 2);
78 }
79
testName()80 void TestWaylandServerSeat::testName()
81 {
82 Display display;
83 display.addSocketName(s_socketName);
84 display.start();
85 SeatInterface *seat = new SeatInterface(&display);
86 QCOMPARE(seat->name(), QString());
87
88 QSignalSpy nameSpy(seat, SIGNAL(nameChanged(QString)));
89 QVERIFY(nameSpy.isValid());
90 const QString name = QStringLiteral("foobar");
91 seat->setName(name);
92 QCOMPARE(seat->name(), name);
93 QCOMPARE(nameSpy.count(), 1);
94 QCOMPARE(nameSpy.first().first().toString(), name);
95 seat->setName(name);
96 QCOMPARE(nameSpy.count(), 1);
97 }
98
testPointerButton()99 void TestWaylandServerSeat::testPointerButton()
100 {
101 Display display;
102 display.addSocketName(s_socketName);
103 display.start();
104 SeatInterface *seat = new SeatInterface(&display);
105 seat->setHasPointer(true);
106
107 // no button pressed yet, should be released and no serial
108 QVERIFY(!seat->isPointerButtonPressed(0));
109 QVERIFY(!seat->isPointerButtonPressed(1));
110 QCOMPARE(seat->pointerButtonSerial(0), quint32(0));
111 QCOMPARE(seat->pointerButtonSerial(1), quint32(0));
112
113 // mark the button as pressed
114 seat->notifyPointerButton(0, PointerButtonState::Pressed);
115 seat->notifyPointerFrame();
116 QVERIFY(seat->isPointerButtonPressed(0));
117 QCOMPARE(seat->pointerButtonSerial(0), display.serial());
118
119 // other button should still be unpressed
120 QVERIFY(!seat->isPointerButtonPressed(1));
121 QCOMPARE(seat->pointerButtonSerial(1), quint32(0));
122
123 // release it again
124 seat->notifyPointerButton(0, PointerButtonState::Released);
125 seat->notifyPointerFrame();
126 QVERIFY(!seat->isPointerButtonPressed(0));
127 QCOMPARE(seat->pointerButtonSerial(0), display.serial());
128 }
129
testPointerPos()130 void TestWaylandServerSeat::testPointerPos()
131 {
132 Display display;
133 display.addSocketName(s_socketName);
134 display.start();
135 SeatInterface *seat = new SeatInterface(&display);
136 seat->setHasPointer(true);
137 QSignalSpy seatPosSpy(seat, SIGNAL(pointerPosChanged(QPointF)));
138 QVERIFY(seatPosSpy.isValid());
139
140 QCOMPARE(seat->pointerPos(), QPointF());
141
142 seat->notifyPointerMotion(QPointF(10, 15));
143 seat->notifyPointerFrame();
144 QCOMPARE(seat->pointerPos(), QPointF(10, 15));
145 QCOMPARE(seatPosSpy.count(), 1);
146 QCOMPARE(seatPosSpy.first().first().toPointF(), QPointF(10, 15));
147
148 seat->notifyPointerMotion(QPointF(10, 15));
149 seat->notifyPointerFrame();
150 QCOMPARE(seatPosSpy.count(), 1);
151
152 seat->notifyPointerMotion(QPointF(5, 7));
153 seat->notifyPointerFrame();
154 QCOMPARE(seat->pointerPos(), QPointF(5, 7));
155 QCOMPARE(seatPosSpy.count(), 2);
156 QCOMPARE(seatPosSpy.first().first().toPointF(), QPointF(10, 15));
157 QCOMPARE(seatPosSpy.last().first().toPointF(), QPointF(5, 7));
158 }
159
testRepeatInfo()160 void TestWaylandServerSeat::testRepeatInfo()
161 {
162 Display display;
163 display.addSocketName(s_socketName);
164 display.start();
165 SeatInterface *seat = new SeatInterface(&display);
166 seat->setHasKeyboard(true);
167 QCOMPARE(seat->keyboard()->keyRepeatRate(), 0);
168 QCOMPARE(seat->keyboard()->keyRepeatDelay(), 0);
169 seat->keyboard()->setRepeatInfo(25, 660);
170 QCOMPARE(seat->keyboard()->keyRepeatRate(), 25);
171 QCOMPARE(seat->keyboard()->keyRepeatDelay(), 660);
172 // setting negative values should result in 0
173 seat->keyboard()->setRepeatInfo(-25, -660);
174 QCOMPARE(seat->keyboard()->keyRepeatRate(), 0);
175 QCOMPARE(seat->keyboard()->keyRepeatDelay(), 0);
176 }
177
testMultiple()178 void TestWaylandServerSeat::testMultiple()
179 {
180 Display display;
181 display.addSocketName(s_socketName);
182 display.start();
183 QVERIFY(display.seats().isEmpty());
184 SeatInterface *seat1 = new SeatInterface(&display);
185 QCOMPARE(display.seats().count(), 1);
186 QCOMPARE(display.seats().at(0), seat1);
187 SeatInterface *seat2 = new SeatInterface(&display);
188 QCOMPARE(display.seats().count(), 2);
189 QCOMPARE(display.seats().at(0), seat1);
190 QCOMPARE(display.seats().at(1), seat2);
191 SeatInterface *seat3 = new SeatInterface(&display);
192 QCOMPARE(display.seats().count(), 3);
193 QCOMPARE(display.seats().at(0), seat1);
194 QCOMPARE(display.seats().at(1), seat2);
195 QCOMPARE(display.seats().at(2), seat3);
196
197 delete seat3;
198 QCOMPARE(display.seats().count(), 2);
199 QCOMPARE(display.seats().at(0), seat1);
200 QCOMPARE(display.seats().at(1), seat2);
201
202 delete seat2;
203 QCOMPARE(display.seats().count(), 1);
204 QCOMPARE(display.seats().at(0), seat1);
205
206 delete seat1;
207 QCOMPARE(display.seats().count(), 0);
208 }
209
210 QTEST_GUILESS_MAIN(TestWaylandServerSeat)
211 #include "test_seat.moc"
212