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