File indexing completed on 2024-11-10 04:57:31

0001 /*
0002     SPDX-FileCopyrightText: 2020 David Edmundson <davidedmundson@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 #include "primaryselectiondevice_v1.h"
0007 #include "display.h"
0008 #include "primaryselectiondevicemanager_v1.h"
0009 #include "primaryselectionoffer_v1.h"
0010 #include "primaryselectionsource_v1.h"
0011 #include "seat.h"
0012 #include "seat_p.h"
0013 
0014 // Wayland
0015 #include <qwayland-server-wp-primary-selection-unstable-v1.h>
0016 
0017 namespace KWin
0018 {
0019 class PrimarySelectionDeviceV1InterfacePrivate : public QtWaylandServer::zwp_primary_selection_device_v1
0020 {
0021 public:
0022     PrimarySelectionDeviceV1InterfacePrivate(PrimarySelectionDeviceV1Interface *q, SeatInterface *seat, wl_resource *resource);
0023 
0024     PrimarySelectionOfferV1Interface *createDataOffer(AbstractDataSource *source);
0025 
0026     PrimarySelectionDeviceV1Interface *q;
0027     SeatInterface *seat;
0028     QPointer<PrimarySelectionSourceV1Interface> selection;
0029 
0030 private:
0031     void setSelection(PrimarySelectionSourceV1Interface *dataSource);
0032 
0033 protected:
0034     void zwp_primary_selection_device_v1_destroy_resource(Resource *resource) override;
0035     void zwp_primary_selection_device_v1_set_selection(Resource *resource, wl_resource *source, uint32_t serial) override;
0036     void zwp_primary_selection_device_v1_destroy(Resource *resource) override;
0037 };
0038 
0039 PrimarySelectionDeviceV1InterfacePrivate::PrimarySelectionDeviceV1InterfacePrivate(PrimarySelectionDeviceV1Interface *_q,
0040                                                                                    SeatInterface *seat,
0041                                                                                    wl_resource *resource)
0042     : QtWaylandServer::zwp_primary_selection_device_v1(resource)
0043     , q(_q)
0044     , seat(seat)
0045 {
0046 }
0047 
0048 void PrimarySelectionDeviceV1InterfacePrivate::zwp_primary_selection_device_v1_set_selection(Resource *resource, wl_resource *source, uint32_t serial)
0049 {
0050     PrimarySelectionSourceV1Interface *dataSource = nullptr;
0051 
0052     if (source) {
0053         dataSource = PrimarySelectionSourceV1Interface::get(source);
0054         Q_ASSERT(dataSource);
0055     }
0056 
0057     if (selection == dataSource) {
0058         return;
0059     }
0060     if (selection) {
0061         selection->cancel();
0062     }
0063     selection = dataSource;
0064     if (selection) {
0065         Q_EMIT q->selectionChanged(selection);
0066     }
0067 }
0068 
0069 void PrimarySelectionDeviceV1InterfacePrivate::zwp_primary_selection_device_v1_destroy(QtWaylandServer::zwp_primary_selection_device_v1::Resource *resource)
0070 {
0071     wl_resource_destroy(resource->handle);
0072 }
0073 
0074 PrimarySelectionOfferV1Interface *PrimarySelectionDeviceV1InterfacePrivate::createDataOffer(AbstractDataSource *source)
0075 {
0076     if (!source) {
0077         // a data offer can only exist together with a source
0078         return nullptr;
0079     }
0080 
0081     wl_resource *data_offer_resource = wl_resource_create(resource()->client(), &zwp_primary_selection_offer_v1_interface, resource()->version(), 0);
0082     if (!data_offer_resource) {
0083         wl_resource_post_no_memory(resource()->handle);
0084         return nullptr;
0085     }
0086 
0087     PrimarySelectionOfferV1Interface *offer = new PrimarySelectionOfferV1Interface(source, data_offer_resource);
0088     send_data_offer(offer->resource());
0089     offer->sendAllOffers();
0090     return offer;
0091 }
0092 
0093 void PrimarySelectionDeviceV1InterfacePrivate::zwp_primary_selection_device_v1_destroy_resource(
0094     QtWaylandServer::zwp_primary_selection_device_v1::Resource *resource)
0095 {
0096     delete q;
0097 }
0098 
0099 PrimarySelectionDeviceV1Interface::PrimarySelectionDeviceV1Interface(SeatInterface *seat, wl_resource *resource)
0100     : QObject()
0101     , d(new PrimarySelectionDeviceV1InterfacePrivate(this, seat, resource))
0102 {
0103     SeatInterfacePrivate *seatPrivate = SeatInterfacePrivate::get(seat);
0104     seatPrivate->registerPrimarySelectionDevice(this);
0105 }
0106 
0107 PrimarySelectionDeviceV1Interface::~PrimarySelectionDeviceV1Interface() = default;
0108 
0109 SeatInterface *PrimarySelectionDeviceV1Interface::seat() const
0110 {
0111     return d->seat;
0112 }
0113 
0114 PrimarySelectionSourceV1Interface *PrimarySelectionDeviceV1Interface::selection() const
0115 {
0116     return d->selection;
0117 }
0118 
0119 void PrimarySelectionDeviceV1Interface::sendSelection(AbstractDataSource *other)
0120 {
0121     PrimarySelectionOfferV1Interface *offer = d->createDataOffer(other);
0122     d->send_selection(offer ? offer->resource() : nullptr);
0123 }
0124 
0125 wl_client *PrimarySelectionDeviceV1Interface::client() const
0126 {
0127     return d->resource()->client();
0128 }
0129 
0130 }
0131 
0132 #include "moc_primaryselectiondevice_v1.cpp"