/* SPDX-FileCopyrightText: 2016 Martin Gräßlin SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL */ #include "pointerconstraints.h" #include "event_queue.h" #include "pointer.h" #include "region.h" #include "surface.h" #include "wayland_pointer_p.h" #include namespace KWayland { namespace Client { class Q_DECL_HIDDEN PointerConstraints::Private { public: Private() = default; void setup(zwp_pointer_constraints_v1 *arg); WaylandPointer pointerconstraints; EventQueue *queue = nullptr; }; PointerConstraints::PointerConstraints(QObject *parent) : QObject(parent) , d(new Private) { } void PointerConstraints::Private::setup(zwp_pointer_constraints_v1 *arg) { Q_ASSERT(arg); Q_ASSERT(!pointerconstraints); pointerconstraints.setup(arg); } PointerConstraints::~PointerConstraints() { release(); } void PointerConstraints::setup(zwp_pointer_constraints_v1 *pointerconstraints) { d->setup(pointerconstraints); } void PointerConstraints::release() { d->pointerconstraints.release(); } void PointerConstraints::destroy() { d->pointerconstraints.destroy(); } PointerConstraints::operator zwp_pointer_constraints_v1 *() { return d->pointerconstraints; } PointerConstraints::operator zwp_pointer_constraints_v1 *() const { return d->pointerconstraints; } bool PointerConstraints::isValid() const { return d->pointerconstraints.isValid(); } void PointerConstraints::setEventQueue(EventQueue *queue) { d->queue = queue; } EventQueue *PointerConstraints::eventQueue() { return d->queue; } LockedPointer *PointerConstraints::lockPointer(Surface *surface, Pointer *pointer, Region *region, LifeTime lifetime, QObject *parent) { Q_ASSERT(isValid()); auto p = new LockedPointer(parent); zwp_pointer_constraints_v1_lifetime lf; switch (lifetime) { case LifeTime::OneShot: lf = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT; break; case LifeTime::Persistent: lf = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT; break; default: Q_UNREACHABLE(); break; } wl_region *wr = nullptr; if (region) { wr = *region; } auto w = zwp_pointer_constraints_v1_lock_pointer(d->pointerconstraints, *surface, *pointer, wr, lf); if (d->queue) { d->queue->addProxy(w); } p->setup(w); return p; } ConfinedPointer *PointerConstraints::confinePointer(Surface *surface, Pointer *pointer, Region *region, LifeTime lifetime, QObject *parent) { Q_ASSERT(isValid()); auto p = new ConfinedPointer(parent); zwp_pointer_constraints_v1_lifetime lf; switch (lifetime) { case LifeTime::OneShot: lf = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_ONESHOT; break; case LifeTime::Persistent: lf = ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT; break; default: Q_UNREACHABLE(); break; } wl_region *wr = nullptr; if (region) { wr = *region; } auto w = zwp_pointer_constraints_v1_confine_pointer(d->pointerconstraints, *surface, *pointer, wr, lf); if (d->queue) { d->queue->addProxy(w); } p->setup(w); return p; } class Q_DECL_HIDDEN LockedPointer::Private { public: Private(LockedPointer *q); void setup(zwp_locked_pointer_v1 *arg); WaylandPointer lockedpointer; private: LockedPointer *q; private: static void lockedCallback(void *data, zwp_locked_pointer_v1 *zwp_locked_pointer_v1); static void unlockedCallback(void *data, zwp_locked_pointer_v1 *zwp_locked_pointer_v1); static const zwp_locked_pointer_v1_listener s_listener; }; const zwp_locked_pointer_v1_listener LockedPointer::Private::s_listener = {lockedCallback, unlockedCallback}; void LockedPointer::Private::lockedCallback(void *data, zwp_locked_pointer_v1 *zwp_locked_pointer_v1) { auto p = reinterpret_cast(data); Q_ASSERT(p->lockedpointer == zwp_locked_pointer_v1); Q_EMIT p->q->locked(); } void LockedPointer::Private::unlockedCallback(void *data, zwp_locked_pointer_v1 *zwp_locked_pointer_v1) { auto p = reinterpret_cast(data); Q_ASSERT(p->lockedpointer == zwp_locked_pointer_v1); Q_EMIT p->q->unlocked(); } LockedPointer::Private::Private(LockedPointer *q) : q(q) { } LockedPointer::LockedPointer(QObject *parent) : QObject(parent) , d(new Private(this)) { } void LockedPointer::Private::setup(zwp_locked_pointer_v1 *arg) { Q_ASSERT(arg); Q_ASSERT(!lockedpointer); lockedpointer.setup(arg); zwp_locked_pointer_v1_add_listener(lockedpointer, &s_listener, this); } LockedPointer::~LockedPointer() { release(); } void LockedPointer::setup(zwp_locked_pointer_v1 *lockedpointer) { d->setup(lockedpointer); } void LockedPointer::release() { d->lockedpointer.release(); } void LockedPointer::destroy() { d->lockedpointer.destroy(); } LockedPointer::operator zwp_locked_pointer_v1 *() { return d->lockedpointer; } LockedPointer::operator zwp_locked_pointer_v1 *() const { return d->lockedpointer; } bool LockedPointer::isValid() const { return d->lockedpointer.isValid(); } void LockedPointer::setCursorPositionHint(const QPointF &surfaceLocal) { Q_ASSERT(isValid()); zwp_locked_pointer_v1_set_cursor_position_hint(d->lockedpointer, wl_fixed_from_double(surfaceLocal.x()), wl_fixed_from_double(surfaceLocal.y())); } void LockedPointer::setRegion(Region *region) { Q_ASSERT(isValid()); wl_region *wr = nullptr; if (region) { wr = *region; } zwp_locked_pointer_v1_set_region(d->lockedpointer, wr); } class Q_DECL_HIDDEN ConfinedPointer::Private { public: Private(ConfinedPointer *q); void setup(zwp_confined_pointer_v1 *arg); WaylandPointer confinedpointer; private: ConfinedPointer *q; private: static void confinedCallback(void *data, zwp_confined_pointer_v1 *zwp_confined_pointer_v1); static void unconfinedCallback(void *data, zwp_confined_pointer_v1 *zwp_confined_pointer_v1); static const zwp_confined_pointer_v1_listener s_listener; }; const zwp_confined_pointer_v1_listener ConfinedPointer::Private::s_listener = {confinedCallback, unconfinedCallback}; void ConfinedPointer::Private::confinedCallback(void *data, zwp_confined_pointer_v1 *zwp_confined_pointer_v1) { auto p = reinterpret_cast(data); Q_ASSERT(p->confinedpointer == zwp_confined_pointer_v1); Q_EMIT p->q->confined(); } void ConfinedPointer::Private::unconfinedCallback(void *data, zwp_confined_pointer_v1 *zwp_confined_pointer_v1) { auto p = reinterpret_cast(data); Q_ASSERT(p->confinedpointer == zwp_confined_pointer_v1); Q_EMIT p->q->unconfined(); } ConfinedPointer::Private::Private(ConfinedPointer *q) : q(q) { } ConfinedPointer::ConfinedPointer(QObject *parent) : QObject(parent) , d(new Private(this)) { } void ConfinedPointer::Private::setup(zwp_confined_pointer_v1 *arg) { Q_ASSERT(arg); Q_ASSERT(!confinedpointer); confinedpointer.setup(arg); zwp_confined_pointer_v1_add_listener(confinedpointer, &s_listener, this); } ConfinedPointer::~ConfinedPointer() { release(); } void ConfinedPointer::setup(zwp_confined_pointer_v1 *confinedpointer) { d->setup(confinedpointer); } void ConfinedPointer::release() { d->confinedpointer.release(); } void ConfinedPointer::destroy() { d->confinedpointer.destroy(); } ConfinedPointer::operator zwp_confined_pointer_v1 *() { return d->confinedpointer; } ConfinedPointer::operator zwp_confined_pointer_v1 *() const { return d->confinedpointer; } bool ConfinedPointer::isValid() const { return d->confinedpointer.isValid(); } void ConfinedPointer::setRegion(Region *region) { Q_ASSERT(isValid()); wl_region *wr = nullptr; if (region) { wr = *region; } zwp_confined_pointer_v1_set_region(d->confinedpointer, wr); } } } #include "moc_pointerconstraints.cpp"