KWayland

fakeinput_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2015 Martin Gräßlin <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 #include "fakeinput_interface.h"
7 #include "display.h"
8 #include "global_p.h"
9 
10 #include <QPointF>
11 #include <QSizeF>
12 
13 #include <wayland-fake-input-server-protocol.h>
14 #include <wayland-server.h>
15 
16 namespace KWayland
17 {
18 namespace Server
19 {
20 class FakeInputInterface::Private : public Global::Private
21 {
22 public:
23  Private(FakeInputInterface *q, Display *d);
25 
26 private:
27  void bind(wl_client *client, uint32_t version, uint32_t id) override;
28  static void authenticateCallback(wl_client *client, wl_resource *resource, const char *application, const char *reason);
29  static void pointerMotionCallback(wl_client *client, wl_resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y);
30  static void pointerMotionAbsoluteCallback(wl_client *client, wl_resource *resource, wl_fixed_t x, wl_fixed_t y);
31  static void buttonCallback(wl_client *client, wl_resource *resource, uint32_t button, uint32_t state);
32  static void axisCallback(wl_client *client, wl_resource *resource, uint32_t axis, wl_fixed_t value);
33  static void touchDownCallback(wl_client *client, wl_resource *resource, quint32 id, wl_fixed_t x, wl_fixed_t y);
34  static void touchMotionCallback(wl_client *client, wl_resource *resource, quint32 id, wl_fixed_t x, wl_fixed_t y);
35  static void touchUpCallback(wl_client *client, wl_resource *resource, quint32 id);
36  static void touchCancelCallback(wl_client *client, wl_resource *resource);
37  static void touchFrameCallback(wl_client *client, wl_resource *resource);
38  static void keyboardKeyCallback(wl_client *client, wl_resource *resource, uint32_t button, uint32_t state);
39 
40  static void unbind(wl_resource *resource);
41  static Private *cast(wl_resource *r)
42  {
43  return reinterpret_cast<Private *>(wl_resource_get_user_data(r));
44  }
45  static FakeInputDevice *device(wl_resource *r);
46 
47  FakeInputInterface *q;
48  static const struct org_kde_kwin_fake_input_interface s_interface;
49  static const quint32 s_version;
50  static QList<quint32> touchIds;
51 };
52 
53 class FakeInputDevice::Private
54 {
55 public:
56  Private(wl_resource *resource, FakeInputInterface *interface);
57  wl_resource *resource;
58  FakeInputInterface *interface;
59  bool authenticated = false;
60 };
61 
62 const quint32 FakeInputInterface::Private::s_version = 4;
63 QList<quint32> FakeInputInterface::Private::touchIds = QList<quint32>();
64 
65 #ifndef K_DOXYGEN
66 const struct org_kde_kwin_fake_input_interface FakeInputInterface::Private::s_interface = {authenticateCallback,
67  pointerMotionCallback,
68  buttonCallback,
69  axisCallback,
70  touchDownCallback,
71  touchMotionCallback,
72  touchUpCallback,
73  touchCancelCallback,
74  touchFrameCallback,
75  pointerMotionAbsoluteCallback,
76  keyboardKeyCallback};
77 #endif
78 
79 FakeInputInterface::Private::Private(FakeInputInterface *q, Display *d)
80  : Global::Private(d, &org_kde_kwin_fake_input_interface, s_version)
81  , q(q)
82 {
83 }
84 
85 void FakeInputInterface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
86 {
87  auto c = display->getConnection(client);
88  wl_resource *resource = c->createResource(&org_kde_kwin_fake_input_interface, qMin(version, s_version), id);
89  if (!resource) {
90  wl_client_post_no_memory(client);
91  return;
92  }
93  wl_resource_set_implementation(resource, &s_interface, this, unbind);
94  FakeInputDevice *device = new FakeInputDevice(resource, q);
95  devices << device;
96  QObject::connect(device, &FakeInputDevice::destroyed, q, [device, this] {
97  devices.removeAll(device);
98  });
99  Q_EMIT q->deviceCreated(device);
100 }
101 
102 void FakeInputInterface::Private::unbind(wl_resource *resource)
103 {
104  if (FakeInputDevice *d = device(resource)) {
105  d->deleteLater();
106  }
107 }
108 
109 FakeInputDevice *FakeInputInterface::Private::device(wl_resource *r)
110 {
111  Private *p = cast(r);
112  auto it = std::find_if(p->devices.constBegin(), p->devices.constEnd(), [r](FakeInputDevice *device) {
113  return device->resource() == r;
114  });
115  if (it != p->devices.constEnd()) {
116  return *it;
117  }
118  return nullptr;
119 }
120 
121 void FakeInputInterface::Private::authenticateCallback(wl_client *client, wl_resource *resource, const char *application, const char *reason)
122 {
123  Q_UNUSED(client)
124  FakeInputDevice *d = device(resource);
125  if (!d) {
126  return;
127  }
128  Q_EMIT d->authenticationRequested(QString::fromUtf8(application), QString::fromUtf8(reason));
129 }
130 
131 void FakeInputInterface::Private::pointerMotionCallback(wl_client *client, wl_resource *resource, wl_fixed_t delta_x, wl_fixed_t delta_y)
132 {
133  Q_UNUSED(client)
134  FakeInputDevice *d = device(resource);
135  if (!d || !d->isAuthenticated()) {
136  return;
137  }
138  Q_EMIT d->pointerMotionRequested(QSizeF(wl_fixed_to_double(delta_x), wl_fixed_to_double(delta_y)));
139 }
140 
141 void FakeInputInterface::Private::pointerMotionAbsoluteCallback(wl_client *client, wl_resource *resource, wl_fixed_t x, wl_fixed_t y)
142 {
143  Q_UNUSED(client)
144  FakeInputDevice *d = device(resource);
145  if (!d || !d->isAuthenticated()) {
146  return;
147  }
148  Q_EMIT d->pointerMotionAbsoluteRequested(QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)));
149 }
150 
151 void FakeInputInterface::Private::axisCallback(wl_client *client, wl_resource *resource, uint32_t axis, wl_fixed_t value)
152 {
153  Q_UNUSED(client)
154  FakeInputDevice *d = device(resource);
155  if (!d || !d->isAuthenticated()) {
156  return;
157  }
158  Qt::Orientation orientation;
159  switch (axis) {
160  case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
161  orientation = Qt::Horizontal;
162  break;
163  case WL_POINTER_AXIS_VERTICAL_SCROLL:
164  orientation = Qt::Vertical;
165  break;
166  default:
167  // invalid
168  return;
169  }
170  Q_EMIT d->pointerAxisRequested(orientation, wl_fixed_to_double(value));
171 }
172 
173 void FakeInputInterface::Private::buttonCallback(wl_client *client, wl_resource *resource, uint32_t button, uint32_t state)
174 {
175  Q_UNUSED(client)
176  FakeInputDevice *d = device(resource);
177  if (!d || !d->isAuthenticated()) {
178  return;
179  }
180  switch (state) {
181  case WL_POINTER_BUTTON_STATE_PRESSED:
182  Q_EMIT d->pointerButtonPressRequested(button);
183  break;
184  case WL_POINTER_BUTTON_STATE_RELEASED:
185  Q_EMIT d->pointerButtonReleaseRequested(button);
186  break;
187  default:
188  // nothing
189  break;
190  }
191 }
192 
193 void FakeInputInterface::Private::touchDownCallback(wl_client *client, wl_resource *resource, quint32 id, wl_fixed_t x, wl_fixed_t y)
194 {
195  Q_UNUSED(client)
196  FakeInputDevice *d = device(resource);
197  if (!d || !d->isAuthenticated()) {
198  return;
199  }
200  if (touchIds.contains(id)) {
201  return;
202  }
203  touchIds << id;
204  Q_EMIT d->touchDownRequested(id, QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)));
205 }
206 
207 void FakeInputInterface::Private::touchMotionCallback(wl_client *client, wl_resource *resource, quint32 id, wl_fixed_t x, wl_fixed_t y)
208 {
209  Q_UNUSED(client)
210  FakeInputDevice *d = device(resource);
211  if (!d || !d->isAuthenticated()) {
212  return;
213  }
214  if (!touchIds.contains(id)) {
215  return;
216  }
217  Q_EMIT d->touchMotionRequested(id, QPointF(wl_fixed_to_double(x), wl_fixed_to_double(y)));
218 }
219 
220 void FakeInputInterface::Private::touchUpCallback(wl_client *client, wl_resource *resource, quint32 id)
221 {
222  Q_UNUSED(client)
223  FakeInputDevice *d = device(resource);
224  if (!d || !d->isAuthenticated()) {
225  return;
226  }
227  if (!touchIds.contains(id)) {
228  return;
229  }
230  touchIds.removeOne(id);
231  Q_EMIT d->touchUpRequested(id);
232 }
233 
234 void FakeInputInterface::Private::touchCancelCallback(wl_client *client, wl_resource *resource)
235 {
236  Q_UNUSED(client)
237  FakeInputDevice *d = device(resource);
238  if (!d || !d->isAuthenticated()) {
239  return;
240  }
241  touchIds.clear();
242  Q_EMIT d->touchCancelRequested();
243 }
244 
245 void FakeInputInterface::Private::touchFrameCallback(wl_client *client, wl_resource *resource)
246 {
247  Q_UNUSED(client)
248  FakeInputDevice *d = device(resource);
249  if (!d || !d->isAuthenticated()) {
250  return;
251  }
252  Q_EMIT d->touchFrameRequested();
253 }
254 
255 void FakeInputInterface::Private::keyboardKeyCallback(wl_client *client, wl_resource *resource, uint32_t button, uint32_t state)
256 {
257  Q_UNUSED(client)
258  FakeInputDevice *d = device(resource);
259  if (!d || !d->isAuthenticated()) {
260  return;
261  }
262  switch (state) {
263  case WL_KEYBOARD_KEY_STATE_PRESSED:
264  Q_EMIT d->keyboardKeyPressRequested(button);
265  break;
266  case WL_KEYBOARD_KEY_STATE_RELEASED:
267  Q_EMIT d->keyboardKeyReleaseRequested(button);
268  break;
269  default:
270  // nothing
271  break;
272  }
273 }
274 
275 FakeInputInterface::FakeInputInterface(Display *display, QObject *parent)
276  : Global(new Private(this, display), parent)
277 {
278 }
279 
280 FakeInputInterface::~FakeInputInterface() = default;
281 
282 FakeInputDevice::Private::Private(wl_resource *resource, FakeInputInterface *interface)
283  : resource(resource)
284  , interface(interface)
285 {
286 }
287 
288 FakeInputDevice::FakeInputDevice(wl_resource *resource, FakeInputInterface *parent)
289  : QObject(parent)
290  , d(new Private(resource, parent))
291 {
292 }
293 
294 FakeInputDevice::~FakeInputDevice() = default;
295 
296 void FakeInputDevice::setAuthentication(bool authenticated)
297 {
298  d->authenticated = authenticated;
299 }
300 
301 wl_resource *FakeInputDevice::resource()
302 {
303  return d->resource;
304 }
305 
306 bool FakeInputDevice::isAuthenticated() const
307 {
308  return d->authenticated;
309 }
310 
311 }
312 }
QString fromUtf8(const char *str, int size)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Orientation
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Jan 30 2023 03:56:23 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.