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 "pointerconstraints.h"
7#include "event_queue.h"
8#include "pointer.h"
9#include "region.h"
10#include "surface.h"
11#include "wayland_pointer_p.h"
12
13#include <wayland-pointer-constraints-unstable-v1-client-protocol.h>
14
15namespace KWayland
16{
17namespace Client
18{
19class Q_DECL_HIDDEN PointerConstraints::Private
20{
21public:
22 Private() = default;
23
24 void setup(zwp_pointer_constraints_v1 *arg);
25
26 WaylandPointer<zwp_pointer_constraints_v1, zwp_pointer_constraints_v1_destroy> pointerconstraints;
27 EventQueue *queue = nullptr;
28};
29
30PointerConstraints::PointerConstraints(QObject *parent)
31 : QObject(parent)
32 , d(new Private)
33{
34}
35
36void PointerConstraints::Private::setup(zwp_pointer_constraints_v1 *arg)
37{
38 Q_ASSERT(arg);
39 Q_ASSERT(!pointerconstraints);
40 pointerconstraints.setup(pointer: arg);
41}
42
43PointerConstraints::~PointerConstraints()
44{
45 release();
46}
47
48void PointerConstraints::setup(zwp_pointer_constraints_v1 *pointerconstraints)
49{
50 d->setup(pointerconstraints);
51}
52
53void PointerConstraints::release()
54{
55 d->pointerconstraints.release();
56}
57
58void PointerConstraints::destroy()
59{
60 d->pointerconstraints.destroy();
61}
62
63PointerConstraints::operator zwp_pointer_constraints_v1 *()
64{
65 return d->pointerconstraints;
66}
67
68PointerConstraints::operator zwp_pointer_constraints_v1 *() const
69{
70 return d->pointerconstraints;
71}
72
73bool PointerConstraints::isValid() const
74{
75 return d->pointerconstraints.isValid();
76}
77
78void PointerConstraints::setEventQueue(EventQueue *queue)
79{
80 d->queue = queue;
81}
82
83EventQueue *PointerConstraints::eventQueue()
84{
85 return d->queue;
86}
87
88LockedPointer *PointerConstraints::lockPointer(Surface *surface, Pointer *pointer, Region *region, LifeTime lifetime, QObject *parent)
89{
90 Q_ASSERT(isValid());
91 auto p = new LockedPointer(parent);
92 zwp_pointer_constraints_v1_lifetime lf;
93 switch (lifetime) {
94 case LifeTime::OneShot:
95 lf = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT;
96 break;
97 case LifeTime::Persistent:
98 lf = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT;
99 break;
100 default:
101 Q_UNREACHABLE();
102 break;
103 }
104 wl_region *wr = nullptr;
105 if (region) {
106 wr = *region;
107 }
108 auto w = zwp_pointer_constraints_v1_lock_pointer(zwp_pointer_constraints_v1: d->pointerconstraints, surface: *surface, pointer: *pointer, region: wr, lifetime: lf);
109 if (d->queue) {
110 d->queue->addProxy(proxy: w);
111 }
112 p->setup(w);
113 return p;
114}
115
116ConfinedPointer *PointerConstraints::confinePointer(Surface *surface, Pointer *pointer, Region *region, LifeTime lifetime, QObject *parent)
117{
118 Q_ASSERT(isValid());
119 auto p = new ConfinedPointer(parent);
120 zwp_pointer_constraints_v1_lifetime lf;
121 switch (lifetime) {
122 case LifeTime::OneShot:
123 lf = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT;
124 break;
125 case LifeTime::Persistent:
126 lf = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT;
127 break;
128 default:
129 Q_UNREACHABLE();
130 break;
131 }
132 wl_region *wr = nullptr;
133 if (region) {
134 wr = *region;
135 }
136 auto w = zwp_pointer_constraints_v1_confine_pointer(zwp_pointer_constraints_v1: d->pointerconstraints, surface: *surface, pointer: *pointer, region: wr, lifetime: lf);
137 if (d->queue) {
138 d->queue->addProxy(proxy: w);
139 }
140 p->setup(w);
141 return p;
142}
143
144class Q_DECL_HIDDEN LockedPointer::Private
145{
146public:
147 Private(LockedPointer *q);
148
149 void setup(zwp_locked_pointer_v1 *arg);
150
151 WaylandPointer<zwp_locked_pointer_v1, zwp_locked_pointer_v1_destroy> lockedpointer;
152
153private:
154 LockedPointer *q;
155
156private:
157 static void lockedCallback(void *data, zwp_locked_pointer_v1 *zwp_locked_pointer_v1);
158 static void unlockedCallback(void *data, zwp_locked_pointer_v1 *zwp_locked_pointer_v1);
159
160 static const zwp_locked_pointer_v1_listener s_listener;
161};
162
163const zwp_locked_pointer_v1_listener LockedPointer::Private::s_listener = {.locked: lockedCallback, .unlocked: unlockedCallback};
164
165void LockedPointer::Private::lockedCallback(void *data, zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
166{
167 auto p = reinterpret_cast<LockedPointer::Private *>(data);
168 Q_ASSERT(p->lockedpointer == zwp_locked_pointer_v1);
169 Q_EMIT p->q->locked();
170}
171
172void LockedPointer::Private::unlockedCallback(void *data, zwp_locked_pointer_v1 *zwp_locked_pointer_v1)
173{
174 auto p = reinterpret_cast<LockedPointer::Private *>(data);
175 Q_ASSERT(p->lockedpointer == zwp_locked_pointer_v1);
176 Q_EMIT p->q->unlocked();
177}
178
179LockedPointer::Private::Private(LockedPointer *q)
180 : q(q)
181{
182}
183
184LockedPointer::LockedPointer(QObject *parent)
185 : QObject(parent)
186 , d(new Private(this))
187{
188}
189
190void LockedPointer::Private::setup(zwp_locked_pointer_v1 *arg)
191{
192 Q_ASSERT(arg);
193 Q_ASSERT(!lockedpointer);
194 lockedpointer.setup(pointer: arg);
195 zwp_locked_pointer_v1_add_listener(zwp_locked_pointer_v1: lockedpointer, listener: &s_listener, data: this);
196}
197
198LockedPointer::~LockedPointer()
199{
200 release();
201}
202
203void LockedPointer::setup(zwp_locked_pointer_v1 *lockedpointer)
204{
205 d->setup(lockedpointer);
206}
207
208void LockedPointer::release()
209{
210 d->lockedpointer.release();
211}
212
213void LockedPointer::destroy()
214{
215 d->lockedpointer.destroy();
216}
217
218LockedPointer::operator zwp_locked_pointer_v1 *()
219{
220 return d->lockedpointer;
221}
222
223LockedPointer::operator zwp_locked_pointer_v1 *() const
224{
225 return d->lockedpointer;
226}
227
228bool LockedPointer::isValid() const
229{
230 return d->lockedpointer.isValid();
231}
232
233void LockedPointer::setCursorPositionHint(const QPointF &surfaceLocal)
234{
235 Q_ASSERT(isValid());
236 zwp_locked_pointer_v1_set_cursor_position_hint(zwp_locked_pointer_v1: d->lockedpointer, surface_x: wl_fixed_from_double(d: surfaceLocal.x()), surface_y: wl_fixed_from_double(d: surfaceLocal.y()));
237}
238
239void LockedPointer::setRegion(Region *region)
240{
241 Q_ASSERT(isValid());
242 wl_region *wr = nullptr;
243 if (region) {
244 wr = *region;
245 }
246 zwp_locked_pointer_v1_set_region(zwp_locked_pointer_v1: d->lockedpointer, region: wr);
247}
248
249class Q_DECL_HIDDEN ConfinedPointer::Private
250{
251public:
252 Private(ConfinedPointer *q);
253
254 void setup(zwp_confined_pointer_v1 *arg);
255
256 WaylandPointer<zwp_confined_pointer_v1, zwp_confined_pointer_v1_destroy> confinedpointer;
257
258private:
259 ConfinedPointer *q;
260
261private:
262 static void confinedCallback(void *data, zwp_confined_pointer_v1 *zwp_confined_pointer_v1);
263 static void unconfinedCallback(void *data, zwp_confined_pointer_v1 *zwp_confined_pointer_v1);
264
265 static const zwp_confined_pointer_v1_listener s_listener;
266};
267
268const zwp_confined_pointer_v1_listener ConfinedPointer::Private::s_listener = {.confined: confinedCallback, .unconfined: unconfinedCallback};
269
270void ConfinedPointer::Private::confinedCallback(void *data, zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
271{
272 auto p = reinterpret_cast<ConfinedPointer::Private *>(data);
273 Q_ASSERT(p->confinedpointer == zwp_confined_pointer_v1);
274 Q_EMIT p->q->confined();
275}
276
277void ConfinedPointer::Private::unconfinedCallback(void *data, zwp_confined_pointer_v1 *zwp_confined_pointer_v1)
278{
279 auto p = reinterpret_cast<ConfinedPointer::Private *>(data);
280 Q_ASSERT(p->confinedpointer == zwp_confined_pointer_v1);
281 Q_EMIT p->q->unconfined();
282}
283
284ConfinedPointer::Private::Private(ConfinedPointer *q)
285 : q(q)
286{
287}
288
289ConfinedPointer::ConfinedPointer(QObject *parent)
290 : QObject(parent)
291 , d(new Private(this))
292{
293}
294
295void ConfinedPointer::Private::setup(zwp_confined_pointer_v1 *arg)
296{
297 Q_ASSERT(arg);
298 Q_ASSERT(!confinedpointer);
299 confinedpointer.setup(pointer: arg);
300 zwp_confined_pointer_v1_add_listener(zwp_confined_pointer_v1: confinedpointer, listener: &s_listener, data: this);
301}
302
303ConfinedPointer::~ConfinedPointer()
304{
305 release();
306}
307
308void ConfinedPointer::setup(zwp_confined_pointer_v1 *confinedpointer)
309{
310 d->setup(confinedpointer);
311}
312
313void ConfinedPointer::release()
314{
315 d->confinedpointer.release();
316}
317
318void ConfinedPointer::destroy()
319{
320 d->confinedpointer.destroy();
321}
322
323ConfinedPointer::operator zwp_confined_pointer_v1 *()
324{
325 return d->confinedpointer;
326}
327
328ConfinedPointer::operator zwp_confined_pointer_v1 *() const
329{
330 return d->confinedpointer;
331}
332
333bool ConfinedPointer::isValid() const
334{
335 return d->confinedpointer.isValid();
336}
337
338void ConfinedPointer::setRegion(Region *region)
339{
340 Q_ASSERT(isValid());
341 wl_region *wr = nullptr;
342 if (region) {
343 wr = *region;
344 }
345 zwp_confined_pointer_v1_set_region(zwp_confined_pointer_v1: d->confinedpointer, region: wr);
346}
347
348}
349}
350
351#include "moc_pointerconstraints.cpp"
352

source code of kwayland/src/client/pointerconstraints.cpp