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