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

0001 /*
0002     SPDX-FileCopyrightText: 2020 David Edmundson <davidedmundson@kde.org>
0003     SPDX-FileCopyrightText: 2021 David Redondo <kde@david-redondo.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 #include "datacontroldevice_v1_interface.h"
0008 #include "datacontroldevicemanager_v1_interface.h"
0009 #include "datacontroloffer_v1_interface.h"
0010 #include "datacontrolsource_v1_interface.h"
0011 #include "display.h"
0012 #include "seat_interface.h"
0013 #include "seat_interface_p.h"
0014 #include "surface_interface.h"
0015 
0016 // Wayland
0017 #include <qwayland-server-wlr-data-control-unstable-v1.h>
0018 
0019 namespace KWaylandServer
0020 {
0021 class DataControlDeviceV1InterfacePrivate : public QtWaylandServer::zwlr_data_control_device_v1
0022 {
0023 public:
0024     DataControlDeviceV1InterfacePrivate(DataControlDeviceV1Interface *q, SeatInterface *seat, wl_resource *resource);
0025 
0026     DataControlOfferV1Interface *createDataOffer(AbstractDataSource *source);
0027 
0028     DataControlDeviceV1Interface *q;
0029     QPointer<SeatInterface> seat;
0030     QPointer<DataControlSourceV1Interface> selection;
0031     QPointer<DataControlSourceV1Interface> primarySelection;
0032 
0033 protected:
0034     void zwlr_data_control_device_v1_destroy_resource(Resource *resource) override;
0035     void zwlr_data_control_device_v1_set_selection(Resource *resource, wl_resource *source) override;
0036     void zwlr_data_control_device_v1_set_primary_selection(Resource *resource, struct ::wl_resource *source) override;
0037     void zwlr_data_control_device_v1_destroy(Resource *resource) override;
0038 };
0039 
0040 DataControlDeviceV1InterfacePrivate::DataControlDeviceV1InterfacePrivate(DataControlDeviceV1Interface *_q, SeatInterface *seat, wl_resource *resource)
0041     : QtWaylandServer::zwlr_data_control_device_v1(resource)
0042     , q(_q)
0043     , seat(seat)
0044 {
0045 }
0046 
0047 void DataControlDeviceV1InterfacePrivate::zwlr_data_control_device_v1_set_selection(Resource *resource, wl_resource *source)
0048 {
0049     DataControlSourceV1Interface *dataSource = nullptr;
0050 
0051     if (source) {
0052         dataSource = DataControlSourceV1Interface::get(source);
0053         Q_ASSERT(dataSource);
0054         if (dataSource == seat->selection() || dataSource == seat->primarySelection()) {
0055             wl_resource_post_error(resource->handle, error::error_used_source, "source given to set_selection was already used before");
0056             return;
0057         }
0058     }
0059     if (selection) {
0060         selection->cancel();
0061     }
0062     selection = dataSource;
0063     Q_EMIT q->selectionChanged(selection);
0064 }
0065 
0066 void DataControlDeviceV1InterfacePrivate::zwlr_data_control_device_v1_set_primary_selection(Resource *resource, wl_resource *source)
0067 {
0068     DataControlSourceV1Interface *dataSource = nullptr;
0069 
0070     if (source) {
0071         dataSource = DataControlSourceV1Interface::get(source);
0072         Q_ASSERT(dataSource);
0073         if (dataSource == seat->selection() || dataSource == seat->primarySelection()) {
0074             wl_resource_post_error(resource->handle, error::error_used_source, "source given to set_primary_selection was already used before");
0075             return;
0076         }
0077     }
0078     if (primarySelection) {
0079         primarySelection->cancel();
0080     }
0081     primarySelection = dataSource;
0082     Q_EMIT q->primarySelectionChanged(primarySelection);
0083 }
0084 
0085 void DataControlDeviceV1InterfacePrivate::zwlr_data_control_device_v1_destroy(QtWaylandServer::zwlr_data_control_device_v1::Resource *resource)
0086 {
0087     wl_resource_destroy(resource->handle);
0088 }
0089 
0090 DataControlOfferV1Interface *DataControlDeviceV1InterfacePrivate::createDataOffer(AbstractDataSource *source)
0091 {
0092     if (!source) {
0093         // a data offer can only exist together with a source
0094         return nullptr;
0095     }
0096 
0097     wl_resource *data_offer_resource = wl_resource_create(resource()->client(), &zwlr_data_control_offer_v1_interface, resource()->version(), 0);
0098     if (!data_offer_resource) {
0099         return nullptr;
0100     }
0101 
0102     DataControlOfferV1Interface *offer = new DataControlOfferV1Interface(source, data_offer_resource);
0103     send_data_offer(offer->resource());
0104     offer->sendAllOffers();
0105     return offer;
0106 }
0107 
0108 void DataControlDeviceV1InterfacePrivate::zwlr_data_control_device_v1_destroy_resource(QtWaylandServer::zwlr_data_control_device_v1::Resource *resource)
0109 {
0110     delete q;
0111 }
0112 
0113 DataControlDeviceV1Interface::DataControlDeviceV1Interface(SeatInterface *seat, wl_resource *resource)
0114     : QObject()
0115     , d(new DataControlDeviceV1InterfacePrivate(this, seat, resource))
0116 {
0117     SeatInterfacePrivate *seatPrivate = SeatInterfacePrivate::get(seat);
0118     seatPrivate->registerDataControlDevice(this);
0119 }
0120 
0121 DataControlDeviceV1Interface::~DataControlDeviceV1Interface() = default;
0122 
0123 SeatInterface *DataControlDeviceV1Interface::seat() const
0124 {
0125     return d->seat;
0126 }
0127 
0128 DataControlSourceV1Interface *DataControlDeviceV1Interface::selection() const
0129 {
0130     return d->selection;
0131 }
0132 
0133 DataControlSourceV1Interface *DataControlDeviceV1Interface::primarySelection() const
0134 {
0135     return d->primarySelection;
0136 }
0137 
0138 void DataControlDeviceV1Interface::sendSelection(AbstractDataSource *other)
0139 {
0140     DataControlOfferV1Interface *offer = d->createDataOffer(other);
0141     d->send_selection(offer ? offer->resource() : nullptr);
0142 }
0143 
0144 void DataControlDeviceV1Interface::sendPrimarySelection(KWaylandServer::AbstractDataSource *other)
0145 {
0146     if (d->resource()->version() >= ZWLR_DATA_CONTROL_DEVICE_V1_PRIMARY_SELECTION_SINCE_VERSION) {
0147         DataControlOfferV1Interface *offer = d->createDataOffer(other);
0148         d->send_primary_selection(offer ? offer->resource() : nullptr);
0149     }
0150 }
0151 }