KWayland

pointer.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 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 "pointer.h"
7 #include "surface.h"
8 #include "wayland_pointer_p.h"
9 // Qt
10 #include <QPointF>
11 #include <QPointer>
12 // wayland
13 #include <wayland-client-protocol.h>
14 
15 namespace KWayland
16 {
17 namespace Client
18 {
19 
20 static Pointer::Axis wlAxisToPointerAxis(uint32_t axis)
21 {
22  switch (axis) {
23  case WL_POINTER_AXIS_VERTICAL_SCROLL:
24  return Pointer::Axis::Vertical;
25  case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
26  return Pointer::Axis::Horizontal;
27  }
28 
29  Q_UNREACHABLE();
30 }
31 
32 class Q_DECL_HIDDEN Pointer::Private
33 {
34 public:
35  Private(Pointer *q);
36  void setup(wl_pointer *p);
37 
38  WaylandPointer<wl_pointer, wl_pointer_release> pointer;
39  QPointer<Surface> enteredSurface;
40  quint32 enteredSerial = 0;
41 private:
42  void enter(uint32_t serial, wl_surface *surface, const QPointF &relativeToSurface);
43  void leave(uint32_t serial);
44  static void enterCallback(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface,
45  wl_fixed_t sx, wl_fixed_t sy);
46  static void leaveCallback(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface);
47  static void motionCallback(void *data, wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy);
48  static void buttonCallback(void *data, wl_pointer *pointer, uint32_t serial, uint32_t time,
49  uint32_t button, uint32_t state);
50  static void axisCallback(void *data, wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value);
51  static void frameCallback(void *data, wl_pointer *pointer);
52  static void axisSourceCallback(void *data, wl_pointer *pointer, uint32_t axis_source);
53  static void axisStopCallback(void *data, wl_pointer *pointer, uint32_t time, uint32_t axis);
54  static void axisDiscreteCallback(void *data, wl_pointer *pointer, uint32_t axis, int32_t discrete);
55 
56  Pointer *q;
57  static const wl_pointer_listener s_listener;
58 };
59 
60 Pointer::Private::Private(Pointer *q)
61  : q(q)
62 {
63 }
64 
65 void Pointer::Private::setup(wl_pointer *p)
66 {
67  Q_ASSERT(p);
68  Q_ASSERT(!pointer);
69  pointer.setup(p);
70  wl_pointer_add_listener(pointer, &s_listener, this);
71 }
72 
73 const wl_pointer_listener Pointer::Private::s_listener = {
74  enterCallback,
75  leaveCallback,
76  motionCallback,
77  buttonCallback,
78  axisCallback,
79  frameCallback,
80  axisSourceCallback,
81  axisStopCallback,
82  axisDiscreteCallback
83 };
84 
85 Pointer::Pointer(QObject *parent)
86  : QObject(parent)
87  , d(new Private(this))
88 {
89 }
90 
91 Pointer::~Pointer()
92 {
93  release();
94 }
95 
97 {
98  d->pointer.release();
99 }
100 
102 {
103  d->pointer.destroy();
104 }
105 
106 void Pointer::setup(wl_pointer *pointer)
107 {
108  d->setup(pointer);
109 }
110 
111 void Pointer::Private::enterCallback(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface,
112  wl_fixed_t sx, wl_fixed_t sy)
113 {
114  auto p = reinterpret_cast<Pointer::Private*>(data);
115  Q_ASSERT(p->pointer == pointer);
116  p->enter(serial, surface, QPointF(wl_fixed_to_double(sx), wl_fixed_to_double(sy)));
117 }
118 
119 void Pointer::Private::enter(uint32_t serial, wl_surface *surface, const QPointF &relativeToSurface)
120 {
121  enteredSurface = QPointer<Surface>(Surface::get(surface));
122  enteredSerial = serial;
123  emit q->entered(serial, relativeToSurface);
124 }
125 
126 void Pointer::Private::leaveCallback(void *data, wl_pointer *pointer, uint32_t serial, wl_surface *surface)
127 {
128  auto p = reinterpret_cast<Pointer::Private*>(data);
129  Q_ASSERT(p->pointer == pointer);
130  Q_UNUSED(surface)
131  p->leave(serial);
132 }
133 
134 void Pointer::Private::leave(uint32_t serial)
135 {
136  enteredSurface.clear();
137  emit q->left(serial);
138 }
139 
140 void Pointer::Private::motionCallback(void *data, wl_pointer *pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
141 {
142  auto p = reinterpret_cast<Pointer::Private*>(data);
143  Q_ASSERT(p->pointer == pointer);
144  emit p->q->motion(QPointF(wl_fixed_to_double(sx), wl_fixed_to_double(sy)), time);
145 }
146 
147 void Pointer::Private::buttonCallback(void *data, wl_pointer *pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
148 {
149  auto p = reinterpret_cast<Pointer::Private*>(data);
150  Q_ASSERT(p->pointer == pointer);
151  auto toState = [state] {
152  if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
153  return ButtonState::Released;
154  } else {
155  return ButtonState::Pressed;
156  }
157  };
158  emit p->q->buttonStateChanged(serial, time, button, toState());
159 }
160 
161 void Pointer::Private::axisCallback(void *data, wl_pointer *pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
162 {
163  auto p = reinterpret_cast<Pointer::Private*>(data);
164  Q_ASSERT(p->pointer == pointer);
165  emit p->q->axisChanged(time, wlAxisToPointerAxis(axis), wl_fixed_to_double(value));
166 }
167 
168 void Pointer::Private::frameCallback(void *data, wl_pointer *pointer)
169 {
170  auto p = reinterpret_cast<Pointer::Private*>(data);
171  Q_ASSERT(p->pointer == pointer);
172  emit p->q->frame();
173 }
174 
175 void Pointer::Private::axisSourceCallback(void *data, wl_pointer *pointer, uint32_t axis_source)
176 {
177  auto p = reinterpret_cast<Pointer::Private*>(data);
178  Q_ASSERT(p->pointer == pointer);
179  AxisSource source;
180  switch (axis_source) {
181  case WL_POINTER_AXIS_SOURCE_WHEEL:
182  source = AxisSource::Wheel;
183  break;
184  case WL_POINTER_AXIS_SOURCE_FINGER:
185  source = AxisSource::Finger;
186  break;
187  case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
188  source = AxisSource::Continuous;
189  break;
190  case WL_POINTER_AXIS_SOURCE_WHEEL_TILT:
191  source = AxisSource::WheelTilt;
192  break;
193  default:
194  Q_UNREACHABLE();
195  break;
196  }
197  emit p->q->axisSourceChanged(source);
198 }
199 
200 void Pointer::Private::axisStopCallback(void *data, wl_pointer *pointer, uint32_t time, uint32_t axis)
201 {
202  auto p = reinterpret_cast<Pointer::Private*>(data);
203  Q_ASSERT(p->pointer == pointer);
204  emit p->q->axisStopped(time, wlAxisToPointerAxis(axis));
205 }
206 
207 void Pointer::Private::axisDiscreteCallback(void *data, wl_pointer *pointer, uint32_t axis, int32_t discrete)
208 {
209  auto p = reinterpret_cast<Pointer::Private*>(data);
210  Q_ASSERT(p->pointer == pointer);
211  emit p->q->axisDiscreteChanged(wlAxisToPointerAxis(axis), discrete);
212 }
213 
214 void Pointer::setCursor(Surface *surface, const QPoint &hotspot)
215 {
216  Q_ASSERT(isValid());
217  wl_surface *s = nullptr;
218  if (surface) {
219  s = *surface;
220  }
221  wl_pointer_set_cursor(d->pointer, d->enteredSerial, s, hotspot.x(), hotspot.y());
222 }
223 
225 {
226  setCursor(nullptr);
227 }
228 
230 {
231  return d->enteredSurface.data();
232 }
233 
235 {
236  return d->enteredSurface.data();
237 }
238 
239 bool Pointer::isValid() const
240 {
241  return d->pointer.isValid();
242 }
243 
244 Pointer::operator wl_pointer*() const
245 {
246  return d->pointer;
247 }
248 
249 Pointer::operator wl_pointer*()
250 {
251  return d->pointer;
252 }
253 
254 }
255 }
void destroy()
Destroys the data held by this Pointer.
Definition: pointer.cpp:101
void hideCursor()
Hides the cursor.
Definition: pointer.cpp:224
int x() const const
int y() const const
void setup(wl_pointer *pointer)
Setup this Pointer to manage the pointer.
Definition: pointer.cpp:106
bool isValid() const
Definition: pointer.cpp:239
Wrapper for the wl_surface interface.
Definition: surface.h:44
void release()
Releases the wl_pointer interface.
Definition: pointer.cpp:96
T * data() const const
static Surface * get(wl_surface *native)
Definition: surface.cpp:286
void setCursor(Surface *surface, const QPoint &hotspot=QPoint())
Sets the cursor image for this Pointer.
Definition: pointer.cpp:214
QObject * parent() const const
Surface * enteredSurface() const
Definition: pointer.cpp:234
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Aug 7 2020 22:48:18 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.