File indexing completed on 2024-05-19 16:35:29

0001 /*
0002     SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "tearingcontrol_v1_interface.h"
0007 #include "display.h"
0008 #include "surface_interface_p.h"
0009 
0010 namespace KWaylandServer
0011 {
0012 
0013 static constexpr uint32_t s_version = 1;
0014 
0015 class TearingControlManagerV1InterfacePrivate : public QtWaylandServer::wp_tearing_control_manager_v1
0016 {
0017 public:
0018     TearingControlManagerV1InterfacePrivate(Display *display);
0019 
0020 private:
0021     void wp_tearing_control_manager_v1_destroy(Resource *resource) override;
0022     void wp_tearing_control_manager_v1_get_tearing_control(Resource *resource, uint32_t id, struct ::wl_resource *surface) override;
0023 };
0024 
0025 class TearingControlV1Interface : private QtWaylandServer::wp_tearing_control_v1
0026 {
0027 public:
0028     TearingControlV1Interface(SurfaceInterface *surface, wl_client *client, uint32_t id);
0029     ~TearingControlV1Interface();
0030 
0031 private:
0032     void wp_tearing_control_v1_set_presentation_hint(Resource *resource, uint32_t hint) override;
0033     void wp_tearing_control_v1_destroy(Resource *resource) override;
0034     void wp_tearing_control_v1_destroy_resource(Resource *resource) override;
0035 
0036     const QPointer<SurfaceInterface> m_surface;
0037 };
0038 
0039 TearingControlManagerV1Interface::TearingControlManagerV1Interface(Display *display, QObject *parent)
0040     : QObject(parent)
0041     , d(new TearingControlManagerV1InterfacePrivate(display))
0042 {
0043 }
0044 
0045 TearingControlManagerV1Interface::~TearingControlManagerV1Interface() = default;
0046 
0047 TearingControlManagerV1InterfacePrivate::TearingControlManagerV1InterfacePrivate(Display *display)
0048     : QtWaylandServer::wp_tearing_control_manager_v1(*display, s_version)
0049 {
0050 }
0051 
0052 void TearingControlManagerV1InterfacePrivate::wp_tearing_control_manager_v1_destroy(Resource *resource)
0053 {
0054     wl_resource_destroy(resource->handle);
0055 }
0056 
0057 void TearingControlManagerV1InterfacePrivate::wp_tearing_control_manager_v1_get_tearing_control(Resource *resource, uint32_t id, struct ::wl_resource *wlSurface)
0058 {
0059     SurfaceInterface *surface = SurfaceInterface::get(wlSurface);
0060     if (SurfaceInterfacePrivate::get(surface)->tearing) {
0061         wl_resource_post_error(resource->handle, QtWaylandServer::wp_tearing_control_manager_v1::error_tearing_control_exists, "Surface already has a wp_surface_tearing_control_v1");
0062         return;
0063     }
0064     SurfaceInterfacePrivate::get(surface)->tearing = new TearingControlV1Interface(surface, resource->client(), id);
0065 }
0066 
0067 TearingControlV1Interface::TearingControlV1Interface(SurfaceInterface *surface, wl_client *client, uint32_t id)
0068     : QtWaylandServer::wp_tearing_control_v1(client, id, s_version)
0069     , m_surface(surface)
0070 {
0071 }
0072 
0073 TearingControlV1Interface::~TearingControlV1Interface()
0074 {
0075     if (m_surface) {
0076         SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(m_surface);
0077         surfacePrivate->pending.presentationHint = PresentationHint::VSync;
0078         surfacePrivate->pending.tearingIsSet = true;
0079         surfacePrivate->tearing = nullptr;
0080     }
0081 }
0082 
0083 void TearingControlV1Interface::wp_tearing_control_v1_set_presentation_hint(Resource *resource, uint32_t hint)
0084 {
0085     if (m_surface) {
0086         SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(m_surface);
0087         if (hint == presentation_hint::presentation_hint_async) {
0088             surfacePrivate->pending.presentationHint = PresentationHint::Async;
0089         } else {
0090             surfacePrivate->pending.presentationHint = PresentationHint::VSync;
0091         }
0092         surfacePrivate->pending.tearingIsSet = true;
0093     }
0094 }
0095 
0096 void TearingControlV1Interface::wp_tearing_control_v1_destroy(Resource *resource)
0097 {
0098     wl_resource_destroy(resource->handle);
0099 }
0100 
0101 void TearingControlV1Interface::wp_tearing_control_v1_destroy_resource(Resource *resource)
0102 {
0103     delete this;
0104 }
0105 }