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

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2019 Roman Gilg <subdiff@gmail.com>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #pragma once
0010 
0011 #include <QObject>
0012 #include <QVector>
0013 
0014 #include <xcb/xcb.h>
0015 
0016 class QSocketNotifier;
0017 
0018 struct xcb_selection_request_event_t;
0019 struct xcb_xfixes_selection_notify_event_t;
0020 
0021 namespace KWaylandServer
0022 {
0023 class DataDeviceInterface;
0024 class DataSourceInterface;
0025 class AbstractDataSource;
0026 }
0027 
0028 namespace KWin
0029 {
0030 namespace Xwl
0031 {
0032 class Selection;
0033 
0034 /**
0035  * Base class representing a data source.
0036  */
0037 class SelectionSource : public QObject
0038 {
0039     Q_OBJECT
0040 
0041 public:
0042     SelectionSource(Selection *selection);
0043 
0044     xcb_timestamp_t timestamp() const
0045     {
0046         return m_timestamp;
0047     }
0048     void setTimestamp(xcb_timestamp_t time)
0049     {
0050         m_timestamp = time;
0051     }
0052 
0053 protected:
0054     Selection *selection() const
0055     {
0056         return m_selection;
0057     }
0058     void setWindow(xcb_window_t window)
0059     {
0060         m_window = window;
0061     }
0062     xcb_window_t window() const
0063     {
0064         return m_window;
0065     }
0066 
0067 private:
0068     xcb_timestamp_t m_timestamp = XCB_CURRENT_TIME;
0069     Selection *m_selection;
0070     xcb_window_t m_window;
0071 
0072     Q_DISABLE_COPY(SelectionSource)
0073 };
0074 
0075 /**
0076  * Representing a Wayland native data source.
0077  */
0078 class WlSource : public SelectionSource
0079 {
0080     Q_OBJECT
0081 
0082 public:
0083     WlSource(Selection *selection);
0084     void setDataSourceIface(KWaylandServer::AbstractDataSource *dsi);
0085 
0086     bool handleSelectionRequest(xcb_selection_request_event_t *event);
0087     void sendTargets(xcb_selection_request_event_t *event);
0088     void sendTimestamp(xcb_selection_request_event_t *event);
0089 
0090     void receiveOffer(const QString &mime);
0091     void sendSelectionNotify(xcb_selection_request_event_t *event, bool success);
0092 
0093 Q_SIGNALS:
0094     void transferReady(xcb_selection_request_event_t *event, qint32 fd);
0095 
0096 private:
0097     bool checkStartTransfer(xcb_selection_request_event_t *event);
0098 
0099     KWaylandServer::AbstractDataSource *m_dsi = nullptr;
0100 
0101     QVector<QString> m_offers;
0102     QMetaObject::Connection m_offerConnection;
0103 
0104     Q_DISABLE_COPY(WlSource)
0105 };
0106 
0107 using Mimes = QVector<QPair<QString, xcb_atom_t>>;
0108 
0109 /**
0110  * Representing an X data source.
0111  */
0112 class X11Source : public SelectionSource
0113 {
0114     Q_OBJECT
0115 
0116 public:
0117     X11Source(Selection *selection, xcb_xfixes_selection_notify_event_t *event);
0118 
0119     void getTargets();
0120 
0121     Mimes offers() const
0122     {
0123         return m_offers;
0124     }
0125     void setOffers(const Mimes &offers);
0126 
0127     bool handleSelectionNotify(xcb_selection_notify_event_t *event);
0128 
0129     void setRequestor(xcb_window_t window)
0130     {
0131         setWindow(window);
0132     }
0133 
0134     void startTransfer(const QString &mimeName, qint32 fd);
0135 Q_SIGNALS:
0136     void offersChanged(const QStringList &added, const QStringList &removed);
0137     void transferReady(xcb_atom_t target, qint32 fd);
0138 
0139 private:
0140     void handleTargets();
0141 
0142     xcb_window_t m_owner;
0143 
0144     Mimes m_offers;
0145 
0146     Q_DISABLE_COPY(X11Source)
0147 };
0148 
0149 } // namespace Xwl
0150 } // namespace KWin