File indexing completed on 2024-05-19 16:35:27
0001 /* 0002 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "shadow_interface.h" 0007 #include "clientbuffer.h" 0008 #include "display.h" 0009 #include "surface_interface_p.h" 0010 0011 #include <qwayland-server-shadow.h> 0012 0013 namespace KWaylandServer 0014 { 0015 static const quint32 s_version = 2; 0016 0017 class ShadowManagerInterfacePrivate : public QtWaylandServer::org_kde_kwin_shadow_manager 0018 { 0019 public: 0020 ShadowManagerInterfacePrivate(ShadowManagerInterface *_q, Display *display); 0021 0022 ShadowManagerInterface *q; 0023 Display *display; 0024 0025 protected: 0026 void org_kde_kwin_shadow_manager_create(Resource *resource, uint32_t id, wl_resource *surface) override; 0027 void org_kde_kwin_shadow_manager_unset(Resource *resource, wl_resource *surface) override; 0028 void org_kde_kwin_shadow_manager_destroy(Resource *resource) override; 0029 }; 0030 0031 ShadowManagerInterfacePrivate::ShadowManagerInterfacePrivate(ShadowManagerInterface *_q, Display *display) 0032 : QtWaylandServer::org_kde_kwin_shadow_manager(*display, s_version) 0033 , q(_q) 0034 , display(display) 0035 { 0036 } 0037 0038 void ShadowManagerInterfacePrivate::org_kde_kwin_shadow_manager_destroy(Resource *resource) 0039 { 0040 wl_resource_destroy(resource->handle); 0041 } 0042 0043 void ShadowManagerInterfacePrivate::org_kde_kwin_shadow_manager_create(Resource *resource, uint32_t id, wl_resource *surface) 0044 { 0045 SurfaceInterface *s = SurfaceInterface::get(surface); 0046 if (!s) { 0047 wl_resource_post_error(resource->handle, 0, "Invalid surface"); 0048 return; 0049 } 0050 0051 wl_resource *shadow_resource = wl_resource_create(resource->client(), &org_kde_kwin_shadow_interface, resource->version(), id); 0052 if (!shadow_resource) { 0053 wl_client_post_no_memory(resource->client()); 0054 return; 0055 } 0056 0057 auto shadow = new ShadowInterface(q, shadow_resource); 0058 0059 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(s); 0060 surfacePrivate->setShadow(QPointer<ShadowInterface>(shadow)); 0061 } 0062 0063 void ShadowManagerInterfacePrivate::org_kde_kwin_shadow_manager_unset(Resource *resource, wl_resource *surface) 0064 { 0065 SurfaceInterface *s = SurfaceInterface::get(surface); 0066 if (!s) { 0067 wl_resource_post_error(resource->handle, 0, "Invalid surface"); 0068 return; 0069 } 0070 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(s); 0071 surfacePrivate->setShadow(QPointer<ShadowInterface>()); 0072 } 0073 0074 ShadowManagerInterface::ShadowManagerInterface(Display *display, QObject *parent) 0075 : QObject(parent) 0076 , d(new ShadowManagerInterfacePrivate(this, display)) 0077 { 0078 } 0079 0080 ShadowManagerInterface::~ShadowManagerInterface() = default; 0081 0082 Display *ShadowManagerInterface::display() const 0083 { 0084 return d->display; 0085 } 0086 0087 class ShadowInterfacePrivate : public QtWaylandServer::org_kde_kwin_shadow 0088 { 0089 public: 0090 ShadowInterfacePrivate(ShadowInterface *_q, wl_resource *resource); 0091 ~ShadowInterfacePrivate(); 0092 0093 struct State 0094 { 0095 enum Flags { 0096 None = 0, 0097 LeftBuffer = 1 << 0, 0098 TopLeftBuffer = 1 << 1, 0099 TopBuffer = 1 << 2, 0100 TopRightBuffer = 1 << 3, 0101 RightBuffer = 1 << 4, 0102 BottomRightBuffer = 1 << 5, 0103 BottomBuffer = 1 << 6, 0104 BottomLeftBuffer = 1 << 7, 0105 Offset = 1 << 8, 0106 }; 0107 QPointer<ClientBuffer> left; 0108 QPointer<ClientBuffer> topLeft; 0109 QPointer<ClientBuffer> top; 0110 QPointer<ClientBuffer> topRight; 0111 QPointer<ClientBuffer> right; 0112 QPointer<ClientBuffer> bottomRight; 0113 QPointer<ClientBuffer> bottom; 0114 QPointer<ClientBuffer> bottomLeft; 0115 QMarginsF offset; 0116 Flags flags = Flags::None; 0117 }; 0118 0119 void commit(); 0120 void attach(State::Flags flag, wl_resource *buffer); 0121 0122 ShadowManagerInterface *manager; 0123 State current; 0124 State pending; 0125 ShadowInterface *q; 0126 0127 protected: 0128 void org_kde_kwin_shadow_destroy_resource(Resource *resource) override; 0129 void org_kde_kwin_shadow_commit(Resource *resource) override; 0130 void org_kde_kwin_shadow_attach_left(Resource *resource, wl_resource *buffer) override; 0131 void org_kde_kwin_shadow_attach_top_left(Resource *resource, wl_resource *buffer) override; 0132 void org_kde_kwin_shadow_attach_top(Resource *resource, wl_resource *buffer) override; 0133 void org_kde_kwin_shadow_attach_top_right(Resource *resource, wl_resource *buffer) override; 0134 void org_kde_kwin_shadow_attach_right(Resource *resource, wl_resource *buffer) override; 0135 void org_kde_kwin_shadow_attach_bottom_right(Resource *resource, wl_resource *buffer) override; 0136 void org_kde_kwin_shadow_attach_bottom(Resource *resource, wl_resource *buffer) override; 0137 void org_kde_kwin_shadow_attach_bottom_left(Resource *resource, wl_resource *buffer) override; 0138 void org_kde_kwin_shadow_set_left_offset(Resource *resource, wl_fixed_t offset) override; 0139 void org_kde_kwin_shadow_set_top_offset(Resource *resource, wl_fixed_t offset) override; 0140 void org_kde_kwin_shadow_set_right_offset(Resource *resource, wl_fixed_t offset) override; 0141 void org_kde_kwin_shadow_set_bottom_offset(Resource *resource, wl_fixed_t offset) override; 0142 void org_kde_kwin_shadow_destroy(Resource *resource) override; 0143 }; 0144 0145 void ShadowInterfacePrivate::org_kde_kwin_shadow_commit(Resource *resource) 0146 { 0147 #define BUFFER(__FLAG__, __PART__) \ 0148 if (pending.flags & State::Flags::__FLAG__##Buffer) { \ 0149 if (current.__PART__) { \ 0150 current.__PART__->unref(); \ 0151 } \ 0152 if (pending.__PART__) { \ 0153 pending.__PART__->ref(); \ 0154 } \ 0155 current.__PART__ = pending.__PART__; \ 0156 } 0157 BUFFER(Left, left) 0158 BUFFER(TopLeft, topLeft) 0159 BUFFER(Top, top) 0160 BUFFER(TopRight, topRight) 0161 BUFFER(Right, right) 0162 BUFFER(BottomRight, bottomRight) 0163 BUFFER(Bottom, bottom) 0164 BUFFER(BottomLeft, bottomLeft) 0165 #undef BUFFER 0166 0167 if (pending.flags & State::Offset) { 0168 current.offset = pending.offset; 0169 } 0170 pending = State(); 0171 } 0172 0173 void ShadowInterfacePrivate::attach(ShadowInterfacePrivate::State::Flags flag, wl_resource *buffer) 0174 { 0175 ClientBuffer *b = manager->display()->clientBufferForResource(buffer); 0176 switch (flag) { 0177 case State::LeftBuffer: 0178 pending.left = b; 0179 break; 0180 case State::TopLeftBuffer: 0181 pending.topLeft = b; 0182 break; 0183 case State::TopBuffer: 0184 pending.top = b; 0185 break; 0186 case State::TopRightBuffer: 0187 pending.topRight = b; 0188 break; 0189 case State::RightBuffer: 0190 pending.right = b; 0191 break; 0192 case State::BottomRightBuffer: 0193 pending.bottomRight = b; 0194 break; 0195 case State::BottomBuffer: 0196 pending.bottom = b; 0197 break; 0198 case State::BottomLeftBuffer: 0199 pending.bottomLeft = b; 0200 break; 0201 default: 0202 Q_UNREACHABLE(); 0203 break; 0204 } 0205 pending.flags = State::Flags(pending.flags | flag); 0206 } 0207 0208 void ShadowInterfacePrivate::org_kde_kwin_shadow_destroy(Resource *resource) 0209 { 0210 wl_resource_destroy(resource->handle); 0211 } 0212 0213 void ShadowInterfacePrivate::org_kde_kwin_shadow_destroy_resource(Resource *resource) 0214 { 0215 delete q; 0216 } 0217 0218 void ShadowInterfacePrivate::org_kde_kwin_shadow_attach_left(Resource *resource, wl_resource *buffer) 0219 { 0220 attach(State::LeftBuffer, buffer); 0221 } 0222 0223 void ShadowInterfacePrivate::org_kde_kwin_shadow_attach_top_left(Resource *resource, wl_resource *buffer) 0224 { 0225 attach(State::TopLeftBuffer, buffer); 0226 } 0227 0228 void ShadowInterfacePrivate::org_kde_kwin_shadow_attach_top(Resource *resource, wl_resource *buffer) 0229 { 0230 attach(State::TopBuffer, buffer); 0231 } 0232 0233 void ShadowInterfacePrivate::org_kde_kwin_shadow_attach_top_right(Resource *resource, wl_resource *buffer) 0234 { 0235 attach(State::TopRightBuffer, buffer); 0236 } 0237 0238 void ShadowInterfacePrivate::org_kde_kwin_shadow_attach_right(Resource *resource, wl_resource *buffer) 0239 { 0240 attach(State::RightBuffer, buffer); 0241 } 0242 0243 void ShadowInterfacePrivate::org_kde_kwin_shadow_attach_bottom_right(Resource *resource, wl_resource *buffer) 0244 { 0245 attach(State::BottomRightBuffer, buffer); 0246 } 0247 0248 void ShadowInterfacePrivate::org_kde_kwin_shadow_attach_bottom(Resource *resource, wl_resource *buffer) 0249 { 0250 attach(State::BottomBuffer, buffer); 0251 } 0252 0253 void ShadowInterfacePrivate::org_kde_kwin_shadow_attach_bottom_left(Resource *resource, wl_resource *buffer) 0254 { 0255 attach(State::BottomLeftBuffer, buffer); 0256 } 0257 0258 void ShadowInterfacePrivate::org_kde_kwin_shadow_set_left_offset(Resource *resource, wl_fixed_t offset) 0259 { 0260 pending.flags = State::Flags(pending.flags | State::Offset); 0261 pending.offset.setLeft(wl_fixed_to_double(offset)); 0262 } 0263 0264 void ShadowInterfacePrivate::org_kde_kwin_shadow_set_top_offset(Resource *resource, wl_fixed_t offset) 0265 { 0266 pending.flags = State::Flags(pending.flags | State::Offset); 0267 pending.offset.setTop(wl_fixed_to_double(offset)); 0268 } 0269 0270 void ShadowInterfacePrivate::org_kde_kwin_shadow_set_right_offset(Resource *resource, wl_fixed_t offset) 0271 { 0272 pending.flags = State::Flags(pending.flags | State::Offset); 0273 pending.offset.setRight(wl_fixed_to_double(offset)); 0274 } 0275 0276 void ShadowInterfacePrivate::org_kde_kwin_shadow_set_bottom_offset(Resource *resource, wl_fixed_t offset) 0277 { 0278 pending.flags = State::Flags(pending.flags | State::Offset); 0279 pending.offset.setBottom(wl_fixed_to_double(offset)); 0280 } 0281 0282 ShadowInterfacePrivate::ShadowInterfacePrivate(ShadowInterface *_q, wl_resource *resource) 0283 : QtWaylandServer::org_kde_kwin_shadow(resource) 0284 , q(_q) 0285 { 0286 } 0287 0288 ShadowInterfacePrivate::~ShadowInterfacePrivate() 0289 { 0290 #define CURRENT(__PART__) \ 0291 if (current.__PART__) { \ 0292 current.__PART__->unref(); \ 0293 } 0294 CURRENT(left) 0295 CURRENT(topLeft) 0296 CURRENT(top) 0297 CURRENT(topRight) 0298 CURRENT(right) 0299 CURRENT(bottomRight) 0300 CURRENT(bottom) 0301 CURRENT(bottomLeft) 0302 #undef CURRENT 0303 } 0304 0305 ShadowInterface::ShadowInterface(ShadowManagerInterface *manager, wl_resource *resource) 0306 : QObject() 0307 , d(new ShadowInterfacePrivate(this, resource)) 0308 { 0309 d->manager = manager; 0310 } 0311 0312 ShadowInterface::~ShadowInterface() = default; 0313 0314 QMarginsF ShadowInterface::offset() const 0315 { 0316 return d->current.offset; 0317 } 0318 0319 #define BUFFER(__PART__) \ 0320 ClientBuffer *ShadowInterface::__PART__() const \ 0321 { \ 0322 return d->current.__PART__; \ 0323 } 0324 0325 BUFFER(left) 0326 BUFFER(topLeft) 0327 BUFFER(top) 0328 BUFFER(topRight) 0329 BUFFER(right) 0330 BUFFER(bottomRight) 0331 BUFFER(bottom) 0332 BUFFER(bottomLeft) 0333 0334 }