File indexing completed on 2024-11-10 04:57:36
0001 /* 0002 SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "viewporter.h" 0008 #include "display.h" 0009 #include "surface_p.h" 0010 #include "viewporter_p.h" 0011 0012 static const int s_version = 1; 0013 0014 namespace KWin 0015 { 0016 class ViewporterInterfacePrivate : public QtWaylandServer::wp_viewporter 0017 { 0018 protected: 0019 void wp_viewporter_destroy(Resource *resource) override; 0020 void wp_viewporter_get_viewport(Resource *resource, uint32_t id, struct ::wl_resource *surface) override; 0021 }; 0022 0023 void ViewporterInterfacePrivate::wp_viewporter_destroy(Resource *resource) 0024 { 0025 wl_resource_destroy(resource->handle); 0026 } 0027 0028 void ViewporterInterfacePrivate::wp_viewporter_get_viewport(Resource *resource, uint32_t id, struct ::wl_resource *surface_resource) 0029 { 0030 SurfaceInterface *surface = SurfaceInterface::get(surface_resource); 0031 ViewportInterface *viewport = ViewportInterface::get(surface); 0032 0033 if (viewport) { 0034 wl_resource_post_error(resource->handle, error_viewport_exists, "the specified surface already has a viewport"); 0035 return; 0036 } 0037 0038 wl_resource *viewportResource = wl_resource_create(resource->client(), &wp_viewport_interface, resource->version(), id); 0039 0040 new ViewportInterface(surface, viewportResource); 0041 } 0042 0043 ViewportInterface::ViewportInterface(SurfaceInterface *surface, wl_resource *resource) 0044 : QtWaylandServer::wp_viewport(resource) 0045 , surface(surface) 0046 { 0047 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface); 0048 surfacePrivate->viewportExtension = this; 0049 } 0050 0051 ViewportInterface::~ViewportInterface() 0052 { 0053 if (surface) { 0054 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface); 0055 surfacePrivate->viewportExtension = nullptr; 0056 } 0057 } 0058 0059 ViewportInterface *ViewportInterface::get(SurfaceInterface *surface) 0060 { 0061 return SurfaceInterfacePrivate::get(surface)->viewportExtension; 0062 } 0063 0064 void ViewportInterface::wp_viewport_destroy_resource(Resource *resource) 0065 { 0066 delete this; 0067 } 0068 0069 void ViewportInterface::wp_viewport_destroy(Resource *resource) 0070 { 0071 if (surface) { 0072 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface); 0073 surfacePrivate->pending->viewport.sourceGeometry = QRectF(); 0074 surfacePrivate->pending->viewport.sourceGeometryIsSet = true; 0075 surfacePrivate->pending->viewport.destinationSize = QSize(); 0076 surfacePrivate->pending->viewport.destinationSizeIsSet = true; 0077 } 0078 0079 wl_resource_destroy(resource->handle); 0080 } 0081 0082 void ViewportInterface::wp_viewport_set_source(Resource *resource, wl_fixed_t x_fixed, wl_fixed_t y_fixed, wl_fixed_t width_fixed, wl_fixed_t height_fixed) 0083 { 0084 if (!surface) { 0085 wl_resource_post_error(resource->handle, error_no_surface, "the wl_surface for this viewport no longer exists"); 0086 return; 0087 } 0088 0089 const qreal x = wl_fixed_to_double(x_fixed); 0090 const qreal y = wl_fixed_to_double(y_fixed); 0091 const qreal width = wl_fixed_to_double(width_fixed); 0092 const qreal height = wl_fixed_to_double(height_fixed); 0093 0094 if (x == -1 && y == -1 && width == -1 && height == -1) { 0095 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface); 0096 surfacePrivate->pending->viewport.sourceGeometry = QRectF(); 0097 surfacePrivate->pending->viewport.sourceGeometryIsSet = true; 0098 return; 0099 } 0100 0101 if (x < 0 || y < 0 || width <= 0 || height <= 0) { 0102 wl_resource_post_error(resource->handle, error_bad_value, "invalid source geometry"); 0103 return; 0104 } 0105 0106 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface); 0107 surfacePrivate->pending->viewport.sourceGeometry = QRectF(x, y, width, height); 0108 surfacePrivate->pending->viewport.sourceGeometryIsSet = true; 0109 } 0110 0111 void ViewportInterface::wp_viewport_set_destination(Resource *resource, int32_t width, int32_t height) 0112 { 0113 if (!surface) { 0114 wl_resource_post_error(resource->handle, error_no_surface, "the wl_surface for this viewport no longer exists"); 0115 return; 0116 } 0117 0118 if (width == -1 && height == -1) { 0119 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface); 0120 surfacePrivate->pending->viewport.destinationSize = QSize(); 0121 surfacePrivate->pending->viewport.destinationSizeIsSet = true; 0122 return; 0123 } 0124 0125 if (width <= 0 || height <= 0) { 0126 wl_resource_post_error(resource->handle, error_bad_value, "invalid destination size"); 0127 return; 0128 } 0129 0130 SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface); 0131 surfacePrivate->pending->viewport.destinationSize = QSize(width, height); 0132 surfacePrivate->pending->viewport.destinationSizeIsSet = true; 0133 } 0134 0135 ViewporterInterface::ViewporterInterface(Display *display, QObject *parent) 0136 : QObject(parent) 0137 , d(new ViewporterInterfacePrivate) 0138 { 0139 d->init(*display, s_version); 0140 } 0141 0142 ViewporterInterface::~ViewporterInterface() 0143 { 0144 } 0145 0146 } // namespace KWin 0147 0148 #include "moc_viewporter.cpp"