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 "relativepointer.h"
7 #include "event_queue.h"
8 #include "pointer.h"
9 #include "wayland_pointer_p.h"
10 #include <QSizeF>
11 #include <wayland-relativepointer-unstable-v1-client-protocol.h>
12
13 namespace KWayland
14 {
15 namespace Client
16 {
17 class Q_DECL_HIDDEN RelativePointerManager::Private
18 {
19 public:
20 Private() = default;
21
22 WaylandPointer<zwp_relative_pointer_manager_v1, zwp_relative_pointer_manager_v1_destroy> relativepointermanagerunstablev1;
23 EventQueue *queue = nullptr;
24 };
25
RelativePointerManager(QObject * parent)26 RelativePointerManager::RelativePointerManager(QObject *parent)
27 : QObject(parent)
28 , d(new Private)
29 {
30 }
31
~RelativePointerManager()32 RelativePointerManager::~RelativePointerManager()
33 {
34 release();
35 }
36
setup(zwp_relative_pointer_manager_v1 * relativepointermanagerunstablev1)37 void RelativePointerManager::setup(zwp_relative_pointer_manager_v1 *relativepointermanagerunstablev1)
38 {
39 Q_ASSERT(relativepointermanagerunstablev1);
40 Q_ASSERT(!d->relativepointermanagerunstablev1);
41 d->relativepointermanagerunstablev1.setup(relativepointermanagerunstablev1);
42 }
43
release()44 void RelativePointerManager::release()
45 {
46 d->relativepointermanagerunstablev1.release();
47 }
48
destroy()49 void RelativePointerManager::destroy()
50 {
51 d->relativepointermanagerunstablev1.destroy();
52 }
53
setEventQueue(EventQueue * queue)54 void RelativePointerManager::setEventQueue(EventQueue *queue)
55 {
56 d->queue = queue;
57 }
58
eventQueue()59 EventQueue *RelativePointerManager::eventQueue()
60 {
61 return d->queue;
62 }
63
operator zwp_relative_pointer_manager_v1*()64 RelativePointerManager::operator zwp_relative_pointer_manager_v1 *()
65 {
66 return d->relativepointermanagerunstablev1;
67 }
68
operator zwp_relative_pointer_manager_v1*() const69 RelativePointerManager::operator zwp_relative_pointer_manager_v1 *() const
70 {
71 return d->relativepointermanagerunstablev1;
72 }
73
isValid() const74 bool RelativePointerManager::isValid() const
75 {
76 return d->relativepointermanagerunstablev1.isValid();
77 }
78
createRelativePointer(Pointer * pointer,QObject * parent)79 RelativePointer *RelativePointerManager::createRelativePointer(Pointer *pointer, QObject *parent)
80 {
81 Q_ASSERT(isValid());
82 RelativePointer *p = new RelativePointer(parent);
83 auto w = zwp_relative_pointer_manager_v1_get_relative_pointer(d->relativepointermanagerunstablev1, *pointer);
84 if (d->queue) {
85 d->queue->addProxy(w);
86 }
87 p->setup(w);
88 return p;
89 }
90
91 class Q_DECL_HIDDEN RelativePointer::Private
92 {
93 public:
94 Private(RelativePointer *q);
95
96 void setup(zwp_relative_pointer_v1 *relativepointerunstablev1);
97
98 WaylandPointer<zwp_relative_pointer_v1, zwp_relative_pointer_v1_destroy> relativepointerunstablev1;
99
100 private:
101 static void relativeMotionCallback(void *data,
102 zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
103 uint32_t utime_hi,
104 uint32_t utime_lo,
105 wl_fixed_t dx,
106 wl_fixed_t dy,
107 wl_fixed_t dx_unaccel,
108 wl_fixed_t dy_unaccel);
109
110 RelativePointer *q;
111
112 static const zwp_relative_pointer_v1_listener s_listener;
113 };
114
Private(RelativePointer * q)115 RelativePointer::Private::Private(RelativePointer *q)
116 : q(q)
117 {
118 }
119
120 const zwp_relative_pointer_v1_listener RelativePointer::Private::s_listener = {relativeMotionCallback};
121
relativeMotionCallback(void * data,zwp_relative_pointer_v1 * zwp_relative_pointer_v1,uint32_t utime_hi,uint32_t utime_lo,wl_fixed_t dx,wl_fixed_t dy,wl_fixed_t dx_unaccel,wl_fixed_t dy_unaccel)122 void RelativePointer::Private::relativeMotionCallback(void *data,
123 zwp_relative_pointer_v1 *zwp_relative_pointer_v1,
124 uint32_t utime_hi,
125 uint32_t utime_lo,
126 wl_fixed_t dx,
127 wl_fixed_t dy,
128 wl_fixed_t dx_unaccel,
129 wl_fixed_t dy_unaccel)
130 {
131 auto p = reinterpret_cast<RelativePointer::Private *>(data);
132 Q_ASSERT(p->relativepointerunstablev1 == zwp_relative_pointer_v1);
133 const QSizeF delta(wl_fixed_to_double(dx), wl_fixed_to_double(dy));
134 const QSizeF deltaNonAccel(wl_fixed_to_double(dx_unaccel), wl_fixed_to_double(dy_unaccel));
135 const quint64 timestamp = quint64(utime_lo) | (quint64(utime_hi) << 32);
136 Q_EMIT p->q->relativeMotion(delta, deltaNonAccel, timestamp);
137 }
138
setup(zwp_relative_pointer_v1 * v1)139 void RelativePointer::Private::setup(zwp_relative_pointer_v1 *v1)
140 {
141 Q_ASSERT(v1);
142 Q_ASSERT(!relativepointerunstablev1);
143 relativepointerunstablev1.setup(v1);
144 zwp_relative_pointer_v1_add_listener(relativepointerunstablev1, &s_listener, this);
145 }
146
RelativePointer(QObject * parent)147 RelativePointer::RelativePointer(QObject *parent)
148 : QObject(parent)
149 , d(new Private(this))
150 {
151 }
152
~RelativePointer()153 RelativePointer::~RelativePointer()
154 {
155 release();
156 }
157
setup(zwp_relative_pointer_v1 * relativepointerunstablev1)158 void RelativePointer::setup(zwp_relative_pointer_v1 *relativepointerunstablev1)
159 {
160 d->setup(relativepointerunstablev1);
161 }
162
release()163 void RelativePointer::release()
164 {
165 d->relativepointerunstablev1.release();
166 }
167
destroy()168 void RelativePointer::destroy()
169 {
170 d->relativepointerunstablev1.destroy();
171 }
172
operator zwp_relative_pointer_v1*()173 RelativePointer::operator zwp_relative_pointer_v1 *()
174 {
175 return d->relativepointerunstablev1;
176 }
177
operator zwp_relative_pointer_v1*() const178 RelativePointer::operator zwp_relative_pointer_v1 *() const
179 {
180 return d->relativepointerunstablev1;
181 }
182
isValid() const183 bool RelativePointer::isValid() const
184 {
185 return d->relativepointerunstablev1.isValid();
186 }
187
188 }
189 }
190