File indexing completed on 2024-05-12 05:32:35

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 <QList>
0012 #include <QObject>
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 KWin
0022 {
0023 class DataDeviceInterface;
0024 class DataSourceInterface;
0025 class AbstractDataSource;
0026 
0027 namespace Xwl
0028 {
0029 class Selection;
0030 
0031 /**
0032  * Base class representing a data source.
0033  */
0034 class SelectionSource : public QObject
0035 {
0036     Q_OBJECT
0037 
0038 public:
0039     SelectionSource(Selection *selection);
0040 
0041     xcb_timestamp_t timestamp() const
0042     {
0043         return m_timestamp;
0044     }
0045     void setTimestamp(xcb_timestamp_t time)
0046     {
0047         m_timestamp = time;
0048     }
0049 
0050 protected:
0051     Selection *selection() const
0052     {
0053         return m_selection;
0054     }
0055     void setWindow(xcb_window_t window)
0056     {
0057         m_window = window;
0058     }
0059     xcb_window_t window() const
0060     {
0061         return m_window;
0062     }
0063 
0064 private:
0065     xcb_timestamp_t m_timestamp = XCB_CURRENT_TIME;
0066     Selection *m_selection;
0067     xcb_window_t m_window;
0068 
0069     Q_DISABLE_COPY(SelectionSource)
0070 };
0071 
0072 /**
0073  * Representing a Wayland native data source.
0074  */
0075 class WlSource : public SelectionSource
0076 {
0077     Q_OBJECT
0078 
0079 public:
0080     WlSource(Selection *selection);
0081     void setDataSourceIface(AbstractDataSource *dsi);
0082 
0083     bool handleSelectionRequest(xcb_selection_request_event_t *event);
0084     void sendTargets(xcb_selection_request_event_t *event);
0085     void sendTimestamp(xcb_selection_request_event_t *event);
0086 
0087     void receiveOffer(const QString &mime);
0088     void sendSelectionNotify(xcb_selection_request_event_t *event, bool success);
0089 
0090 Q_SIGNALS:
0091     void transferReady(xcb_selection_request_event_t *event, qint32 fd);
0092 
0093 private:
0094     bool checkStartTransfer(xcb_selection_request_event_t *event);
0095 
0096     AbstractDataSource *m_dsi = nullptr;
0097 
0098     QList<QString> m_offers;
0099     QMetaObject::Connection m_offerConnection;
0100 
0101     Q_DISABLE_COPY(WlSource)
0102 };
0103 
0104 using Mimes = QList<QPair<QString, xcb_atom_t>>;
0105 
0106 /**
0107  * Representing an X data source.
0108  */
0109 class X11Source : public SelectionSource
0110 {
0111     Q_OBJECT
0112 
0113 public:
0114     X11Source(Selection *selection, xcb_xfixes_selection_notify_event_t *event);
0115 
0116     void getTargets();
0117 
0118     Mimes offers() const
0119     {
0120         return m_offers;
0121     }
0122     void setOffers(const Mimes &offers);
0123 
0124     bool handleSelectionNotify(xcb_selection_notify_event_t *event);
0125 
0126     void setRequestor(xcb_window_t window)
0127     {
0128         setWindow(window);
0129     }
0130 
0131     void startTransfer(const QString &mimeName, qint32 fd);
0132 Q_SIGNALS:
0133     void offersChanged(const QStringList &added, const QStringList &removed);
0134     void transferReady(xcb_atom_t target, qint32 fd);
0135 
0136 private:
0137     void handleTargets();
0138 
0139     Mimes m_offers;
0140 
0141     Q_DISABLE_COPY(X11Source)
0142 };
0143 
0144 } // namespace Xwl
0145 } // namespace KWin