1 /****************************************************************************
2 Copyright 2016 Martin Gräßlin <mgraesslin@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), which shall
10 act as a proxy defined in Section 6 of version 3 of the license.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 ****************************************************************************/
20 #include "relativepointer.h"
21 #include "event_queue.h"
22 #include "pointer.h"
23 #include "wayland_pointer_p.h"
24 #include <QSizeF>
25 #include <wayland-relativepointer-unstable-v1-client-protocol.h>
26
27 namespace Wrapland
28 {
29 namespace Client
30 {
31
32 class Q_DECL_HIDDEN RelativePointerManager::Private
33 {
34 public:
35 Private() = default;
36
37 WaylandPointer<zwp_relative_pointer_manager_v1, zwp_relative_pointer_manager_v1_destroy>
38 relativepointermanagerunstablev1;
39 EventQueue* queue = nullptr;
40 };
41
RelativePointerManager(QObject * parent)42 RelativePointerManager::RelativePointerManager(QObject* parent)
43 : QObject(parent)
44 , d(new Private)
45 {
46 }
47
~RelativePointerManager()48 RelativePointerManager::~RelativePointerManager()
49 {
50 release();
51 }
52
setup(zwp_relative_pointer_manager_v1 * relativepointermanagerunstablev1)53 void RelativePointerManager::setup(
54 zwp_relative_pointer_manager_v1* relativepointermanagerunstablev1)
55 {
56 Q_ASSERT(relativepointermanagerunstablev1);
57 Q_ASSERT(!d->relativepointermanagerunstablev1);
58 d->relativepointermanagerunstablev1.setup(relativepointermanagerunstablev1);
59 }
60
release()61 void RelativePointerManager::release()
62 {
63 d->relativepointermanagerunstablev1.release();
64 }
65
setEventQueue(EventQueue * queue)66 void RelativePointerManager::setEventQueue(EventQueue* queue)
67 {
68 d->queue = queue;
69 }
70
eventQueue()71 EventQueue* RelativePointerManager::eventQueue()
72 {
73 return d->queue;
74 }
75
operator zwp_relative_pointer_manager_v1*()76 RelativePointerManager::operator zwp_relative_pointer_manager_v1*()
77 {
78 return d->relativepointermanagerunstablev1;
79 }
80
operator zwp_relative_pointer_manager_v1*() const81 RelativePointerManager::operator zwp_relative_pointer_manager_v1*() const
82 {
83 return d->relativepointermanagerunstablev1;
84 }
85
isValid() const86 bool RelativePointerManager::isValid() const
87 {
88 return d->relativepointermanagerunstablev1.isValid();
89 }
90
createRelativePointer(Pointer * pointer,QObject * parent)91 RelativePointer* RelativePointerManager::createRelativePointer(Pointer* pointer, QObject* parent)
92 {
93 Q_ASSERT(isValid());
94 RelativePointer* p = new RelativePointer(parent);
95 auto w = zwp_relative_pointer_manager_v1_get_relative_pointer(
96 d->relativepointermanagerunstablev1, *pointer);
97 if (d->queue) {
98 d->queue->addProxy(w);
99 }
100 p->setup(w);
101 return p;
102 }
103
104 class Q_DECL_HIDDEN RelativePointer::Private
105 {
106 public:
107 Private(RelativePointer* q);
108
109 void setup(zwp_relative_pointer_v1* relativepointerunstablev1);
110
111 WaylandPointer<zwp_relative_pointer_v1, zwp_relative_pointer_v1_destroy>
112 relativepointerunstablev1;
113
114 private:
115 static void relativeMotionCallback(void* data,
116 zwp_relative_pointer_v1* zwp_relative_pointer_v1,
117 uint32_t utime_hi,
118 uint32_t utime_lo,
119 wl_fixed_t dx,
120 wl_fixed_t dy,
121 wl_fixed_t dx_unaccel,
122 wl_fixed_t dy_unaccel);
123
124 RelativePointer* q;
125
126 static const zwp_relative_pointer_v1_listener s_listener;
127 };
128
Private(RelativePointer * q)129 RelativePointer::Private::Private(RelativePointer* q)
130 : q(q)
131 {
132 }
133
134 const zwp_relative_pointer_v1_listener RelativePointer::Private::s_listener = {
135 relativeMotionCallback,
136 };
137
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)138 void RelativePointer::Private::relativeMotionCallback(
139 void* data,
140 zwp_relative_pointer_v1* zwp_relative_pointer_v1,
141 uint32_t utime_hi,
142 uint32_t utime_lo,
143 wl_fixed_t dx,
144 wl_fixed_t dy,
145 wl_fixed_t dx_unaccel,
146 wl_fixed_t dy_unaccel)
147 {
148 auto p = reinterpret_cast<RelativePointer::Private*>(data);
149 Q_ASSERT(p->relativepointerunstablev1 == zwp_relative_pointer_v1);
150 const QSizeF delta(wl_fixed_to_double(dx), wl_fixed_to_double(dy));
151 const QSizeF deltaNonAccel(wl_fixed_to_double(dx_unaccel), wl_fixed_to_double(dy_unaccel));
152 const quint64 timestamp = quint64(utime_lo) | (quint64(utime_hi) << 32);
153 emit p->q->relativeMotion(delta, deltaNonAccel, timestamp);
154 }
155
setup(zwp_relative_pointer_v1 * v1)156 void RelativePointer::Private::setup(zwp_relative_pointer_v1* v1)
157 {
158 Q_ASSERT(v1);
159 Q_ASSERT(!relativepointerunstablev1);
160 relativepointerunstablev1.setup(v1);
161 zwp_relative_pointer_v1_add_listener(relativepointerunstablev1, &s_listener, this);
162 }
163
RelativePointer(QObject * parent)164 RelativePointer::RelativePointer(QObject* parent)
165 : QObject(parent)
166 , d(new Private(this))
167 {
168 }
169
~RelativePointer()170 RelativePointer::~RelativePointer()
171 {
172 release();
173 }
174
setup(zwp_relative_pointer_v1 * relativepointerunstablev1)175 void RelativePointer::setup(zwp_relative_pointer_v1* relativepointerunstablev1)
176 {
177 d->setup(relativepointerunstablev1);
178 }
179
release()180 void RelativePointer::release()
181 {
182 d->relativepointerunstablev1.release();
183 }
184
operator zwp_relative_pointer_v1*()185 RelativePointer::operator zwp_relative_pointer_v1*()
186 {
187 return d->relativepointerunstablev1;
188 }
189
operator zwp_relative_pointer_v1*() const190 RelativePointer::operator zwp_relative_pointer_v1*() const
191 {
192 return d->relativepointerunstablev1;
193 }
194
isValid() const195 bool RelativePointer::isValid() const
196 {
197 return d->relativepointerunstablev1.isValid();
198 }
199
200 }
201 }
202