1 | /* |
2 | SPDX-FileCopyrightText: 2016 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 "pointergestures.h" |
7 | #include "event_queue.h" |
8 | #include "pointer.h" |
9 | #include "surface.h" |
10 | #include "wayland_pointer_p.h" |
11 | |
12 | #include <wayland-pointer-gestures-unstable-v1-client-protocol.h> |
13 | |
14 | #include <QSizeF> |
15 | |
16 | namespace KWayland |
17 | { |
18 | namespace Client |
19 | { |
20 | class Q_DECL_HIDDEN PointerGestures::Private |
21 | { |
22 | public: |
23 | Private() = default; |
24 | |
25 | WaylandPointer<zwp_pointer_gestures_v1, zwp_pointer_gestures_v1_destroy> pointergestures; |
26 | EventQueue *queue = nullptr; |
27 | }; |
28 | |
29 | PointerGestures::PointerGestures(QObject *parent) |
30 | : QObject(parent) |
31 | , d(new Private) |
32 | { |
33 | } |
34 | |
35 | PointerGestures::~PointerGestures() |
36 | { |
37 | release(); |
38 | } |
39 | |
40 | void PointerGestures::setup(zwp_pointer_gestures_v1 *pointergestures) |
41 | { |
42 | Q_ASSERT(pointergestures); |
43 | Q_ASSERT(!d->pointergestures); |
44 | d->pointergestures.setup(pointer: pointergestures); |
45 | } |
46 | |
47 | void PointerGestures::release() |
48 | { |
49 | d->pointergestures.release(); |
50 | } |
51 | |
52 | void PointerGestures::destroy() |
53 | { |
54 | d->pointergestures.destroy(); |
55 | } |
56 | |
57 | PointerGestures::operator zwp_pointer_gestures_v1 *() |
58 | { |
59 | return d->pointergestures; |
60 | } |
61 | |
62 | PointerGestures::operator zwp_pointer_gestures_v1 *() const |
63 | { |
64 | return d->pointergestures; |
65 | } |
66 | |
67 | bool PointerGestures::isValid() const |
68 | { |
69 | return d->pointergestures.isValid(); |
70 | } |
71 | |
72 | void PointerGestures::setEventQueue(EventQueue *queue) |
73 | { |
74 | d->queue = queue; |
75 | } |
76 | |
77 | EventQueue *PointerGestures::eventQueue() |
78 | { |
79 | return d->queue; |
80 | } |
81 | |
82 | PointerSwipeGesture *PointerGestures::createSwipeGesture(Pointer *pointer, QObject *parent) |
83 | { |
84 | Q_ASSERT(isValid()); |
85 | PointerSwipeGesture *p = new PointerSwipeGesture(parent); |
86 | auto w = zwp_pointer_gestures_v1_get_swipe_gesture(zwp_pointer_gestures_v1: d->pointergestures, pointer: *pointer); |
87 | if (d->queue) { |
88 | d->queue->addProxy(proxy: w); |
89 | } |
90 | p->setup(w); |
91 | return p; |
92 | } |
93 | |
94 | PointerPinchGesture *PointerGestures::createPinchGesture(Pointer *pointer, QObject *parent) |
95 | { |
96 | Q_ASSERT(isValid()); |
97 | PointerPinchGesture *p = new PointerPinchGesture(parent); |
98 | auto w = zwp_pointer_gestures_v1_get_pinch_gesture(zwp_pointer_gestures_v1: d->pointergestures, pointer: *pointer); |
99 | if (d->queue) { |
100 | d->queue->addProxy(proxy: w); |
101 | } |
102 | p->setup(w); |
103 | return p; |
104 | } |
105 | |
106 | class Q_DECL_HIDDEN PointerSwipeGesture::Private |
107 | { |
108 | public: |
109 | Private(PointerSwipeGesture *q); |
110 | |
111 | void setup(zwp_pointer_gesture_swipe_v1 *pg); |
112 | |
113 | WaylandPointer<zwp_pointer_gesture_swipe_v1, zwp_pointer_gesture_swipe_v1_destroy> pointerswipegesture; |
114 | quint32 fingerCount = 0; |
115 | QPointer<Surface> surface; |
116 | |
117 | private: |
118 | static void beginCallback(void *data, |
119 | zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1, |
120 | uint32_t serial, |
121 | uint32_t time, |
122 | wl_surface *surface, |
123 | uint32_t fingers); |
124 | static void updateCallback(void *data, zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1, uint32_t time, wl_fixed_t dx, wl_fixed_t dy); |
125 | static void endCallback(void *data, zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1, uint32_t serial, uint32_t time, int32_t cancelled); |
126 | |
127 | PointerSwipeGesture *q; |
128 | static const zwp_pointer_gesture_swipe_v1_listener s_listener; |
129 | }; |
130 | |
131 | const zwp_pointer_gesture_swipe_v1_listener PointerSwipeGesture::Private::s_listener = {.begin: beginCallback, .update: updateCallback, .end: endCallback}; |
132 | |
133 | void PointerSwipeGesture::Private::beginCallback(void *data, |
134 | zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1, |
135 | uint32_t serial, |
136 | uint32_t time, |
137 | wl_surface *surface, |
138 | uint32_t fingers) |
139 | { |
140 | auto p = reinterpret_cast<PointerSwipeGesture::Private *>(data); |
141 | Q_ASSERT(p->pointerswipegesture == zwp_pointer_gesture_swipe_v1); |
142 | p->fingerCount = fingers; |
143 | p->surface = QPointer<Surface>(Surface::get(native: surface)); |
144 | Q_EMIT p->q->started(serial, time); |
145 | } |
146 | |
147 | void PointerSwipeGesture::Private::updateCallback(void *data, |
148 | zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1, |
149 | uint32_t time, |
150 | wl_fixed_t dx, |
151 | wl_fixed_t dy) |
152 | { |
153 | auto p = reinterpret_cast<PointerSwipeGesture::Private *>(data); |
154 | Q_ASSERT(p->pointerswipegesture == zwp_pointer_gesture_swipe_v1); |
155 | Q_EMIT p->q->updated(delta: QSizeF(wl_fixed_to_double(f: dx), wl_fixed_to_double(f: dy)), time); |
156 | } |
157 | |
158 | void PointerSwipeGesture::Private::endCallback(void *data, |
159 | zwp_pointer_gesture_swipe_v1 *zwp_pointer_gesture_swipe_v1, |
160 | uint32_t serial, |
161 | uint32_t time, |
162 | int32_t cancelled) |
163 | { |
164 | auto p = reinterpret_cast<PointerSwipeGesture::Private *>(data); |
165 | Q_ASSERT(p->pointerswipegesture == zwp_pointer_gesture_swipe_v1); |
166 | if (cancelled) { |
167 | Q_EMIT p->q->cancelled(serial, time); |
168 | } else { |
169 | Q_EMIT p->q->ended(serial, time); |
170 | } |
171 | p->fingerCount = 0; |
172 | p->surface.clear(); |
173 | } |
174 | |
175 | PointerSwipeGesture::Private::Private(PointerSwipeGesture *q) |
176 | : q(q) |
177 | { |
178 | } |
179 | |
180 | PointerSwipeGesture::PointerSwipeGesture(QObject *parent) |
181 | : QObject(parent) |
182 | , d(new Private(this)) |
183 | { |
184 | } |
185 | |
186 | PointerSwipeGesture::~PointerSwipeGesture() |
187 | { |
188 | release(); |
189 | } |
190 | |
191 | quint32 PointerSwipeGesture::fingerCount() const |
192 | { |
193 | return d->fingerCount; |
194 | } |
195 | |
196 | QPointer<Surface> PointerSwipeGesture::surface() const |
197 | { |
198 | return d->surface; |
199 | } |
200 | |
201 | void PointerSwipeGesture::Private::setup(zwp_pointer_gesture_swipe_v1 *pg) |
202 | { |
203 | Q_ASSERT(pg); |
204 | Q_ASSERT(!pointerswipegesture); |
205 | pointerswipegesture.setup(pointer: pg); |
206 | zwp_pointer_gesture_swipe_v1_add_listener(zwp_pointer_gesture_swipe_v1: pointerswipegesture, listener: &s_listener, data: this); |
207 | } |
208 | |
209 | void PointerSwipeGesture::setup(zwp_pointer_gesture_swipe_v1 *pointerswipegesture) |
210 | { |
211 | d->setup(pointerswipegesture); |
212 | } |
213 | |
214 | void PointerSwipeGesture::release() |
215 | { |
216 | d->pointerswipegesture.release(); |
217 | } |
218 | |
219 | void PointerSwipeGesture::destroy() |
220 | { |
221 | d->pointerswipegesture.destroy(); |
222 | } |
223 | |
224 | PointerSwipeGesture::operator zwp_pointer_gesture_swipe_v1 *() |
225 | { |
226 | return d->pointerswipegesture; |
227 | } |
228 | |
229 | PointerSwipeGesture::operator zwp_pointer_gesture_swipe_v1 *() const |
230 | { |
231 | return d->pointerswipegesture; |
232 | } |
233 | |
234 | bool PointerSwipeGesture::isValid() const |
235 | { |
236 | return d->pointerswipegesture.isValid(); |
237 | } |
238 | |
239 | class Q_DECL_HIDDEN PointerPinchGesture::Private |
240 | { |
241 | public: |
242 | Private(PointerPinchGesture *q); |
243 | |
244 | void setup(zwp_pointer_gesture_pinch_v1 *pg); |
245 | |
246 | WaylandPointer<zwp_pointer_gesture_pinch_v1, zwp_pointer_gesture_pinch_v1_destroy> pointerpinchgesture; |
247 | quint32 fingerCount = 0; |
248 | QPointer<Surface> surface; |
249 | |
250 | private: |
251 | static void beginCallback(void *data, |
252 | zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1, |
253 | uint32_t serial, |
254 | uint32_t time, |
255 | wl_surface *surface, |
256 | uint32_t fingers); |
257 | static void updateCallback(void *data, |
258 | zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1, |
259 | uint32_t time, |
260 | wl_fixed_t dx, |
261 | wl_fixed_t dy, |
262 | wl_fixed_t scale, |
263 | wl_fixed_t rotation); |
264 | static void endCallback(void *data, zwp_pointer_gesture_pinch_v1 *zwp_pointer_gesture_pinch_v1, uint32_t serial, uint32_t time, int32_t cancelled); |
265 | |
266 | PointerPinchGesture *q; |
267 | static const zwp_pointer_gesture_pinch_v1_listener s_listener; |
268 | }; |
269 | |
270 | const zwp_pointer_gesture_pinch_v1_listener PointerPinchGesture::Private::s_listener = {.begin: beginCallback, .update: updateCallback, .end: endCallback}; |
271 | |
272 | void PointerPinchGesture::Private::beginCallback(void *data, |
273 | zwp_pointer_gesture_pinch_v1 *pg, |
274 | uint32_t serial, |
275 | uint32_t time, |
276 | wl_surface *surface, |
277 | uint32_t fingers) |
278 | { |
279 | auto p = reinterpret_cast<PointerPinchGesture::Private *>(data); |
280 | Q_ASSERT(p->pointerpinchgesture == pg); |
281 | p->fingerCount = fingers; |
282 | p->surface = QPointer<Surface>(Surface::get(native: surface)); |
283 | Q_EMIT p->q->started(serial, time); |
284 | } |
285 | |
286 | void PointerPinchGesture::Private::updateCallback(void *data, |
287 | zwp_pointer_gesture_pinch_v1 *pg, |
288 | uint32_t time, |
289 | wl_fixed_t dx, |
290 | wl_fixed_t dy, |
291 | wl_fixed_t scale, |
292 | wl_fixed_t rotation) |
293 | { |
294 | auto p = reinterpret_cast<PointerPinchGesture::Private *>(data); |
295 | Q_ASSERT(p->pointerpinchgesture == pg); |
296 | Q_EMIT p->q->updated(delta: QSizeF(wl_fixed_to_double(f: dx), wl_fixed_to_double(f: dy)), scale: wl_fixed_to_double(f: scale), rotation: wl_fixed_to_double(f: rotation), time); |
297 | } |
298 | |
299 | void PointerPinchGesture::Private::endCallback(void *data, zwp_pointer_gesture_pinch_v1 *pg, uint32_t serial, uint32_t time, int32_t cancelled) |
300 | { |
301 | auto p = reinterpret_cast<PointerPinchGesture::Private *>(data); |
302 | Q_ASSERT(p->pointerpinchgesture == pg); |
303 | if (cancelled) { |
304 | Q_EMIT p->q->cancelled(serial, time); |
305 | } else { |
306 | Q_EMIT p->q->ended(serial, time); |
307 | } |
308 | p->fingerCount = 0; |
309 | p->surface.clear(); |
310 | } |
311 | |
312 | PointerPinchGesture::Private::Private(PointerPinchGesture *q) |
313 | : q(q) |
314 | { |
315 | } |
316 | |
317 | PointerPinchGesture::PointerPinchGesture(QObject *parent) |
318 | : QObject(parent) |
319 | , d(new Private(this)) |
320 | { |
321 | } |
322 | |
323 | PointerPinchGesture::~PointerPinchGesture() |
324 | { |
325 | release(); |
326 | } |
327 | |
328 | void PointerPinchGesture::Private::setup(zwp_pointer_gesture_pinch_v1 *pg) |
329 | { |
330 | Q_ASSERT(pg); |
331 | Q_ASSERT(!pointerpinchgesture); |
332 | pointerpinchgesture.setup(pointer: pg); |
333 | zwp_pointer_gesture_pinch_v1_add_listener(zwp_pointer_gesture_pinch_v1: pointerpinchgesture, listener: &s_listener, data: this); |
334 | } |
335 | |
336 | void PointerPinchGesture::setup(zwp_pointer_gesture_pinch_v1 *pointerpinchgesture) |
337 | { |
338 | d->setup(pointerpinchgesture); |
339 | } |
340 | |
341 | void PointerPinchGesture::release() |
342 | { |
343 | d->pointerpinchgesture.release(); |
344 | } |
345 | |
346 | void PointerPinchGesture::destroy() |
347 | { |
348 | d->pointerpinchgesture.destroy(); |
349 | } |
350 | |
351 | PointerPinchGesture::operator zwp_pointer_gesture_pinch_v1 *() |
352 | { |
353 | return d->pointerpinchgesture; |
354 | } |
355 | |
356 | PointerPinchGesture::operator zwp_pointer_gesture_pinch_v1 *() const |
357 | { |
358 | return d->pointerpinchgesture; |
359 | } |
360 | |
361 | bool PointerPinchGesture::isValid() const |
362 | { |
363 | return d->pointerpinchgesture.isValid(); |
364 | } |
365 | |
366 | quint32 PointerPinchGesture::fingerCount() const |
367 | { |
368 | return d->fingerCount; |
369 | } |
370 | |
371 | QPointer<Surface> PointerPinchGesture::surface() const |
372 | { |
373 | return d->surface; |
374 | } |
375 | |
376 | } |
377 | } |
378 | |
379 | #include "moc_pointergestures.cpp" |
380 | |