summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wayland/qwaylandclipboard.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wayland/qwaylandclipboard.cpp')
-rw-r--r--src/plugins/platforms/wayland/qwaylandclipboard.cpp255
1 files changed, 14 insertions, 241 deletions
diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp
index c5475016a..3ad9ed2f7 100644
--- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp
+++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp
@@ -42,218 +42,37 @@
#include "qwaylandclipboard.h"
#include "qwaylanddisplay.h"
#include "qwaylandinputdevice.h"
-#include "qwaylandmime.h"
-#include <QtGui/QPlatformNativeInterface>
-#include <QtGui/QGuiApplication>
-#include <QtCore/QMimeData>
-#include <QtCore/QStringList>
-#include <QtCore/QFile>
-#include <QtCore/QtDebug>
-#include <QtGui/private/qdnd_p.h>
-#include <QtCore/private/qcore_unix_p.h> // for QT_READ
-
-static QWaylandClipboard *clipboard = 0;
-
-class QWaylandClipboardMimeData : public QInternalMimeData
-{
-public:
- void clearAll();
- void setFormats(const QStringList &formatList);
- bool hasFormat_sys(const QString &mimeType) const;
- QStringList formats_sys() const;
- QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
-private:
- QStringList mFormatList;
-};
-
-void QWaylandClipboardMimeData::clearAll()
-{
- clear();
- mFormatList.clear();
-}
-
-void QWaylandClipboardMimeData::setFormats(const QStringList &formatList)
-{
- mFormatList = formatList;
-}
-
-bool QWaylandClipboardMimeData::hasFormat_sys(const QString &mimeType) const
-{
- return formats().contains(mimeType);
-}
-
-QStringList QWaylandClipboardMimeData::formats_sys() const
-{
- return mFormatList;
-}
-
-QVariant QWaylandClipboardMimeData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const
-{
- return clipboard->retrieveData(mimeType, type);
-}
-
-class QWaylandSelection
-{
-public:
- QWaylandSelection(QWaylandDisplay *display, QMimeData *data);
- ~QWaylandSelection();
-
- static uint32_t getTime();
- static void send(void *data, struct wl_selection *selection, const char *mime_type, int fd);
- static void cancelled(void *data, struct wl_selection *selection);
- static const struct wl_selection_listener selectionListener;
-
- QMimeData *mMimeData;
- struct wl_selection *mSelection;
-};
-
-const struct wl_selection_listener QWaylandSelection::selectionListener = {
- QWaylandSelection::send,
- QWaylandSelection::cancelled
-};
-
-uint32_t QWaylandSelection::getTime()
-{
- struct timeval tv;
- gettimeofday(&tv, 0);
- return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-}
-
-QWaylandSelection::QWaylandSelection(QWaylandDisplay *display, QMimeData *data)
- : mMimeData(data), mSelection(0)
-{
- struct wl_shell *shell = display->wl_shell();
- mSelection = wl_shell_create_selection(shell);
- wl_selection_add_listener(mSelection, &selectionListener, this);
- foreach (const QString &format, data->formats())
- wl_selection_offer(mSelection, format.toLatin1().constData());
- wl_selection_activate(mSelection,
- display->inputDevices().at(0)->wl_input_device(),
- getTime());
-}
-
-QWaylandSelection::~QWaylandSelection()
-{
- if (mSelection) {
- clipboard->unregisterSelection(this);
- wl_selection_destroy(mSelection);
- }
- delete mMimeData;
-}
-
-void QWaylandSelection::send(void *data,
- struct wl_selection *selection,
- const char *mime_type,
- int fd)
-{
- Q_UNUSED(selection);
- QWaylandSelection *self = static_cast<QWaylandSelection *>(data);
- QString mimeType = QString::fromLatin1(mime_type);
- QByteArray content = QWaylandMimeHelper::getByteArray(self->mMimeData, mimeType);
- if (!content.isEmpty()) {
- QFile f;
- if (f.open(fd, QIODevice::WriteOnly))
- f.write(content);
- }
- close(fd);
-}
-
-void QWaylandSelection::cancelled(void *data, struct wl_selection *selection)
-{
- Q_UNUSED(selection);
- delete static_cast<QWaylandSelection *>(data);
-}
-
-QWaylandClipboard *QWaylandClipboard::instance(QWaylandDisplay *display)
-{
- if (!clipboard)
- clipboard = new QWaylandClipboard(display);
- return clipboard;
-}
+#include "qwaylanddataoffer.h"
+#include "qwaylanddatasource.h"
+#include "qwaylanddatadevicemanager.h"
QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display)
- : mDisplay(display), mMimeDataIn(0), mOffer(0)
+ : mDisplay(display)
{
}
QWaylandClipboard::~QWaylandClipboard()
{
- if (mOffer)
- wl_selection_offer_destroy(mOffer);
- delete mMimeDataIn;
- qDeleteAll(mSelections);
-}
-
-void QWaylandClipboard::unregisterSelection(QWaylandSelection *selection)
-{
- mSelections.removeOne(selection);
-}
-void QWaylandClipboard::syncCallback(void *data, struct wl_callback *wl_callback, uint32_t time)
-{
- Q_UNUSED(wl_callback);
- Q_UNUSED(time);
- *static_cast<bool *>(data) = true;
-}
-const struct wl_callback_listener QWaylandClipboard::syncCallbackListener =
-{
- QWaylandClipboard::syncCallback
-};
-void QWaylandClipboard::forceRoundtrip(struct wl_display *display)
-{
- bool done = false;
- struct wl_callback *syncCallback = wl_display_sync(display);
- wl_callback_add_listener(syncCallback,&syncCallbackListener,&done);
- wl_display_iterate(display, WL_DISPLAY_WRITABLE);
- while (!done)
- wl_display_iterate(display, WL_DISPLAY_READABLE);
-}
-
-QVariant QWaylandClipboard::retrieveData(const QString &mimeType, QVariant::Type type) const
-{
- Q_UNUSED(type);
- if (mOfferedMimeTypes.isEmpty() || !mOffer)
- return QVariant();
- int pipefd[2];
- if (pipe(pipefd) == -1) {
- qWarning("QWaylandClipboard: pipe() failed");
- return QVariant();
- }
- QByteArray mimeTypeBa = mimeType.toLatin1();
- wl_selection_offer_receive(mOffer, mimeTypeBa.constData(), pipefd[1]);
- QByteArray content;
- forceRoundtrip(mDisplay->wl_display());
- char buf[256];
- int n;
- close(pipefd[1]);
- while ((n = QT_READ(pipefd[0], &buf, sizeof buf)) > 0)
- content.append(buf, n);
- close(pipefd[0]);
- return content;
}
QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
{
Q_ASSERT(mode == QClipboard::Clipboard);
- if (!mSelections.isEmpty())
- return mSelections.last()->mMimeData;
- if (!mMimeDataIn)
- mMimeDataIn = new QWaylandClipboardMimeData;
- mMimeDataIn->clearAll();
- if (!mOfferedMimeTypes.isEmpty() && mOffer)
- mMimeDataIn->setFormats(mOfferedMimeTypes);
- return mMimeDataIn;
+ if (!mDisplay->dndSelectionHandler())
+ return 0;
+
+ QWaylandDataSource *transfer_source = mDisplay->dndSelectionHandler()->selectionTransferSource();
+ if (transfer_source) { //if we have the keyboard focus and selectionTransferSource then we own the clipboard
+ return transfer_source->mimeData();
+ }
+ return mDisplay->dndSelectionHandler()->selectionTransfer();
}
void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
{
Q_ASSERT(mode == QClipboard::Clipboard);
- if (!mDisplay->inputDevices().isEmpty()) {
- if (!data)
- data = new QMimeData;
- mSelections.append(new QWaylandSelection(mDisplay, data));
- } else {
- qWarning("QWaylandClipboard::setMimeData: No input devices");
- }
+ if (mDisplay->dndSelectionHandler())
+ mDisplay->dndSelectionHandler()->createAndSetSelectionSource(data,mode);
}
bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const
@@ -261,49 +80,3 @@ bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const
return mode == QClipboard::Clipboard;
}
-const struct wl_selection_offer_listener QWaylandClipboard::selectionOfferListener = {
- QWaylandClipboard::offer,
- QWaylandClipboard::keyboardFocus
-};
-
-void QWaylandClipboard::createSelectionOffer(uint32_t id)
-{
- mOfferedMimeTypes.clear();
- if (mOffer)
- wl_selection_offer_destroy(mOffer);
- mOffer = 0;
- struct wl_selection_offer *offer = static_cast<struct wl_selection_offer *>
- (wl_display_bind(mDisplay->wl_display(), id,&wl_selection_offer_interface));
- qDebug() << "creating selection offer";
- wl_selection_offer_add_listener(offer, &selectionOfferListener, this);
-}
-
-void QWaylandClipboard::offer(void *data,
- struct wl_selection_offer *selection_offer,
- const char *type)
-{
- Q_UNUSED(data);
- Q_UNUSED(selection_offer);
- qDebug() << "received offer";
- clipboard->mOfferedMimeTypes.append(QString::fromLatin1(type));
-}
-
-void QWaylandClipboard::keyboardFocus(void *data,
- struct wl_selection_offer *selection_offer,
- wl_input_device *input_device)
-{
- Q_UNUSED(data);
- if (!input_device) {
- wl_selection_offer_destroy(selection_offer);
- clipboard->mOffer = 0;
- return;
- }
- clipboard->mOffer = selection_offer;
- if (clipboard->mSelections.isEmpty())
- QMetaObject::invokeMethod(&clipboard->mEmitter, "emitChanged", Qt::QueuedConnection);
-}
-
-void QWaylandClipboardSignalEmitter::emitChanged()
-{
- clipboard->emitChanged(QClipboard::Clipboard);
-}