File indexing completed on 2024-05-19 16:35:24
0001 /* 0002 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org> 0003 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 0008 #include "pointerconstraints_v1_interface.h" 0009 #include "display.h" 0010 #include "pointer_interface.h" 0011 #include "pointerconstraints_v1_interface_p.h" 0012 #include "region_interface_p.h" 0013 #include "surface_interface_p.h" 0014 0015 namespace KWaylandServer 0016 { 0017 static const int s_version = 1; 0018 0019 static QRegion mapScaleOverride(const QRegion ®ion, qreal scaleOverride) 0020 { 0021 QRegion out; 0022 for (const QRect &rect : region) { 0023 out += QRect(rect.topLeft() / scaleOverride, rect.size() / scaleOverride); 0024 } 0025 return out; 0026 } 0027 0028 PointerConstraintsV1InterfacePrivate::PointerConstraintsV1InterfacePrivate(Display *display) 0029 : QtWaylandServer::zwp_pointer_constraints_v1(*display, s_version) 0030 { 0031 } 0032 0033 static QRegion regionFromResource(::wl_resource *resource) 0034 { 0035 const RegionInterface *region = RegionInterface::get(resource); 0036 return region ? region->region() : QRegion(); 0037 } 0038 0039 void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_lock_pointer(Resource *resource, 0040 uint32_t id, 0041 ::wl_resource *surface_resource, 0042 ::wl_resource *pointer_resource, 0043 ::wl_resource *region_resource, 0044 uint32_t lifetime) 0045 { 0046 PointerInterface *pointer = PointerInterface::get(pointer_resource); 0047 if (!pointer) { 0048 wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid pointer"); 0049 return; 0050 } 0051 0052 SurfaceInterface *surface = SurfaceInterface::get(surface_resource); 0053 if (!surface) { 0054 wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid surface"); 0055 return; 0056 } 0057 0058 if (surface->lockedPointer() || surface->confinedPointer()) { 0059 wl_resource_post_error(resource->handle, error_already_constrained, "the surface is already constrained"); 0060 return; 0061 } 0062 0063 if (lifetime != lifetime_oneshot && lifetime != lifetime_persistent) { 0064 wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "unknown lifetime %d", lifetime); 0065 return; 0066 } 0067 0068 wl_resource *lockedPointerResource = wl_resource_create(resource->client(), &zwp_locked_pointer_v1_interface, resource->version(), id); 0069 if (!lockedPointerResource) { 0070 wl_resource_post_no_memory(resource->handle); 0071 return; 0072 } 0073 0074 new LockedPointerV1Interface(surface, LockedPointerV1Interface::LifeTime(lifetime), regionFromResource(region_resource), lockedPointerResource); 0075 } 0076 0077 void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_confine_pointer(Resource *resource, 0078 uint32_t id, 0079 ::wl_resource *surface_resource, 0080 ::wl_resource *pointer_resource, 0081 ::wl_resource *region_resource, 0082 uint32_t lifetime) 0083 { 0084 PointerInterface *pointer = PointerInterface::get(pointer_resource); 0085 if (!pointer) { 0086 wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid pointer"); 0087 return; 0088 } 0089 0090 SurfaceInterface *surface = SurfaceInterface::get(surface_resource); 0091 if (!surface) { 0092 wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid surface"); 0093 return; 0094 } 0095 0096 if (lifetime != lifetime_oneshot && lifetime != lifetime_persistent) { 0097 wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, "unknown lifetime %d", lifetime); 0098 return; 0099 } 0100 0101 if (surface->lockedPointer() || surface->confinedPointer()) { 0102 wl_resource_post_error(resource->handle, error_already_constrained, "the surface is already constrained"); 0103 return; 0104 } 0105 0106 wl_resource *confinedPointerResource = wl_resource_create(resource->client(), &zwp_confined_pointer_v1_interface, resource->version(), id); 0107 if (!confinedPointerResource) { 0108 wl_resource_post_no_memory(resource->handle); 0109 return; 0110 } 0111 0112 new ConfinedPointerV1Interface(surface, ConfinedPointerV1Interface::LifeTime(lifetime), regionFromResource(region_resource), confinedPointerResource); 0113 } 0114 0115 void PointerConstraintsV1InterfacePrivate::zwp_pointer_constraints_v1_destroy(Resource *resource) 0116 { 0117 wl_resource_destroy(resource->handle); 0118 } 0119 0120 PointerConstraintsV1Interface::PointerConstraintsV1Interface(Display *display, QObject *parent) 0121 : QObject(parent) 0122 , d(new PointerConstraintsV1InterfacePrivate(display)) 0123 { 0124 } 0125 0126 PointerConstraintsV1Interface::~PointerConstraintsV1Interface() 0127 { 0128 } 0129 0130 LockedPointerV1InterfacePrivate *LockedPointerV1InterfacePrivate::get(LockedPointerV1Interface *q) 0131 { 0132 return q->d.get(); 0133 } 0134 0135 LockedPointerV1InterfacePrivate::LockedPointerV1InterfacePrivate(LockedPointerV1Interface *q, 0136 SurfaceInterface *surface, 0137 LockedPointerV1Interface::LifeTime lifeTime, 0138 const QRegion ®ion, 0139 ::wl_resource *resource) 0140 : QtWaylandServer::zwp_locked_pointer_v1(resource) 0141 , q(q) 0142 , surface(surface) 0143 , lifeTime(lifeTime) 0144 , region(region) 0145 { 0146 } 0147 0148 void LockedPointerV1InterfacePrivate::commit() 0149 { 0150 qreal scaleOverride = surface->scaleOverride(); 0151 if (hasPendingRegion) { 0152 region = mapScaleOverride(pendingRegion, scaleOverride); 0153 hasPendingRegion = false; 0154 Q_EMIT q->regionChanged(); 0155 } 0156 if (hasPendingHint) { 0157 hint = pendingHint / scaleOverride; 0158 hasPendingHint = false; 0159 Q_EMIT q->cursorPositionHintChanged(); 0160 } 0161 } 0162 0163 void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_destroy_resource(Resource *resource) 0164 { 0165 Q_EMIT q->aboutToBeDestroyed(); 0166 delete q; 0167 } 0168 0169 void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_destroy(Resource *resource) 0170 { 0171 wl_resource_destroy(resource->handle); 0172 } 0173 0174 void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_set_cursor_position_hint(Resource *resource, wl_fixed_t surface_x, wl_fixed_t surface_y) 0175 { 0176 pendingHint = QPointF(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); 0177 hasPendingHint = true; 0178 } 0179 0180 void LockedPointerV1InterfacePrivate::zwp_locked_pointer_v1_set_region(Resource *resource, ::wl_resource *region_resource) 0181 { 0182 pendingRegion = regionFromResource(region_resource); 0183 hasPendingRegion = true; 0184 } 0185 0186 LockedPointerV1Interface::LockedPointerV1Interface(SurfaceInterface *surface, LifeTime lifeTime, const QRegion ®ion, ::wl_resource *resource) 0187 : d(new LockedPointerV1InterfacePrivate(this, surface, lifeTime, region, resource)) 0188 { 0189 SurfaceInterfacePrivate::get(surface)->installPointerConstraint(this); 0190 } 0191 0192 LockedPointerV1Interface::~LockedPointerV1Interface() 0193 { 0194 } 0195 0196 LockedPointerV1Interface::LifeTime LockedPointerV1Interface::lifeTime() const 0197 { 0198 return d->lifeTime; 0199 } 0200 0201 QRegion LockedPointerV1Interface::region() const 0202 { 0203 return d->region; 0204 } 0205 0206 QPointF LockedPointerV1Interface::cursorPositionHint() const 0207 { 0208 return d->hint; 0209 } 0210 0211 bool LockedPointerV1Interface::isLocked() const 0212 { 0213 return d->isLocked; 0214 } 0215 0216 void LockedPointerV1Interface::setLocked(bool locked) 0217 { 0218 if (d->isLocked == locked) { 0219 return; 0220 } 0221 if (!locked) { 0222 d->hint = QPointF(-1, -1); 0223 } 0224 d->isLocked = locked; 0225 if (d->isLocked) { 0226 d->send_locked(); 0227 } else { 0228 d->send_unlocked(); 0229 } 0230 Q_EMIT lockedChanged(); 0231 } 0232 0233 ConfinedPointerV1InterfacePrivate *ConfinedPointerV1InterfacePrivate::get(ConfinedPointerV1Interface *q) 0234 { 0235 return q->d.get(); 0236 } 0237 0238 ConfinedPointerV1InterfacePrivate::ConfinedPointerV1InterfacePrivate(ConfinedPointerV1Interface *q, 0239 SurfaceInterface *surface, 0240 ConfinedPointerV1Interface::LifeTime lifeTime, 0241 const QRegion ®ion, 0242 ::wl_resource *resource) 0243 : QtWaylandServer::zwp_confined_pointer_v1(resource) 0244 , q(q) 0245 , surface(surface) 0246 , lifeTime(lifeTime) 0247 , region(region) 0248 { 0249 } 0250 0251 void ConfinedPointerV1InterfacePrivate::commit() 0252 { 0253 qreal scaleOverride = surface->scaleOverride(); 0254 if (hasPendingRegion) { 0255 region = mapScaleOverride(pendingRegion, scaleOverride); 0256 hasPendingRegion = false; 0257 Q_EMIT q->regionChanged(); 0258 } 0259 } 0260 0261 void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_destroy_resource(Resource *resource) 0262 { 0263 delete q; 0264 } 0265 0266 void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_destroy(Resource *resource) 0267 { 0268 wl_resource_destroy(resource->handle); 0269 } 0270 0271 void ConfinedPointerV1InterfacePrivate::zwp_confined_pointer_v1_set_region(Resource *resource, ::wl_resource *region_resource) 0272 { 0273 pendingRegion = regionFromResource(region_resource); 0274 hasPendingRegion = true; 0275 } 0276 0277 ConfinedPointerV1Interface::ConfinedPointerV1Interface(SurfaceInterface *surface, LifeTime lifeTime, const QRegion ®ion, ::wl_resource *resource) 0278 : d(new ConfinedPointerV1InterfacePrivate(this, surface, lifeTime, region, resource)) 0279 { 0280 SurfaceInterfacePrivate::get(surface)->installPointerConstraint(this); 0281 } 0282 0283 ConfinedPointerV1Interface::~ConfinedPointerV1Interface() 0284 { 0285 } 0286 0287 ConfinedPointerV1Interface::LifeTime ConfinedPointerV1Interface::lifeTime() const 0288 { 0289 return d->lifeTime; 0290 } 0291 0292 QRegion ConfinedPointerV1Interface::region() const 0293 { 0294 return d->region; 0295 } 0296 0297 bool ConfinedPointerV1Interface::isConfined() const 0298 { 0299 return d->isConfined; 0300 } 0301 0302 void ConfinedPointerV1Interface::setConfined(bool confined) 0303 { 0304 if (d->isConfined == confined) { 0305 return; 0306 } 0307 d->isConfined = confined; 0308 if (d->isConfined) { 0309 d->send_confined(); 0310 } else { 0311 d->send_unconfined(); 0312 } 0313 Q_EMIT confinedChanged(); 0314 } 0315 0316 } // namespace KWaylandServer