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

KDE's Doxygen guidelines are available online.