KWaylandServer

pointerconstraints_v1_interface.cpp
1 /*
2  SPDX-FileCopyrightText: 2016 Martin Gräßlin <[email protected]>
3  SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 
8 #include "pointerconstraints_v1_interface.h"
9 #include "display.h"
10 #include "pointer_interface.h"
11 #include "pointerconstraints_v1_interface_p.h"
12 #include "region_interface_p.h"
13 #include "surface_interface_p.h"
14 
15 namespace KWaylandServer
16 {
17 static const int s_version = 1;
18 
19 PointerConstraintsV1InterfacePrivate::PointerConstraintsV1InterfacePrivate(Display *display)
20  : QtWaylandServer::zwp_pointer_constraints_v1(*display, s_version)
21 {
22 }
23 
24 static QRegion regionFromResource(::wl_resource *resource)
25 {
26  const RegionInterface *region = RegionInterface::get(resource);
27  return region ? region->region() : QRegion();
28 }
29 
30 void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_lock_pointer(Resource *resource,
31  uint32_t id,
32  ::wl_resource *surface_resource,
33  ::wl_resource *pointer_resource,
34  ::wl_resource *region_resource,
35  uint32_t lifetime)
36 {
37  PointerInterface *pointer = PointerInterface::get(pointer_resource);
38  if (!pointer) {
39  wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid pointer");
40  return;
41  }
42 
43  SurfaceInterface *surface = SurfaceInterface::get(surface_resource);
44  if (!surface) {
45  wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid surface");
46  return;
47  }
48 
49  if (surface->lockedPointer() || surface->confinedPointer()) {
50  wl_resource_post_error(resource->handle, error_already_constrained, "the surface is already constrained");
51  return;
52  }
53 
54  if (lifetime != lifetime_oneshot && lifetime != lifetime_persistent) {
55  wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "unknown lifetime %d", lifetime);
56  return;
57  }
58 
59  wl_resource *lockedPointerResource = wl_resource_create(resource->client(), &zwp_locked_pointer_v1_interface, resource->version(), id);
60  if (!lockedPointerResource) {
61  wl_resource_post_no_memory(resource->handle);
62  return;
63  }
64 
65  auto lockedPointer = new LockedPointerV1Interface(LockedPointerV1Interface::LifeTime(lifetime), regionFromResource(region_resource), lockedPointerResource);
66 
67  SurfaceInterfacePrivate::get(surface)->installPointerConstraint(lockedPointer);
68 }
69 
70 void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_confine_pointer(Resource *resource,
71  uint32_t id,
72  ::wl_resource *surface_resource,
73  ::wl_resource *pointer_resource,
74  ::wl_resource *region_resource,
75  uint32_t lifetime)
76 {
77  PointerInterface *pointer = PointerInterface::get(pointer_resource);
78  if (!pointer) {
79  wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid pointer");
80  return;
81  }
82 
83  SurfaceInterface *surface = SurfaceInterface::get(surface_resource);
84  if (!surface) {
85  wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid surface");
86  return;
87  }
88 
89  if (lifetime != lifetime_oneshot && lifetime != lifetime_persistent) {
90  wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "unknown lifetime %d", lifetime);
91  return;
92  }
93 
94  if (surface->lockedPointer() || surface->confinedPointer()) {
95  wl_resource_post_error(resource->handle, error_already_constrained, "the surface is already constrained");
96  return;
97  }
98 
99  wl_resource *confinedPointerResource = wl_resource_create(resource->client(), &zwp_confined_pointer_v1_interface, resource->version(), id);
100  if (!confinedPointerResource) {
101  wl_resource_post_no_memory(resource->handle);
102  return;
103  }
104 
105  auto confinedPointer =
106  new ConfinedPointerV1Interface(ConfinedPointerV1Interface::LifeTime(lifetime), regionFromResource(region_resource), confinedPointerResource);
107 
108  SurfaceInterfacePrivate::get(surface)->installPointerConstraint(confinedPointer);
109 }
110 
111 void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_destroy(Resource *resource)
112 {
113  wl_resource_destroy(resource->handle);
114 }
115 
116 PointerConstraintsV1Interface::PointerConstraintsV1Interface(Display *display, QObject *parent)
117  : QObject(parent)
118  , d(new PointerConstraintsV1InterfacePrivate(display))
119 {
120 }
121 
122 PointerConstraintsV1Interface::~PointerConstraintsV1Interface()
123 {
124 }
125 
126 LockedPointerV1InterfacePrivate *LockedPointerV1InterfacePrivate::get(LockedPointerV1Interface *q)
127 {
128  return q->d.data();
129 }
130 
131 LockedPointerV1InterfacePrivate::LockedPointerV1InterfacePrivate(LockedPointerV1Interface *q,
132  LockedPointerV1Interface::LifeTime lifeTime,
133  const QRegion &region,
134  ::wl_resource *resource)
135  : QtWaylandServer::zwp_locked_pointer_v1(resource)
136  , q(q)
137  , lifeTime(lifeTime)
138  , region(region)
139 {
140 }
141 
142 void LockedPointerV1InterfacePrivate::commit()
143 {
144  if (hasPendingRegion) {
145  region = pendingRegion;
146  hasPendingRegion = false;
147  Q_EMIT q->regionChanged();
148  }
149  if (hasPendingHint) {
150  hint = pendingHint;
151  hasPendingHint = false;
152  Q_EMIT q->cursorPositionHintChanged();
153  }
154 }
155 
156 void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_destroy_resource(Resource *resource)
157 {
158  Q_UNUSED(resource)
159  Q_EMIT q->aboutToBeDestroyed();
160  delete q;
161 }
162 
163 void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_destroy(Resource *resource)
164 {
165  wl_resource_destroy(resource->handle);
166 }
167 
168 void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_set_cursor_position_hint(Resource *resource, wl_fixed_t surface_x, wl_fixed_t surface_y)
169 {
170  Q_UNUSED(resource)
171  pendingHint = QPointF(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y));
172  hasPendingHint = true;
173 }
174 
175 void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_set_region(Resource *resource, ::wl_resource *region_resource)
176 {
177  Q_UNUSED(resource)
178  pendingRegion = regionFromResource(region_resource);
179  hasPendingRegion = true;
180 }
181 
182 LockedPointerV1Interface::LockedPointerV1Interface(LifeTime lifeTime, const QRegion &region, ::wl_resource *resource)
183  : d(new LockedPointerV1InterfacePrivate(this, lifeTime, region, resource))
184 {
185 }
186 
187 LockedPointerV1Interface::~LockedPointerV1Interface()
188 {
189 }
190 
191 LockedPointerV1Interface::LifeTime LockedPointerV1Interface::lifeTime() const
192 {
193  return d->lifeTime;
194 }
195 
197 {
198  return d->region;
199 }
200 
202 {
203  return d->hint;
204 }
205 
207 {
208  return d->isLocked;
209 }
210 
212 {
213  if (d->isLocked == locked) {
214  return;
215  }
216  if (!locked) {
217  d->hint = QPointF(-1, -1);
218  }
219  d->isLocked = locked;
220  if (d->isLocked) {
221  d->send_locked();
222  } else {
223  d->send_unlocked();
224  }
225  Q_EMIT lockedChanged();
226 }
227 
228 ConfinedPointerV1InterfacePrivate *ConfinedPointerV1InterfacePrivate::get(ConfinedPointerV1Interface *q)
229 {
230  return q->d.data();
231 }
232 
233 ConfinedPointerV1InterfacePrivate::ConfinedPointerV1InterfacePrivate(ConfinedPointerV1Interface *q,
234  ConfinedPointerV1Interface::LifeTime lifeTime,
235  const QRegion &region,
236  ::wl_resource *resource)
237  : QtWaylandServer::zwp_confined_pointer_v1(resource)
238  , q(q)
239  , lifeTime(lifeTime)
240  , region(region)
241 {
242 }
243 
244 void ConfinedPointerV1InterfacePrivate::commit()
245 {
246  if (hasPendingRegion) {
247  region = pendingRegion;
248  hasPendingRegion = false;
249  Q_EMIT q->regionChanged();
250  }
251 }
252 
253 void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_destroy_resource(Resource *resource)
254 {
255  Q_UNUSED(resource)
256  delete q;
257 }
258 
259 void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_destroy(Resource *resource)
260 {
261  wl_resource_destroy(resource->handle);
262 }
263 
264 void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_set_region(Resource *resource, ::wl_resource *region_resource)
265 {
266  Q_UNUSED(resource)
267  pendingRegion = regionFromResource(region_resource);
268  hasPendingRegion = true;
269 }
270 
271 ConfinedPointerV1Interface::ConfinedPointerV1Interface(LifeTime lifeTime, const QRegion &region, ::wl_resource *resource)
272  : d(new ConfinedPointerV1InterfacePrivate(this, lifeTime, region, resource))
273 {
274 }
275 
276 ConfinedPointerV1Interface::~ConfinedPointerV1Interface()
277 {
278 }
279 
280 ConfinedPointerV1Interface::LifeTime ConfinedPointerV1Interface::lifeTime() const
281 {
282  return d->lifeTime;
283 }
284 
286 {
287  return d->region;
288 }
289 
291 {
292  return d->isConfined;
293 }
294 
296 {
297  if (d->isConfined == confined) {
298  return;
299  }
300  d->isConfined = confined;
301  if (d->isConfined) {
302  d->send_confined();
303  } else {
304  d->send_unconfined();
305  }
306  Q_EMIT confinedChanged();
307 }
308 
309 } // namespace KWaylandServer
The ConfinedPointerV1Interface gets installed on a SurfaceInterface.
QRegion region() const
The intersection of this region and the input region of the SurfaceInterface is used to determine whe...
QPointF cursorPositionHint() const
Indicates where the mouse cursor should be positioned after it has been unlocked again.
void regionChanged()
Emitted whenever the region changes.
static PointerInterface * get(wl_resource *native)
void setConfined(bool confined)
Activates or deactivates the confinement.
bool isLocked() const
Whether the Compositor set this pointer lock to be active.
static SurfaceInterface * get(wl_resource *native)
bool isConfined() const
Whether the Compositor set this pointer confinement to be active.
QAction * hint(const QObject *recvr, const char *slot, QObject *parent)
T * data() const const
void setLocked(bool locked)
Activates or deactivates the lock.
PointerInterface * pointer() const
The PointerInterface this Cursor belongs to.
QRegion region() const
The intersection of this region and the input region of the SurfaceInterface is used to determine whe...
QObject * parent() const const
Q_EMITQ_EMIT
SurfaceInterface * surface() const
The SurfaceInterface for the image content of the Cursor.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 23 2021 23:08:28 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.