File indexing completed on 2024-12-22 05:09:20
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 #include "datasource.h" 0007 #include "wayland_pointer_p.h" 0008 // Qt 0009 #include <QMimeType> 0010 // Wayland 0011 #include <wayland-client-protocol.h> 0012 0013 namespace KWayland 0014 { 0015 namespace Client 0016 { 0017 class Q_DECL_HIDDEN DataSource::Private 0018 { 0019 public: 0020 explicit Private(DataSource *q); 0021 void setup(wl_data_source *s); 0022 0023 WaylandPointer<wl_data_source, wl_data_source_destroy> source; 0024 DataDeviceManager::DnDAction selectedAction = DataDeviceManager::DnDAction::None; 0025 0026 private: 0027 void setAction(DataDeviceManager::DnDAction action); 0028 static void targetCallback(void *data, wl_data_source *dataSource, const char *mimeType); 0029 static void sendCallback(void *data, wl_data_source *dataSource, const char *mimeType, int32_t fd); 0030 static void cancelledCallback(void *data, wl_data_source *dataSource); 0031 static void dndDropPerformedCallback(void *data, wl_data_source *wl_data_source); 0032 static void dndFinishedCallback(void *data, wl_data_source *wl_data_source); 0033 static void actionCallback(void *data, wl_data_source *wl_data_source, uint32_t dnd_action); 0034 0035 static const struct wl_data_source_listener s_listener; 0036 0037 DataSource *q; 0038 }; 0039 0040 const wl_data_source_listener DataSource::Private::s_listener = 0041 {targetCallback, sendCallback, cancelledCallback, dndDropPerformedCallback, dndFinishedCallback, actionCallback}; 0042 0043 DataSource::Private::Private(DataSource *q) 0044 : q(q) 0045 { 0046 } 0047 0048 void DataSource::Private::targetCallback(void *data, wl_data_source *dataSource, const char *mimeType) 0049 { 0050 auto d = reinterpret_cast<DataSource::Private *>(data); 0051 Q_ASSERT(d->source == dataSource); 0052 Q_EMIT d->q->targetAccepts(QString::fromUtf8(mimeType)); 0053 } 0054 0055 void DataSource::Private::sendCallback(void *data, wl_data_source *dataSource, const char *mimeType, int32_t fd) 0056 { 0057 auto d = reinterpret_cast<DataSource::Private *>(data); 0058 Q_ASSERT(d->source == dataSource); 0059 Q_EMIT d->q->sendDataRequested(QString::fromUtf8(mimeType), fd); 0060 } 0061 0062 void DataSource::Private::cancelledCallback(void *data, wl_data_source *dataSource) 0063 { 0064 auto d = reinterpret_cast<DataSource::Private *>(data); 0065 Q_ASSERT(d->source == dataSource); 0066 Q_EMIT d->q->cancelled(); 0067 } 0068 0069 void DataSource::Private::dndDropPerformedCallback(void *data, wl_data_source *wl_data_source) 0070 { 0071 Q_UNUSED(wl_data_source) 0072 auto d = reinterpret_cast<DataSource::Private *>(data); 0073 Q_EMIT d->q->dragAndDropPerformed(); 0074 } 0075 0076 void DataSource::Private::dndFinishedCallback(void *data, wl_data_source *wl_data_source) 0077 { 0078 Q_UNUSED(wl_data_source) 0079 auto d = reinterpret_cast<DataSource::Private *>(data); 0080 Q_EMIT d->q->dragAndDropFinished(); 0081 } 0082 0083 void DataSource::Private::actionCallback(void *data, wl_data_source *wl_data_source, uint32_t dnd_action) 0084 { 0085 Q_UNUSED(wl_data_source) 0086 auto d = reinterpret_cast<Private *>(data); 0087 switch (dnd_action) { 0088 case WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY: 0089 d->setAction(DataDeviceManager::DnDAction::Copy); 0090 break; 0091 case WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE: 0092 d->setAction(DataDeviceManager::DnDAction::Move); 0093 break; 0094 case WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK: 0095 d->setAction(DataDeviceManager::DnDAction::Ask); 0096 break; 0097 case WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE: 0098 d->setAction(DataDeviceManager::DnDAction::None); 0099 break; 0100 default: 0101 Q_UNREACHABLE(); 0102 } 0103 } 0104 0105 void DataSource::Private::setAction(DataDeviceManager::DnDAction action) 0106 { 0107 if (action == selectedAction) { 0108 return; 0109 } 0110 selectedAction = action; 0111 Q_EMIT q->selectedDragAndDropActionChanged(); 0112 } 0113 0114 void DataSource::Private::setup(wl_data_source *s) 0115 { 0116 Q_ASSERT(!source.isValid()); 0117 Q_ASSERT(s); 0118 source.setup(s); 0119 wl_data_source_add_listener(s, &s_listener, this); 0120 } 0121 0122 DataSource::DataSource(QObject *parent) 0123 : QObject(parent) 0124 , d(new Private(this)) 0125 { 0126 } 0127 0128 DataSource::~DataSource() 0129 { 0130 release(); 0131 } 0132 0133 void DataSource::release() 0134 { 0135 d->source.release(); 0136 } 0137 0138 void DataSource::destroy() 0139 { 0140 d->source.destroy(); 0141 } 0142 0143 bool DataSource::isValid() const 0144 { 0145 return d->source.isValid(); 0146 } 0147 0148 void DataSource::setup(wl_data_source *dataSource) 0149 { 0150 d->setup(dataSource); 0151 } 0152 0153 void DataSource::offer(const QString &mimeType) 0154 { 0155 wl_data_source_offer(d->source, mimeType.toUtf8().constData()); 0156 } 0157 0158 void DataSource::offer(const QMimeType &mimeType) 0159 { 0160 if (!mimeType.isValid()) { 0161 return; 0162 } 0163 offer(mimeType.name()); 0164 } 0165 0166 DataSource::operator wl_data_source *() const 0167 { 0168 return d->source; 0169 } 0170 0171 DataSource::operator wl_data_source *() 0172 { 0173 return d->source; 0174 } 0175 0176 void DataSource::setDragAndDropActions(DataDeviceManager::DnDActions actions) 0177 { 0178 uint32_t wlActions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; 0179 if (actions.testFlag(DataDeviceManager::DnDAction::Copy)) { 0180 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; 0181 } 0182 if (actions.testFlag(DataDeviceManager::DnDAction::Move)) { 0183 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; 0184 } 0185 if (actions.testFlag(DataDeviceManager::DnDAction::Ask)) { 0186 wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK; 0187 } 0188 wl_data_source_set_actions(d->source, wlActions); 0189 } 0190 0191 DataDeviceManager::DnDAction DataSource::selectedDragAndDropAction() const 0192 { 0193 return d->selectedAction; 0194 } 0195 0196 } 0197 } 0198 0199 #include "moc_datasource.cpp"