1 | /* |
2 | SPDX-FileCopyrightText: 2015 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 | #include "fakeinput.h" |
7 | #include "event_queue.h" |
8 | #include "seat.h" |
9 | #include "wayland_pointer_p.h" |
10 | #include <QPointF> |
11 | #include <QSizeF> |
12 | |
13 | #include <linux/input.h> |
14 | |
15 | #include <wayland-fake-input-client-protocol.h> |
16 | |
17 | namespace KWayland |
18 | { |
19 | namespace Client |
20 | { |
21 | class Q_DECL_HIDDEN FakeInput::Private |
22 | { |
23 | public: |
24 | WaylandPointer<org_kde_kwin_fake_input, org_kde_kwin_fake_input_destroy> manager; |
25 | EventQueue *queue = nullptr; |
26 | |
27 | void sendPointerButtonState(Qt::MouseButton button, quint32 state); |
28 | }; |
29 | |
30 | FakeInput::FakeInput(QObject *parent) |
31 | : QObject(parent) |
32 | , d(new Private) |
33 | { |
34 | } |
35 | |
36 | FakeInput::~FakeInput() |
37 | { |
38 | release(); |
39 | } |
40 | |
41 | void FakeInput::release() |
42 | { |
43 | d->manager.release(); |
44 | } |
45 | |
46 | void FakeInput::destroy() |
47 | { |
48 | d->manager.destroy(); |
49 | } |
50 | |
51 | bool FakeInput::isValid() const |
52 | { |
53 | return d->manager.isValid(); |
54 | } |
55 | |
56 | void FakeInput::setup(org_kde_kwin_fake_input *manager) |
57 | { |
58 | Q_ASSERT(manager); |
59 | Q_ASSERT(!d->manager.isValid()); |
60 | d->manager.setup(pointer: manager); |
61 | } |
62 | |
63 | EventQueue *FakeInput::eventQueue() |
64 | { |
65 | return d->queue; |
66 | } |
67 | |
68 | void FakeInput::setEventQueue(EventQueue *queue) |
69 | { |
70 | d->queue = queue; |
71 | } |
72 | |
73 | void FakeInput::authenticate(const QString &applicationName, const QString &reason) |
74 | { |
75 | Q_ASSERT(d->manager.isValid()); |
76 | org_kde_kwin_fake_input_authenticate(org_kde_kwin_fake_input: d->manager, application: applicationName.toUtf8().constData(), reason: reason.toUtf8().constData()); |
77 | } |
78 | |
79 | void FakeInput::requestPointerMove(const QSizeF &delta) |
80 | { |
81 | Q_ASSERT(d->manager.isValid()); |
82 | org_kde_kwin_fake_input_pointer_motion(org_kde_kwin_fake_input: d->manager, delta_x: wl_fixed_from_double(d: delta.width()), delta_y: wl_fixed_from_double(d: delta.height())); |
83 | } |
84 | |
85 | void FakeInput::requestPointerMoveAbsolute(const QPointF &pos) |
86 | { |
87 | Q_ASSERT(d->manager.isValid()); |
88 | if (wl_proxy_get_version(proxy: d->manager) < ORG_KDE_KWIN_FAKE_INPUT_POINTER_MOTION_ABSOLUTE_SINCE_VERSION) { |
89 | return; |
90 | } |
91 | |
92 | org_kde_kwin_fake_input_pointer_motion_absolute(org_kde_kwin_fake_input: d->manager, x: wl_fixed_from_double(d: pos.x()), y: wl_fixed_from_double(d: pos.y())); |
93 | } |
94 | |
95 | void FakeInput::Private::sendPointerButtonState(Qt::MouseButton button, quint32 state) |
96 | { |
97 | Q_ASSERT(manager.isValid()); |
98 | uint32_t b = 0; |
99 | switch (button) { |
100 | case Qt::LeftButton: |
101 | b = BTN_LEFT; |
102 | break; |
103 | case Qt::RightButton: |
104 | b = BTN_RIGHT; |
105 | break; |
106 | case Qt::MiddleButton: |
107 | b = BTN_MIDDLE; |
108 | break; |
109 | default: |
110 | // TODO: more buttons, check implementation in QtWayland |
111 | // unsupported button |
112 | return; |
113 | } |
114 | org_kde_kwin_fake_input_button(org_kde_kwin_fake_input: manager, button: b, state); |
115 | } |
116 | |
117 | void FakeInput::requestPointerButtonPress(Qt::MouseButton button) |
118 | { |
119 | d->sendPointerButtonState(button, state: WL_POINTER_BUTTON_STATE_PRESSED); |
120 | } |
121 | |
122 | void FakeInput::requestPointerButtonPress(quint32 linuxButton) |
123 | { |
124 | Q_ASSERT(d->manager.isValid()); |
125 | org_kde_kwin_fake_input_button(org_kde_kwin_fake_input: d->manager, button: linuxButton, state: WL_POINTER_BUTTON_STATE_PRESSED); |
126 | } |
127 | |
128 | void FakeInput::requestPointerButtonRelease(Qt::MouseButton button) |
129 | { |
130 | d->sendPointerButtonState(button, state: WL_POINTER_BUTTON_STATE_RELEASED); |
131 | } |
132 | |
133 | void FakeInput::requestPointerButtonRelease(quint32 linuxButton) |
134 | { |
135 | Q_ASSERT(d->manager.isValid()); |
136 | org_kde_kwin_fake_input_button(org_kde_kwin_fake_input: d->manager, button: linuxButton, state: WL_POINTER_BUTTON_STATE_RELEASED); |
137 | } |
138 | |
139 | void FakeInput::requestPointerButtonClick(Qt::MouseButton button) |
140 | { |
141 | requestPointerButtonPress(button); |
142 | requestPointerButtonRelease(button); |
143 | } |
144 | |
145 | void FakeInput::requestPointerButtonClick(quint32 linuxButton) |
146 | { |
147 | requestPointerButtonPress(linuxButton); |
148 | requestPointerButtonRelease(linuxButton); |
149 | } |
150 | |
151 | void FakeInput::requestPointerAxis(Qt::Orientation axis, qreal delta) |
152 | { |
153 | Q_ASSERT(d->manager.isValid()); |
154 | uint32_t a; |
155 | switch (axis) { |
156 | case Qt::Horizontal: |
157 | a = WL_POINTER_AXIS_HORIZONTAL_SCROLL; |
158 | break; |
159 | case Qt::Vertical: |
160 | a = WL_POINTER_AXIS_VERTICAL_SCROLL; |
161 | break; |
162 | default: |
163 | Q_UNREACHABLE(); |
164 | break; |
165 | } |
166 | org_kde_kwin_fake_input_axis(org_kde_kwin_fake_input: d->manager, axis: a, value: wl_fixed_from_double(d: delta)); |
167 | } |
168 | |
169 | void FakeInput::requestTouchDown(quint32 id, const QPointF &pos) |
170 | { |
171 | Q_ASSERT(d->manager.isValid()); |
172 | org_kde_kwin_fake_input_touch_down(org_kde_kwin_fake_input: d->manager, id, x: wl_fixed_from_double(d: pos.x()), y: wl_fixed_from_double(d: pos.y())); |
173 | } |
174 | |
175 | void FakeInput::requestTouchMotion(quint32 id, const QPointF &pos) |
176 | { |
177 | Q_ASSERT(d->manager.isValid()); |
178 | org_kde_kwin_fake_input_touch_motion(org_kde_kwin_fake_input: d->manager, id, x: wl_fixed_from_double(d: pos.x()), y: wl_fixed_from_double(d: pos.y())); |
179 | } |
180 | |
181 | void FakeInput::requestTouchUp(quint32 id) |
182 | { |
183 | Q_ASSERT(d->manager.isValid()); |
184 | org_kde_kwin_fake_input_touch_up(org_kde_kwin_fake_input: d->manager, id); |
185 | } |
186 | |
187 | void FakeInput::requestTouchCancel() |
188 | { |
189 | Q_ASSERT(d->manager.isValid()); |
190 | org_kde_kwin_fake_input_touch_cancel(org_kde_kwin_fake_input: d->manager); |
191 | } |
192 | |
193 | void FakeInput::requestTouchFrame() |
194 | { |
195 | Q_ASSERT(d->manager.isValid()); |
196 | org_kde_kwin_fake_input_touch_frame(org_kde_kwin_fake_input: d->manager); |
197 | } |
198 | |
199 | void FakeInput::requestKeyboardKeyPress(quint32 linuxKey) |
200 | { |
201 | Q_ASSERT(d->manager.isValid()); |
202 | if (wl_proxy_get_version(proxy: d->manager) < ORG_KDE_KWIN_FAKE_INPUT_KEYBOARD_KEY_SINCE_VERSION) { |
203 | return; |
204 | } |
205 | |
206 | org_kde_kwin_fake_input_keyboard_key(org_kde_kwin_fake_input: d->manager, button: linuxKey, state: WL_KEYBOARD_KEY_STATE_PRESSED); |
207 | } |
208 | |
209 | void FakeInput::requestKeyboardKeyRelease(quint32 linuxKey) |
210 | { |
211 | Q_ASSERT(d->manager.isValid()); |
212 | if (wl_proxy_get_version(proxy: d->manager) < ORG_KDE_KWIN_FAKE_INPUT_KEYBOARD_KEY_SINCE_VERSION) { |
213 | return; |
214 | } |
215 | |
216 | org_kde_kwin_fake_input_keyboard_key(org_kde_kwin_fake_input: d->manager, button: linuxKey, state: WL_KEYBOARD_KEY_STATE_RELEASED); |
217 | } |
218 | |
219 | FakeInput::operator org_kde_kwin_fake_input *() const |
220 | { |
221 | return d->manager; |
222 | } |
223 | |
224 | FakeInput::operator org_kde_kwin_fake_input *() |
225 | { |
226 | return d->manager; |
227 | } |
228 | |
229 | } |
230 | } |
231 | |
232 | #include "moc_fakeinput.cpp" |
233 | |