KWin
Loading...
Searching...
No Matches
fakeinputbackend.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "fakeinputbackend.h"
8#include "fakeinputdevice.h"
9#include "wayland/display.h"
10
11#include "wayland/qwayland-server-fake-input.h"
12
13namespace KWin
14{
15
16static const quint32 s_version = 5;
17
18class FakeInputBackendPrivate : public QtWaylandServer::org_kde_kwin_fake_input
19{
20public:
22
23 FakeInputDevice *findDevice(Resource *resource);
24 std::chrono::microseconds currentTime() const;
25
28 std::map<Resource *, std::unique_ptr<FakeInputDevice>> devices;
29 static QList<quint32> touchIds;
30
31protected:
32 void org_kde_kwin_fake_input_bind_resource(Resource *resource) override;
33 void org_kde_kwin_fake_input_destroy_resource(Resource *resource) override;
34 void org_kde_kwin_fake_input_authenticate(Resource *resource, const QString &application, const QString &reason) override;
35 void org_kde_kwin_fake_input_pointer_motion(Resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y) override;
36 void org_kde_kwin_fake_input_button(Resource *resource, uint32_t button, uint32_t state) override;
37 void org_kde_kwin_fake_input_axis(Resource *resource, uint32_t axis, wl_fixed_t value) override;
38 void org_kde_kwin_fake_input_touch_down(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) override;
39 void org_kde_kwin_fake_input_touch_motion(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) override;
40 void org_kde_kwin_fake_input_touch_up(Resource *resource, uint32_t id) override;
41 void org_kde_kwin_fake_input_touch_cancel(Resource *resource) override;
42 void org_kde_kwin_fake_input_touch_frame(Resource *resource) override;
43 void org_kde_kwin_fake_input_pointer_motion_absolute(Resource *resource, wl_fixed_t x, wl_fixed_t y) override;
44 void org_kde_kwin_fake_input_keyboard_key(Resource *resource, uint32_t button, uint32_t state) override;
45 void org_kde_kwin_fake_input_destroy(Resource *resource) override;
46};
47
48QList<quint32> FakeInputBackendPrivate::touchIds = QList<quint32>();
49
51 : q(q)
52 , display(display)
53{
54}
55
57{
58 auto device = new FakeInputDevice(q);
59 devices[resource] = std::unique_ptr<FakeInputDevice>(device);
60 Q_EMIT q->deviceAdded(device);
61}
62
64{
65 wl_resource_destroy(resource->handle);
66}
67
69{
70 auto it = devices.find(resource);
71 if (it != devices.end()) {
72 const auto [resource, device] = std::move(*it);
73 devices.erase(it);
74 Q_EMIT q->deviceRemoved(device.get());
75 }
76}
77
79{
80 return devices[resource].get();
81}
82
83std::chrono::microseconds FakeInputBackendPrivate::currentTime() const
84{
85 return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch());
86}
87
88void FakeInputBackendPrivate::org_kde_kwin_fake_input_authenticate(Resource *resource, const QString &application, const QString &reason)
89{
90 FakeInputDevice *device = findDevice(resource);
91 if (device) {
92 // TODO: make secure
93 device->setAuthenticated(true);
94 }
95}
96
97void FakeInputBackendPrivate::org_kde_kwin_fake_input_pointer_motion(Resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y)
98{
99 FakeInputDevice *device = findDevice(resource);
100 if (!device->isAuthenticated()) {
101 return;
102 }
103 const QPointF delta(wl_fixed_to_double(delta_x), wl_fixed_to_double(delta_y));
104
105 Q_EMIT device->pointerMotion(delta, delta, currentTime(), device);
106 Q_EMIT device->pointerFrame(device);
107}
108
109void FakeInputBackendPrivate::org_kde_kwin_fake_input_button(Resource *resource, uint32_t button, uint32_t state)
110{
111 FakeInputDevice *device = findDevice(resource);
112 if (!device->isAuthenticated()) {
113 return;
114 }
115
117 switch (state) {
118 case WL_POINTER_BUTTON_STATE_PRESSED:
120 break;
121 case WL_POINTER_BUTTON_STATE_RELEASED:
123 break;
124 default:
125 return;
126 }
127
128 Q_EMIT device->pointerButtonChanged(button, nativeState, currentTime(), device);
129 Q_EMIT device->pointerFrame(device);
130}
131
132void FakeInputBackendPrivate::org_kde_kwin_fake_input_axis(Resource *resource, uint32_t axis, wl_fixed_t value)
133{
134 FakeInputDevice *device = findDevice(resource);
135 if (!device->isAuthenticated()) {
136 return;
137 }
138
140 switch (axis) {
141 case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
143 break;
144
145 case WL_POINTER_AXIS_VERTICAL_SCROLL:
147 break;
148
149 default:
150 return;
151 }
152
153 Q_EMIT device->pointerAxisChanged(nativeAxis, wl_fixed_to_double(value), 0, InputRedirection::PointerAxisSourceUnknown, currentTime(), device);
154 Q_EMIT device->pointerFrame(device);
155}
156
157void FakeInputBackendPrivate::org_kde_kwin_fake_input_touch_down(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y)
158{
159 FakeInputDevice *device = findDevice(resource);
160 if (!device->isAuthenticated()) {
161 return;
162 }
163 if (touchIds.contains(id)) {
164 return;
165 }
166 touchIds << id;
167 Q_EMIT device->touchDown(id, QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), currentTime(), device);
168}
169
170void FakeInputBackendPrivate::org_kde_kwin_fake_input_touch_motion(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y)
171{
172 FakeInputDevice *device = findDevice(resource);
173 if (!device->isAuthenticated()) {
174 return;
175 }
176 if (!touchIds.contains(id)) {
177 return;
178 }
179 Q_EMIT device->touchMotion(id, QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), currentTime(), device);
180}
181
183{
184 FakeInputDevice *device = findDevice(resource);
185 if (!device->isAuthenticated()) {
186 return;
187 }
188 if (!touchIds.contains(id)) {
189 return;
190 }
191 touchIds.removeOne(id);
192 Q_EMIT device->touchUp(id, currentTime(), device);
193}
194
196{
197 FakeInputDevice *device = findDevice(resource);
198 if (!device->isAuthenticated()) {
199 return;
200 }
201 touchIds.clear();
202 Q_EMIT device->touchCanceled(device);
203}
204
206{
207 FakeInputDevice *device = findDevice(resource);
208 if (!device->isAuthenticated()) {
209 return;
210 }
211 Q_EMIT device->touchFrame(device);
212}
213
214void FakeInputBackendPrivate::org_kde_kwin_fake_input_pointer_motion_absolute(Resource *resource, wl_fixed_t x, wl_fixed_t y)
215{
216 FakeInputDevice *device = findDevice(resource);
217 if (!device->isAuthenticated()) {
218 return;
219 }
220
221 Q_EMIT device->pointerMotionAbsolute(QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)), currentTime(), device);
222 Q_EMIT device->pointerFrame(device);
223}
224
225void FakeInputBackendPrivate::org_kde_kwin_fake_input_keyboard_key(Resource *resource, uint32_t button, uint32_t state)
226{
227 FakeInputDevice *device = findDevice(resource);
228 if (!device->isAuthenticated()) {
229 return;
230 }
231
233 switch (state) {
234 case WL_KEYBOARD_KEY_STATE_PRESSED:
236 break;
237
238 case WL_KEYBOARD_KEY_STATE_RELEASED:
240 break;
241
242 default:
243 return;
244 }
245
246 Q_EMIT device->keyChanged(button, nativeState, currentTime(), device);
247}
248
250 : d(std::make_unique<FakeInputBackendPrivate>(this, display))
251{
252}
253
255
257{
258 d->init(*d->display, s_version);
259}
260
261} // namespace KWin
262
263#include "moc_fakeinputbackend.cpp"
Class holding the Wayland server display loop.
Definition display.h:34
FakeInputBackend(Display *display)
void org_kde_kwin_fake_input_bind_resource(Resource *resource) override
void org_kde_kwin_fake_input_touch_up(Resource *resource, uint32_t id) override
void org_kde_kwin_fake_input_destroy_resource(Resource *resource) override
void org_kde_kwin_fake_input_touch_motion(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) override
static QList< quint32 > touchIds
void org_kde_kwin_fake_input_button(Resource *resource, uint32_t button, uint32_t state) override
void org_kde_kwin_fake_input_authenticate(Resource *resource, const QString &application, const QString &reason) override
void org_kde_kwin_fake_input_touch_down(Resource *resource, uint32_t id, wl_fixed_t x, wl_fixed_t y) override
void org_kde_kwin_fake_input_touch_cancel(Resource *resource) override
std::map< Resource *, std::unique_ptr< FakeInputDevice > > devices
std::chrono::microseconds currentTime() const
void org_kde_kwin_fake_input_keyboard_key(Resource *resource, uint32_t button, uint32_t state) override
void org_kde_kwin_fake_input_touch_frame(Resource *resource) override
void org_kde_kwin_fake_input_pointer_motion_absolute(Resource *resource, wl_fixed_t x, wl_fixed_t y) override
void org_kde_kwin_fake_input_axis(Resource *resource, uint32_t axis, wl_fixed_t value) override
void org_kde_kwin_fake_input_destroy(Resource *resource) override
FakeInputBackendPrivate(FakeInputBackend *q, Display *display)
void org_kde_kwin_fake_input_pointer_motion(Resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y) override
FakeInputDevice * findDevice(Resource *resource)
void setAuthenticated(bool authenticated)
void deviceAdded(InputDevice *device)
void deviceRemoved(InputDevice *device)
void touchFrame(InputDevice *device)
void touchMotion(qint32 id, const QPointF &absolutePos, std::chrono::microseconds time, InputDevice *device)
void touchCanceled(InputDevice *device)
void pointerMotion(const QPointF &delta, const QPointF &deltaNonAccelerated, std::chrono::microseconds time, InputDevice *device)
void pointerFrame(InputDevice *device)
void pointerButtonChanged(quint32 button, InputRedirection::PointerButtonState state, std::chrono::microseconds time, InputDevice *device)
void touchDown(qint32 id, const QPointF &absolutePos, std::chrono::microseconds time, InputDevice *device)
void pointerMotionAbsolute(const QPointF &position, std::chrono::microseconds time, InputDevice *device)
void keyChanged(quint32 key, InputRedirection::KeyboardKeyState, std::chrono::microseconds time, InputDevice *device)
void touchUp(qint32 id, std::chrono::microseconds time, InputDevice *device)
void pointerAxisChanged(InputRedirection::PointerAxis axis, qreal delta, qint32 deltaV120, InputRedirection::PointerAxisSource source, std::chrono::microseconds time, InputDevice *device)