summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/wayland/qwaylandclipboard.cpp255
-rw-r--r--src/plugins/platforms/wayland/qwaylandclipboard.h38
-rw-r--r--src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp312
-rw-r--r--src/plugins/platforms/wayland/qwaylanddatadevicemanager.h123
-rw-r--r--src/plugins/platforms/wayland/qwaylanddataoffer.cpp (renamed from src/plugins/platforms/wayland/qwaylandmime.cpp)103
-rw-r--r--src/plugins/platforms/wayland/qwaylanddataoffer.h (renamed from src/plugins/platforms/wayland/qwaylandmime.h)36
-rw-r--r--src/plugins/platforms/wayland/qwaylanddatasource.cpp114
-rw-r--r--src/plugins/platforms/wayland/qwaylanddatasource.h75
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.cpp57
-rw-r--r--src/plugins/platforms/wayland/qwaylanddisplay.h15
-rw-r--r--src/plugins/platforms/wayland/qwaylanddnd.cpp365
-rw-r--r--src/plugins/platforms/wayland/qwaylanddnd.h37
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp21
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.h4
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.cpp6
-rw-r--r--src/plugins/platforms/wayland/qwaylandintegration.h2
-rw-r--r--src/plugins/platforms/wayland/wayland.pro14
-rw-r--r--src/qt-compositor/compositor_api/waylandcompositor.cpp12
-rw-r--r--src/qt-compositor/wayland_wrapper/wayland_wrapper.pri23
-rw-r--r--src/qt-compositor/wayland_wrapper/wlcompositor.cpp47
-rw-r--r--src/qt-compositor/wayland_wrapper/wlcompositor.h10
-rw-r--r--src/qt-compositor/wayland_wrapper/wldatadevice.cpp136
-rw-r--r--src/qt-compositor/wayland_wrapper/wldatadevice.h89
-rw-r--r--src/qt-compositor/wayland_wrapper/wldatadevicemanager.cpp112
-rw-r--r--src/qt-compositor/wayland_wrapper/wldatadevicemanager.h (renamed from src/qt-compositor/wayland_wrapper/wldrag.h)75
-rw-r--r--src/qt-compositor/wayland_wrapper/wldataoffer.cpp128
-rw-r--r--src/qt-compositor/wayland_wrapper/wldataoffer.h79
-rw-r--r--src/qt-compositor/wayland_wrapper/wldatasource.cpp117
-rw-r--r--src/qt-compositor/wayland_wrapper/wldatasource.h85
-rw-r--r--src/qt-compositor/wayland_wrapper/wldrag.cpp277
-rw-r--r--src/qt-compositor/wayland_wrapper/wlinputdevice.cpp46
-rw-r--r--src/qt-compositor/wayland_wrapper/wlinputdevice.h14
-rw-r--r--src/qt-compositor/wayland_wrapper/wlselection.cpp380
-rw-r--r--src/qt-compositor/wayland_wrapper/wlselection.h111
-rw-r--r--src/qt-compositor/wayland_wrapper/wlshell.cpp24
-rw-r--r--src/qt-compositor/wayland_wrapper/wlshell.h10
-rw-r--r--src/qt-compositor/wayland_wrapper/wlsurface.cpp12
-rw-r--r--src/qt-compositor/wayland_wrapper/wlsurface.h2
-rw-r--r--src/qt-compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp8
39 files changed, 1802 insertions, 1572 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);
-}
diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.h b/src/plugins/platforms/wayland/qwaylandclipboard.h
index 52d686f03..da9f26017 100644
--- a/src/plugins/platforms/wayland/qwaylandclipboard.h
+++ b/src/plugins/platforms/wayland/qwaylandclipboard.h
@@ -43,27 +43,14 @@
#define QWAYLANDCLIPBOARD_H
#include <QtGui/QPlatformClipboard>
-#include <QtCore/QStringList>
#include <QtCore/QVariant>
-#include <wayland-client.h>
-
class QWaylandDisplay;
-class QWaylandSelection;
-class QWaylandClipboardMimeData;
-struct wl_selection_offer;
-
-class QWaylandClipboardSignalEmitter : public QObject
-{
- Q_OBJECT
-public slots:
- void emitChanged();
-};
class QWaylandClipboard : public QPlatformClipboard
{
public:
- static QWaylandClipboard *instance(QWaylandDisplay *display);
+ QWaylandClipboard(QWaylandDisplay *display);
~QWaylandClipboard();
@@ -71,33 +58,10 @@ public:
void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
bool supportsMode(QClipboard::Mode mode) const;
- void unregisterSelection(QWaylandSelection *selection);
-
- void createSelectionOffer(uint32_t id);
-
QVariant retrieveData(const QString &mimeType, QVariant::Type type) const;
private:
- QWaylandClipboard(QWaylandDisplay *display);
-
- static void offer(void *data,
- struct wl_selection_offer *selection_offer,
- const char *type);
- static void keyboardFocus(void *data,
- struct wl_selection_offer *selection_offer,
- struct wl_input_device *input_device);
- static const struct wl_selection_offer_listener selectionOfferListener;
-
- static const struct wl_callback_listener syncCallbackListener;
- static void syncCallback(void *data, struct wl_callback *wl_callback, uint32_t time);
- static void forceRoundtrip(struct wl_display *display);
-
QWaylandDisplay *mDisplay;
- QWaylandClipboardMimeData *mMimeDataIn;
- QList<QWaylandSelection *> mSelections;
- QStringList mOfferedMimeTypes;
- struct wl_selection_offer *mOffer;
- QWaylandClipboardSignalEmitter mEmitter;
};
#endif // QWAYLANDCLIPBOARD_H
diff --git a/src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp b/src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp
new file mode 100644
index 000000000..cf718744f
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddatadevicemanager.cpp
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylanddatadevicemanager.h"
+
+#include "qwaylandinputdevice.h"
+#include "qwaylanddataoffer.h"
+#include "qwaylanddatasource.h"
+#include "qwaylandshmbackingstore.h"
+
+#include <wayland-client-protocol.h>
+#include <wayland-client.h>
+
+#include <QtGui/QGuiApplication>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QPlatformClipboard>
+#include <QtGui/QPainter>
+
+#include <QWindowSystemInterface>
+
+#include <QtCore/QDebug>
+
+void QWaylandDataDeviceManager::data_offer(void *data,
+ struct wl_data_device *data_device,
+ uint32_t id)
+{
+
+ QWaylandDataDeviceManager *handler = static_cast<QWaylandDataDeviceManager *>(data);
+ //this will be hidden with a wl function call in the near future I hope, but I suppose the scanner
+ //doesn't support it yet
+ struct wl_proxy *newId = wl_proxy_create_for_id(reinterpret_cast<struct wl_proxy *>(data_device),
+ id, &wl_data_offer_interface);
+ struct wl_data_offer *data_offer =
+ reinterpret_cast<struct wl_data_offer *>(newId);
+
+
+ new QWaylandDataOffer(handler->display(),data_offer);
+}
+
+void QWaylandDataDeviceManager::enter(void *data,
+ struct wl_data_device *wl_data_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ int32_t x,
+ int32_t y,
+ struct wl_data_offer *id)
+{
+ Q_UNUSED(wl_data_device);
+ QWaylandDataDeviceManager *data_device_manager = static_cast<QWaylandDataDeviceManager *>(data);
+ if (time < data_device_manager->m_drag_last_event_time)
+ return;
+ data_device_manager->m_drag_last_event_time = time;
+
+ data_device_manager->m_drag_current_event_window = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface));
+ if (!surface)
+ return;
+ QWaylandDataOffer *offer = static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id));
+ if (!offer)
+ return;
+
+ QPoint point(x,y);
+ Qt::DropActions allActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
+ QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(data_device_manager->m_drag_current_event_window->window(),
+ offer,point,allActions);
+ data_device_manager->m_drag_can_drop = response.accepted();
+ data_device_manager->m_drag_data_offer = offer;
+ if (data_device_manager->m_drag_can_drop) {
+ const char *first_offer = qPrintable(offer->formats_sys().at(0));
+ wl_data_offer_accept(offer->handle(),QWaylandDisplay::currentTimeMillisec(),first_offer);
+ } else {
+ wl_data_offer_accept(offer->handle(),QWaylandDisplay::currentTimeMillisec(),0);
+ }
+}
+
+void QWaylandDataDeviceManager::leave(void *data,
+ struct wl_data_device *wl_data_device)
+{
+ QWaylandDataDeviceManager *data_device_manager = static_cast<QWaylandDataDeviceManager *>(data);
+ QWindowSystemInterface::handleDrag(data_device_manager->m_drag_current_event_window->window(),0,QPoint(0,0),Qt::IgnoreAction);
+ data_device_manager->m_drag_can_drop = false;
+ data_device_manager->m_drag_data_offer = 0;
+ data_device_manager->m_drag_last_event_time = 0;
+ data_device_manager->m_drag_current_event_window = 0;
+ data_device_manager->m_drag_position = QPoint();
+}
+
+void QWaylandDataDeviceManager::motion(void *data,
+ struct wl_data_device *wl_data_device,
+ uint32_t time,
+ int32_t x,
+ int32_t y)
+{
+ Q_UNUSED(wl_data_device);
+ QWaylandDataDeviceManager *data_device_manager = static_cast<QWaylandDataDeviceManager *>(data);
+ if (time < data_device_manager->m_drag_last_event_time)
+ return;
+ data_device_manager->m_drag_position = QPoint(x,y);
+
+ Qt::DropActions allActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
+ QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(data_device_manager->m_drag_current_event_window->window(),
+ data_device_manager->m_drag_data_offer, data_device_manager->m_drag_position ,allActions);
+ data_device_manager->m_drag_can_drop = response.accepted();
+ const char *offerMime = 0;
+ if (response.accepted()) {
+ offerMime = qPrintable(data_device_manager->m_drag_data_offer->formats_sys().at(0));
+ }
+ wl_data_offer_accept(data_device_manager->m_drag_data_offer->handle(),QWaylandDisplay::currentTimeMillisec(),offerMime);
+}
+
+void QWaylandDataDeviceManager::drop(void *data,
+ struct wl_data_device *wl_data_device)
+{
+ QWaylandDataDeviceManager *data_device_manager = static_cast<QWaylandDataDeviceManager *>(data);
+ QWindow *window = data_device_manager->m_drag_current_event_window->window();
+ QMimeData *mime = data_device_manager->m_drag_data_offer;
+ QPoint point = data_device_manager->m_drag_position;
+ Qt::DropActions allActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
+
+ QWindowSystemInterface::handleDrop(window,mime,point,allActions);
+}
+
+
+void QWaylandDataDeviceManager::selection(void *data,
+ struct wl_data_device *wl_data_device,
+ struct wl_data_offer *id)
+{
+ QWaylandDataDeviceManager *handler = static_cast<QWaylandDataDeviceManager *>(data);
+ QWaylandDataOffer *mime = handler->m_selection_data_offer;
+ delete mime;
+ QWaylandDataSource *transfer_source = handler->m_selection_data_source;
+ delete transfer_source;
+ handler->m_selection_data_source = 0;
+
+ mime = static_cast<QWaylandDataOffer *>(wl_data_offer_get_user_data(id));
+ handler->m_selection_data_offer = mime;
+}
+
+const struct wl_data_device_listener QWaylandDataDeviceManager::transfer_device_listener = {
+ QWaylandDataDeviceManager::data_offer,
+ QWaylandDataDeviceManager::enter,
+ QWaylandDataDeviceManager::leave,
+ QWaylandDataDeviceManager::motion,
+ QWaylandDataDeviceManager::drop,
+ QWaylandDataDeviceManager::selection
+};
+
+QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id)
+ : m_display(display)
+ , m_selection_data_offer(0)
+ , m_selection_data_source(0)
+ , m_drag_data_offer(0)
+ , m_drag_data_source(0)
+ , m_drag_surface(0)
+ , m_drag_buffer(0)
+ , m_drag_can_drop(false)
+{
+ m_data_device_manager = static_cast<struct wl_data_device_manager *>(wl_display_bind(display->wl_display(),id,&wl_data_device_manager_interface));
+
+ //create transfer devices for all input devices
+ QList<QWaylandInputDevice *> inputDevices = m_display->inputDevices();
+ for (int i = 0; i < inputDevices.size();i++) {
+ inputDevices.at(i)->setTransferDevice(getDataDevice(inputDevices.at(i)));
+ }
+}
+
+QWaylandDataDeviceManager::~QWaylandDataDeviceManager()
+{
+ wl_data_device_manager_destroy(m_data_device_manager);
+}
+
+struct wl_data_device *QWaylandDataDeviceManager::getDataDevice(QWaylandInputDevice *inputDevice)
+{
+ struct wl_data_device *transfer_device = wl_data_device_manager_get_data_device(m_data_device_manager,inputDevice->wl_input_device());
+ wl_data_device_add_listener(transfer_device,&transfer_device_listener,this);
+
+ return transfer_device;
+}
+
+void QWaylandDataDeviceManager::setNewClipboardMimeData(QWaylandDataOffer *mime)
+{
+ if (m_selection_data_offer) {
+ qDebug() << "This function should not be called when there is an exising selection";
+ delete m_selection_data_offer;
+ }
+ m_selection_data_offer = mime;
+ QGuiApplicationPrivate::platformIntegration()->clipboard()->emitChanged(QClipboard::Clipboard);
+}
+
+
+QWaylandDataOffer *QWaylandDataDeviceManager::selectionTransfer() const
+{
+ return m_selection_data_offer;
+}
+
+void QWaylandDataDeviceManager::createAndSetDrag(QDrag *drag)
+{
+ if (m_drag_data_source) {
+ qDebug() << "QWaylandDndSelectionHandler::createAndSetDrag: Allready have a valid drag";
+ delete m_drag_data_source;
+ }
+
+ delete m_drag_data_offer;
+ m_drag_data_offer = 0;
+
+ m_drag_data_source = new QWaylandDataSource(this,drag->mimeData());
+
+ struct wl_data_device *transfer_device = m_display->lastKeyboardFocusInputDevice()->transferDevice();
+ m_drag_surface = m_display->createSurface(this);
+ QPixmap pixmap = drag->pixmap();
+ if (pixmap.isNull()) {
+ pixmap = QPlatformDrag::defaultPixmap();
+ }
+ m_drag_buffer = new QWaylandShmBuffer(m_display,pixmap.size(),QImage::Format_ARGB32_Premultiplied);
+
+ {
+ QPainter p(m_drag_buffer->image());
+ p.drawPixmap(0,0,pixmap);
+ }
+
+ wl_data_device_start_drag(transfer_device,m_drag_data_source->handle(),m_drag_surface,QWaylandDisplay::currentTimeMillisec());
+ wl_data_device_attach(transfer_device,QWaylandDisplay::currentTimeMillisec()
+ ,m_drag_buffer->buffer(),drag->hotSpot().x(),drag->hotSpot().y());
+}
+
+QMimeData *QWaylandDataDeviceManager::dragMime() const
+{
+ if (m_drag_data_offer) {
+ return m_drag_data_offer;
+ } else if (m_drag_data_source){
+ return m_drag_data_source->mimeData();
+ }
+ return 0;
+}
+
+bool QWaylandDataDeviceManager::canDropDrag() const
+{
+ return m_drag_can_drop;
+}
+
+void QWaylandDataDeviceManager::cancelDrag()
+{
+ wl_data_source_destroy(m_drag_data_source->handle() );
+ m_drag_data_source = 0;
+}
+
+void QWaylandDataDeviceManager::createAndSetSelectionSource(QMimeData *mimeData, QClipboard::Mode mode)
+{
+ QWaylandDataSource *transfer_source = m_selection_data_source;
+ delete transfer_source;
+
+ transfer_source = new QWaylandDataSource(this,mimeData);
+ m_selection_data_source = transfer_source;
+
+ struct wl_data_device *transfer_device = m_display->lastKeyboardFocusInputDevice()->transferDevice();
+ wl_data_device_set_selection(transfer_device,transfer_source->handle(),QWaylandDisplay::currentTimeMillisec());
+}
+
+QWaylandDataSource *QWaylandDataDeviceManager::selectionTransferSource()
+{
+ return m_selection_data_source;
+}
+
+
+QWaylandDisplay * QWaylandDataDeviceManager::display() const
+{
+ return m_display;
+}
+
+struct wl_data_device_manager *QWaylandDataDeviceManager::handle() const
+{
+ return m_data_device_manager;
+}
+
+
diff --git a/src/plugins/platforms/wayland/qwaylanddatadevicemanager.h b/src/plugins/platforms/wayland/qwaylanddatadevicemanager.h
new file mode 100644
index 000000000..d2c7cc909
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddatadevicemanager.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDDATADEVICEMANAGER_H
+#define QWAYLANDDATADEVICEMANAGER_H
+
+#include "qwaylanddisplay.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QMimeData>
+#include <QtCore/QStringList>
+#include <QtGui/QClipboard>
+
+class QWaylandDataOffer;
+class QWaylandDataSource;
+class QDrag;
+class QWaylandShmBuffer;
+class QWaylandWindow;
+
+class QWaylandDataDeviceManager
+{
+public:
+ QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id);
+ ~QWaylandDataDeviceManager();
+
+ struct wl_data_device *getDataDevice(QWaylandInputDevice *inputDevice);
+
+ void setNewClipboardMimeData(QWaylandDataOffer *mimeData);
+ QWaylandDataOffer *selectionTransfer() const;
+
+ void createAndSetDrag(QDrag *drag);
+ QMimeData *dragMime() const;
+ bool canDropDrag() const;
+ void cancelDrag();
+
+ void createAndSetSelectionSource(QMimeData *mimeData, QClipboard::Mode mode);
+ QWaylandDataSource *selectionTransferSource();
+
+ QWaylandDisplay *display()const;
+
+ struct wl_data_device_manager *handle() const;
+
+private:
+ struct wl_data_device_manager *m_data_device_manager;
+ QWaylandDisplay *m_display;
+
+ QWaylandDataOffer *m_selection_data_offer;
+ QWaylandDataSource *m_selection_data_source;
+
+ QWaylandDataOffer *m_drag_data_offer;
+ QWaylandDataSource *m_drag_data_source;
+ QWaylandWindow *m_drag_current_event_window;
+ struct wl_surface *m_drag_surface;
+ QWaylandShmBuffer *m_drag_buffer;
+ bool m_drag_can_drop;
+ uint32_t m_drag_last_event_time;
+ QPoint m_drag_position;
+
+ static void data_offer(void *data,
+ struct wl_data_device *wl_data_device,
+ uint32_t id);
+ static void enter(void *data,
+ struct wl_data_device *wl_data_device,
+ uint32_t time,
+ struct wl_surface *surface,
+ int32_t x,
+ int32_t y,
+ struct wl_data_offer *id);
+ static void leave(void *data,
+ struct wl_data_device *wl_data_device);
+ static void motion(void *data,
+ struct wl_data_device *wl_data_device,
+ uint32_t time,
+ int32_t x,
+ int32_t y);
+ static void drop(void *data,
+ struct wl_data_device *wl_data_device);
+ static void selection(void *data,
+ struct wl_data_device *wl_data_device,
+ struct wl_data_offer *id);
+
+ static const struct wl_data_device_listener transfer_device_listener;
+};
+
+#endif // QWAYLANDDATADEVICEMANAGER_H
diff --git a/src/plugins/platforms/wayland/qwaylandmime.cpp b/src/plugins/platforms/wayland/qwaylanddataoffer.cpp
index c218d7ddb..a5e0ed4ac 100644
--- a/src/plugins/platforms/wayland/qwaylandmime.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddataoffer.cpp
@@ -39,13 +39,21 @@
**
****************************************************************************/
-#include "qwaylandmime.h"
+#include "qwaylanddataoffer.h"
+
+#include "qwaylanddatadevicemanager.h"
+
#include <QImage>
#include <QColor>
#include <QUrl>
#include <QBuffer>
#include <QImageWriter>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/QPlatformClipboard>
+
+#include <QtCore/QDebug>
+
QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &mimeType)
{
QByteArray content;
@@ -81,3 +89,96 @@ QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &
}
return content;
}
+
+
+void QWaylandDataOffer::offer_sync_callback(void *data,
+ struct wl_callback *wl_callback,
+ uint32_t time)
+{
+ QWaylandDataOffer *mime = static_cast<QWaylandDataOffer *>(data);
+ mime->m_receiving_offers = false;
+}
+
+const struct wl_callback_listener QWaylandDataOffer::offer_sync_callback_listener = {
+ QWaylandDataOffer::offer_sync_callback
+};
+
+void QWaylandDataOffer::offer(void *data,
+ struct wl_data_offer *wl_data_offer,
+ const char *type)
+{
+ Q_UNUSED(wl_data_offer);
+
+ QWaylandDataOffer *data_offer = static_cast<QWaylandDataOffer *>(data);
+
+ if (!data_offer->m_receiving_offers) {
+ struct wl_callback *callback = wl_display_sync(data_offer->m_display->wl_display());
+ wl_callback_add_listener(callback,&offer_sync_callback_listener,data_offer);
+ data_offer->m_receiving_offers = true;
+ }
+
+ data_offer->m_offered_mime_types.append(QString::fromLocal8Bit(type));
+ qDebug() << data_offer->m_offered_mime_types;
+}
+
+const struct wl_data_offer_listener QWaylandDataOffer::data_offer_listener = {
+ QWaylandDataOffer::offer
+};
+
+QWaylandDataOffer::QWaylandDataOffer(QWaylandDisplay *display, struct wl_data_offer *data_offer)
+ : m_display(display)
+ , m_receiving_offers(false)
+{
+ m_data_offer = data_offer;
+ wl_data_offer_set_user_data(m_data_offer,this);
+ wl_data_offer_add_listener(m_data_offer,&data_offer_listener,this);
+}
+
+QWaylandDataOffer::~QWaylandDataOffer()
+{
+ wl_data_offer_destroy(m_data_offer);
+}
+
+bool QWaylandDataOffer::hasFormat_sys(const QString &mimeType) const
+{
+ return m_offered_mime_types.contains(mimeType);
+}
+
+QStringList QWaylandDataOffer::formats_sys() const
+{
+ return m_offered_mime_types;
+}
+
+QVariant QWaylandDataOffer::retrieveData_sys(const QString &mimeType, QVariant::Type type) const
+{
+ Q_UNUSED(type);
+ if (m_offered_mime_types.isEmpty())
+ return QVariant();
+
+ int pipefd[2];
+ if (pipe(pipefd) == -1) {
+ qWarning("QWaylandMimeData: pipe() failed");
+ return QVariant();
+ }
+
+ QByteArray mimeTypeBa = mimeType.toLatin1();
+ wl_data_offer_receive(m_data_offer,mimeTypeBa.constData(),pipefd[1]);
+
+ m_display->forceRoundTrip();
+ close(pipefd[1]);
+
+ QByteArray content;
+ char buf[256];
+ int n;
+ while ((n = QT_READ(pipefd[0], &buf, sizeof buf)) > 0) {
+ content.append(buf, n);
+ }
+
+ close(pipefd[0]);
+ return content;
+}
+
+struct wl_data_offer *QWaylandDataOffer::handle() const
+{
+ return m_data_offer;
+}
diff --git a/src/plugins/platforms/wayland/qwaylandmime.h b/src/plugins/platforms/wayland/qwaylanddataoffer.h
index 5f6ed954a..99056a4d5 100644
--- a/src/plugins/platforms/wayland/qwaylandmime.h
+++ b/src/plugins/platforms/wayland/qwaylanddataoffer.h
@@ -39,17 +39,49 @@
**
****************************************************************************/
-#ifndef QWAYLANDMIME_H
-#define QWAYLANDMIME_H
+#ifndef QWAYLANDDATAOFFER_H
+#define QWAYLANDDATAOFFER_H
#include <QString>
#include <QByteArray>
#include <QMimeData>
+#include <QtGui/private/qdnd_p.h>
+#include <QtGui/QClipboard>
+
+#include <stdint.h>
+
+class QWaylandDisplay;
+
class QWaylandMimeHelper
{
public:
static QByteArray getByteArray(QMimeData *mimeData, const QString &mimeType);
};
+class QWaylandDataOffer : public QInternalMimeData
+{
+public:
+ QWaylandDataOffer(QWaylandDisplay *display, struct wl_data_offer *offer);
+ ~QWaylandDataOffer();
+
+ bool hasFormat_sys(const QString &mimeType) const;
+ QStringList formats_sys() const;
+ QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
+
+ struct wl_data_offer *handle() const;
+private:
+
+ struct wl_data_offer *m_data_offer;
+ QWaylandDisplay *m_display;
+ QStringList m_offered_mime_types;
+ bool m_receiving_offers;
+
+ static void offer(void *data, struct wl_data_offer *wl_data_offer, const char *type);
+ static const struct wl_data_offer_listener data_offer_listener;
+
+ static void offer_sync_callback(void *data, struct wl_callback *wl_callback, uint32_t time);
+ static const struct wl_callback_listener offer_sync_callback_listener;
+};
+
#endif
diff --git a/src/plugins/platforms/wayland/qwaylanddatasource.cpp b/src/plugins/platforms/wayland/qwaylanddatasource.cpp
new file mode 100644
index 000000000..adf1dba51
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddatasource.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylanddatasource.h"
+
+#include "qwaylanddataoffer.h"
+#include "qwaylandinputdevice.h"
+
+#include <QtCore/QFile>
+
+#include <QtCore/QDebug>
+
+void QWaylandDataSource::data_source_target(void *data,
+ struct wl_data_source *wl_data_source,
+ const char *mime_type)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(wl_data_source);
+ Q_UNUSED(mime_type);
+}
+
+void QWaylandDataSource::data_source_send(void *data,
+ struct wl_data_source *wl_data_source,
+ const char *mime_type,
+ int32_t fd)
+{
+ QWaylandDataSource *self = static_cast<QWaylandDataSource *>(data);
+ QString mimeType = QString::fromLatin1(mime_type);
+ QByteArray content = QWaylandMimeHelper::getByteArray(self->m_mime_data, mimeType);
+ if (!content.isEmpty()) {
+ QFile f;
+ if (f.open(fd, QIODevice::WriteOnly))
+ f.write(content);
+ }
+ close(fd);
+}
+
+void QWaylandDataSource::data_source_cancelled(void *data,
+ struct wl_data_source *wl_data_source)
+{
+ Q_UNUSED(data);
+ Q_UNUSED(wl_data_source);
+}
+
+const struct wl_data_source_listener QWaylandDataSource::data_source_listener = {
+ data_source_target,
+ data_source_send,
+ data_source_cancelled
+};
+
+QWaylandDataSource::QWaylandDataSource(QWaylandDataDeviceManager *dndSelectionHandler, QMimeData *mimeData)
+ : m_mime_data(mimeData)
+{
+ m_data_source = wl_data_device_manager_create_data_source(dndSelectionHandler->handle());
+ wl_data_source_add_listener(m_data_source,&data_source_listener,this);
+ QStringList formats = mimeData->formats();
+ for (int i = 0; i < formats.size(); i++) {
+ const char *offer = qPrintable(formats.at(i));
+ wl_data_source_offer(m_data_source,offer);
+ }
+}
+
+QWaylandDataSource::~QWaylandDataSource()
+{
+ wl_data_source_destroy(m_data_source);
+}
+
+QMimeData * QWaylandDataSource::mimeData() const
+{
+ return m_mime_data;
+}
+
+struct wl_data_source *QWaylandDataSource::handle() const
+{
+ return m_data_source;
+}
diff --git a/src/plugins/platforms/wayland/qwaylanddatasource.h b/src/plugins/platforms/wayland/qwaylanddatasource.h
new file mode 100644
index 000000000..0adb36b68
--- /dev/null
+++ b/src/plugins/platforms/wayland/qwaylanddatasource.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDDATASOURCE_H
+#define QWAYLANDDATASOURCE_H
+
+#include "qwaylanddatadevicemanager.h"
+
+#include <wayland-client-protocol.h>
+
+class QWaylandDataSource
+{
+public:
+ QWaylandDataSource(QWaylandDataDeviceManager *dndSelectionHandler, QMimeData *mimeData);
+ ~QWaylandDataSource();
+
+ QMimeData *mimeData() const;
+
+ struct wl_data_source *handle() const;
+private:
+ struct wl_data_source *m_data_source;
+ QWaylandDisplay *m_display;
+ QMimeData *m_mime_data;
+
+ static void data_source_target(void *data,
+ struct wl_data_source *data_source,
+ const char *mime_type);
+ static void data_source_send(void *data,
+ struct wl_data_source *data_source,
+ const char *mime_type,
+ int32_t fd);
+ static void data_source_cancelled(void *data,
+ struct wl_data_source *data_source);
+ static const struct wl_data_source_listener data_source_listener;
+};
+
+#endif // QWAYLANDDATASOURCE_H
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
index dbc0ff70e..8864e40fe 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp
@@ -46,7 +46,7 @@
#include "qwaylandcursor.h"
#include "qwaylandinputdevice.h"
#include "qwaylandclipboard.h"
-#include "qwaylanddnd.h"
+#include "qwaylanddatadevicemanager.h"
#ifdef QT_WAYLAND_GL_SUPPORT
#include "gl_integration/qwaylandglintegration.h"
@@ -69,6 +69,8 @@
// lock used to syncronize swap-buffers with the display-event-loop
QMutex g_waylandLock;
+#include <QtCore/QDebug>
+
struct wl_surface *QWaylandDisplay::createSurface(void *handle)
{
struct wl_surface * surface = wl_compositor_create_surface(mCompositor);
@@ -90,6 +92,17 @@ QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration()
}
#endif
+QWaylandInputDevice *QWaylandDisplay::lastKeyboardFocusInputDevice() const
+{
+ return mLastKeyboardFocusInputDevice;
+}
+
+void QWaylandDisplay::setLastKeyboardFocusInputDevice(QWaylandInputDevice *device)
+{
+ qDebug() << "setting last keyboard focus input device" << device;
+ mLastKeyboardFocusInputDevice = device;
+}
+
void QWaylandDisplay::shellHandleConfigure(void *data, struct wl_shell *shell,
uint32_t time, uint32_t edges,
struct wl_surface *surface,
@@ -111,7 +124,8 @@ const struct wl_shell_listener QWaylandDisplay::shellListener = {
static QWaylandDisplay *display = 0;
QWaylandDisplay::QWaylandDisplay(void)
- : argb_visual(0), premultiplied_argb_visual(0), rgb_visual(0)
+ : mDndSelectionHandler(0)
+ , mLastKeyboardFocusInputDevice(0)
{
display = this;
qRegisterMetaType<uint32_t>("uint32_t");
@@ -292,10 +306,41 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id,
QWaylandInputDevice *inputDevice =
new QWaylandInputDevice(this, id);
mInputDevices.append(inputDevice);
- } else if (interface == "wl_selection_offer") {
- QWaylandClipboard::instance(display)->createSelectionOffer(id);
- } else if (interface == "wl_drag_offer") {
- QWaylandDrag::instance(display)->createDragOffer(id);
+ } else if (interface == "wl_data_device_manager") {
+ mDndSelectionHandler = new QWaylandDataDeviceManager(this, id);
}
}
+uint32_t QWaylandDisplay::currentTimeMillisec()
+{
+ //### we throw away the time information
+ struct timeval tv;
+ int ret = gettimeofday(&tv, 0);
+ if (ret == 0)
+ return tv.tv_sec*1000 + tv.tv_usec/1000;
+ return 0;
+}
+
+void QWaylandDisplay::force_roundtrip_sync_callback(void *data, struct wl_callback *wl_callback, uint32_t time)
+{
+ Q_UNUSED(wl_callback);
+ Q_UNUSED(time);
+
+ int *round_trip = (int *)data;
+ *round_trip = true;
+}
+
+const struct wl_callback_listener QWaylandDisplay::force_roundtrip_sync_callback_listener = {
+ QWaylandDisplay::force_roundtrip_sync_callback
+};
+
+void QWaylandDisplay::forceRoundTrip()
+{
+ int round_trip = false;
+ wl_callback *sync_callback = wl_display_sync(mDisplay);
+ wl_callback_add_listener(sync_callback,&force_roundtrip_sync_callback_listener,&round_trip);
+ flushRequests();
+ while (!round_trip) {
+ readEvents();
+ }
+}
diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h
index b5eabfdd7..42fea8658 100644
--- a/src/plugins/platforms/wayland/qwaylanddisplay.h
+++ b/src/plugins/platforms/wayland/qwaylanddisplay.h
@@ -57,6 +57,7 @@ class QPlatformScreen;
class QWaylandScreen;
class QWaylandGLIntegration;
class QWaylandWindowManagerIntegration;
+class QWaylandDataDeviceManager;
class QWaylandDisplay : public QObject {
Q_OBJECT
@@ -86,9 +87,17 @@ public:
QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; }
+ QWaylandInputDevice *lastKeyboardFocusInputDevice() const;
+ void setLastKeyboardFocusInputDevice(QWaylandInputDevice *device);
+
+ QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler; }
+
struct wl_shell *shell() const {return mShell; }
struct wl_shm *shm() const { return mShm; }
+ static uint32_t currentTimeMillisec();
+
+ void forceRoundTrip();
public slots:
void createNewScreen(struct wl_output *output, QRect geometry);
void readEvents();
@@ -107,6 +116,8 @@ private:
struct wl_shell *mShell;
QList<QPlatformScreen *> mScreens;
QList<QWaylandInputDevice *> mInputDevices;
+ QWaylandInputDevice *mLastKeyboardFocusInputDevice;
+ QWaylandDataDeviceManager *mDndSelectionHandler;
QSocketNotifier *mReadNotifier;
int mFd;
@@ -114,7 +125,6 @@ private:
uint32_t mSocketMask;
- struct wl_visual *argb_visual, *premultiplied_argb_visual, *rgb_visual;
static const struct wl_output_listener outputListener;
static int sourceUpdate(uint32_t mask, void *data);
@@ -149,6 +159,9 @@ private:
struct wl_surface *surface,
int32_t width, int32_t height);
+ static void force_roundtrip_sync_callback(void *data, struct wl_callback *wl_callback, uint32_t time);
+ static const struct wl_callback_listener force_roundtrip_sync_callback_listener;
+
static const struct wl_shell_listener shellListener;
};
diff --git a/src/plugins/platforms/wayland/qwaylanddnd.cpp b/src/plugins/platforms/wayland/qwaylanddnd.cpp
index 1ebd3b8eb..49af60140 100644
--- a/src/plugins/platforms/wayland/qwaylanddnd.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddnd.cpp
@@ -40,384 +40,49 @@
****************************************************************************/
#include "qwaylanddnd.h"
-#include "qwaylandinputdevice.h"
-#include <QStringList>
-#include <QFile>
-#include <QtGui/private/qdnd_p.h>
-#include <QGuiApplication>
-#include <QSocketNotifier>
-#include <sys/time.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <QDebug>
-#include <QPlatformCursor>
-#include "qwaylandcursor.h"
-
-class QWaylandDragWrapper
-{
-public:
- QWaylandDragWrapper(QWaylandDisplay *display, QMimeData *data);
- ~QWaylandDragWrapper();
- QMimeData *mimeData() const { return mData; }
-
-private:
- static void target(void *data, wl_drag *drag, const char *mimeType);
- static void finish(void *data, wl_drag *drag, int fd);
- static void reject(void *data, wl_drag *drag);
- static const wl_drag_listener dragListener;
-
- QWaylandDisplay *mDisplay;
- wl_drag *mDrag;
- QMimeData *mData;
- QString mAcceptedType;
-};
-
-class QWaylandDragOfferWrapper
-{
-public:
- QWaylandDragOfferWrapper(QWaylandDisplay *display, QMimeData *data, uint32_t id);
- ~QWaylandDragOfferWrapper();
-
-private:
- static void offer(void *data, struct wl_drag_offer *offer, const char *mimeType);
- static void pointerFocus(void *data, struct wl_drag_offer *offer, uint32_t time,
- wl_surface *surface,
- int32_t x, int32_t y,
- int32_t surfaceX, int32_t surfaceY);
- static void motion(void *data, struct wl_drag_offer *offer, uint32_t time,
- int32_t x, int32_t y,
- int32_t surfaceX, int32_t surfaceY);
- static void drop(void *data, struct wl_drag_offer *offer);
- static const wl_drag_offer_listener dragOfferListener;
-
- void sendEventToWindow(struct wl_drag_offer *offer, uint32_t time,
- wl_surface *surface, const QPoint &pos);
-
- QWaylandDisplay *mDisplay;
- QMimeData *mData;
- struct wl_drag_offer *mOffer;
- QMimeData mOfferedTypes; // no data in this one, just the formats
- wl_surface *mFocusSurface;
- bool mAccepted;
- QPoint mLastEventPos;
- friend class QWaylandDrag;
-};
-
-static QWaylandDrag *dnd = 0;
-
-QWaylandDrag *QWaylandDrag::instance(QWaylandDisplay *display)
-{
- if (!dnd)
- dnd = new QWaylandDrag(display);
- return dnd;
-}
+#include "qwaylanddatadevicemanager.h"
QWaylandDrag::QWaylandDrag(QWaylandDisplay *display)
- : mDisplay(display), mDropData(0), mCurrentDrag(0), mCurrentOffer(0)
-{
- mDropData = new QMimeData;
-}
-
-QWaylandDrag::~QWaylandDrag()
-{
- delete mCurrentDrag;
- delete mCurrentOffer;
- delete mDropData;
-}
-
-QMimeData *QWaylandDrag::platformDropData()
-{
- return mDropData;
-}
-
-static void showDragPixmap(bool show)
-{
- QCursor c(QDragManager::self()->object->pixmap());
- QList<QWeakPointer<QPlatformCursor> > cursors = QPlatformCursorPrivate::getInstances();
- foreach (QWeakPointer<QPlatformCursor> cursor, cursors)
- if (cursor)
- static_cast<QWaylandCursor *>(cursor.data())->setupPixmapCursor(show ? &c : 0);
-}
-
-
-QWaylandDragWrapper::QWaylandDragWrapper(QWaylandDisplay *display, QMimeData *data)
- : mDisplay(display), mDrag(0), mData(data)
-{
- QWaylandWindow *w = mDisplay->inputDevices().at(0)->pointerFocus();
- if (!w) {
- qWarning("QWaylandDragWrapper: No window with pointer focus?!");
- return;
- }
- qDebug() << "QWaylandDragWrapper" << data->formats();
- struct wl_shell *shell = display->wl_shell();
- mDrag = wl_shell_create_drag(shell);
- wl_drag_add_listener(mDrag, &dragListener, this);
- foreach (const QString &format, data->formats())
- wl_drag_offer(mDrag, format.toLatin1().constData());
- struct timeval tv;
- gettimeofday(&tv, 0);
- wl_drag_activate(mDrag,
- w->wl_surface(),
- display->inputDevices().at(0)->wl_input_device(),
- tv.tv_sec * 1000 + tv.tv_usec / 1000);
- showDragPixmap(true);
-}
-
-QWaylandDragWrapper::~QWaylandDragWrapper()
-{
- QWaylandDrag *dragHandler = QWaylandDrag::instance(mDisplay);
- if (dragHandler->mCurrentDrag == this)
- dragHandler->mCurrentDrag = 0;
- wl_drag_destroy(mDrag);
-}
-
-const wl_drag_listener QWaylandDragWrapper::dragListener = {
- QWaylandDragWrapper::target,
- QWaylandDragWrapper::finish,
- QWaylandDragWrapper::reject
-};
-
-void QWaylandDragWrapper::target(void *data, wl_drag *drag, const char *mimeType)
-{
- Q_UNUSED(drag);
- QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
- self->mAcceptedType = mimeType ? QString::fromLatin1(mimeType) : QString();
- qDebug() << "target" << self->mAcceptedType;
- QDragManager *manager = QDragManager::self();
- if (mimeType)
- manager->global_accepted_action = manager->defaultAction(manager->possible_actions,
- QGuiApplication::keyboardModifiers());
- else
- manager->global_accepted_action = Qt::IgnoreAction;
-}
-
-void QWaylandDragWrapper::finish(void *data, wl_drag *drag, int fd)
+ : m_display(display)
{
- Q_UNUSED(drag);
- QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
- qDebug() << "finish" << self->mAcceptedType;
- if (self->mAcceptedType.isEmpty())
- return; // no drag target was valid when the drag finished
- QByteArray content = self->mData->data(self->mAcceptedType);
- if (!content.isEmpty()) {
- QFile f;
- if (f.open(fd, QIODevice::WriteOnly))
- f.write(content);
- }
- close(fd);
- // Drag finished on source side with drop.
- QDragManager::self()->stopDrag();
- showDragPixmap(false);
- delete self;
- qDebug() << " *** DRAG OVER WITH DROP";
-}
-
-void QWaylandDragWrapper::reject(void *data, wl_drag *drag)
-{
- Q_UNUSED(drag);
- QWaylandDragWrapper *self = static_cast<QWaylandDragWrapper *>(data);
- self->mAcceptedType = QString();
- qDebug() << "reject";
- QDragManager::self()->global_accepted_action = Qt::IgnoreAction;
-}
-
-
-QWaylandDragOfferWrapper::QWaylandDragOfferWrapper(QWaylandDisplay *display,
- QMimeData *data,
- uint32_t id)
- : mDisplay(display), mData(data), mOffer(0), mFocusSurface(0),
- mAccepted(false)
-{
- mOffer = static_cast<struct wl_drag_offer *>(wl_display_bind(mDisplay->wl_display(), id,&wl_drag_offer_interface));
- wl_drag_offer_add_listener(mOffer, &dragOfferListener, this);
}
-QWaylandDragOfferWrapper::~QWaylandDragOfferWrapper()
+QWaylandDrag::~QWaylandDrag()
{
- QWaylandDrag *dragHandler = QWaylandDrag::instance(mDisplay);
- if (dragHandler->mCurrentOffer == this)
- dragHandler->mCurrentOffer = 0;
- wl_drag_offer_destroy(mOffer);
-}
-const wl_drag_offer_listener QWaylandDragOfferWrapper::dragOfferListener = {
- QWaylandDragOfferWrapper::offer,
- QWaylandDragOfferWrapper::pointerFocus,
- QWaylandDragOfferWrapper::motion,
- QWaylandDragOfferWrapper::drop
-};
-
-void QWaylandDragOfferWrapper::offer(void *data, struct wl_drag_offer *offer, const char *mimeType)
-{
- // Called for each type before pointerFocus.
- Q_UNUSED(offer);
- QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
- self->mOfferedTypes.setData(QString::fromLatin1(mimeType), QByteArray());
}
-void QWaylandDragOfferWrapper::pointerFocus(void *data, struct wl_drag_offer *offer, uint32_t time,
- wl_surface *surface,
- int32_t x, int32_t y,
- int32_t surfaceX, int32_t surfaceY)
+QMimeData * QWaylandDrag::platformDropData()
{
- qDebug() << "pointerFocus" << surface << x << y << surfaceX << surfaceY;
- QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
- QWaylandDrag *mgr = QWaylandDrag::instance(self->mDisplay);
-
- if (!surface) {
- if (self->mFocusSurface) {
- // This is a DragLeave.
- QWindow *window = static_cast<QWaylandWindow *>(
- wl_surface_get_user_data(self->mFocusSurface))->window();
- QWindowSystemInterface::handleDrag(window, 0, QPoint());
- if (self->mAccepted) {
- wl_drag_offer_reject(offer);
- self->mAccepted = false;
- }
- if (!mgr->mCurrentDrag) // no drag -> this is not the source side -> offer can be destroyed
- delete mgr->mCurrentOffer;
- } else {
- // Drag finished on source side without drop.
- QDragManager::self()->stopDrag();
- showDragPixmap(false);
- delete mgr->mCurrentDrag;
- qDebug() << " *** DRAG OVER WITHOUT DROP";
- }
- }
-
- self->mFocusSurface = surface;
-
- // This is a DragMove or DragEnter+DragMove.
- if (surface)
- self->sendEventToWindow(offer, time, surface, QPoint(surfaceX, surfaceY));
+ return m_display->dndSelectionHandler()->dragMime();
}
-void QWaylandDragOfferWrapper::motion(void *data, struct wl_drag_offer *offer, uint32_t time,
- int32_t x, int32_t y,
- int32_t surfaceX, int32_t surfaceY)
+void QWaylandDrag::startDrag(QDrag *drag)
{
- Q_UNUSED(x);
- Q_UNUSED(y);
- QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
- if (!self->mFocusSurface)
- return;
-// qDebug() << "motion" << self->mFocusSurface << x << y << surfaceX << surfaceY;
- self->sendEventToWindow(offer, time, self->mFocusSurface, QPoint(surfaceX, surfaceY));
+ m_display->dndSelectionHandler()->createAndSetDrag(drag);
}
-void QWaylandDragOfferWrapper::sendEventToWindow(struct wl_drag_offer *offer, uint32_t time,
- wl_surface *surface, const QPoint &pos)
+void QWaylandDrag::move(const QMouseEvent *me)
{
- QWindow *window = static_cast<QWaylandWindow *>(wl_surface_get_user_data(surface))->window();
- Qt::DropAction action = QWindowSystemInterface::handleDrag(window, &mOfferedTypes, pos);
- bool accepted = (action != Qt::IgnoreAction && !mOfferedTypes.formats().isEmpty());
- if (accepted != mAccepted) {
- mAccepted = accepted;
- if (mAccepted) {
- // What can we do, just accept the first type...
- QByteArray ba = mOfferedTypes.formats().first().toLatin1();
- qDebug() << "wl_drag_offer_accept" << ba;
- wl_drag_offer_accept(offer, time, ba.constData());
- } else {
- qDebug() << "wl_drag_offer_reject";
- wl_drag_offer_reject(offer);
- }
- }
- mLastEventPos = pos;
+ qFatal("This function should not be called");
}
-void QWaylandDragOfferWrapper::drop(void *data, struct wl_drag_offer *offer)
+bool QWaylandDrag::canDrop() const
{
- QWaylandDragOfferWrapper *self = static_cast<QWaylandDragOfferWrapper *>(data);
- if (!self->mAccepted) {
- wl_drag_offer_reject(offer);
- return;
- }
-
- QWaylandDrag *mgr = QWaylandDrag::instance(self->mDisplay);
- QMimeData *mimeData = QWaylandDrag::instance(self->mDisplay)->platformDropData();
- mimeData->clear();
- if (mgr->mCurrentDrag) { // means this offer is the client's own
- QMimeData *localData = mgr->mCurrentDrag->mimeData();
- foreach (const QString &format, localData->formats())
- mimeData->setData(format, localData->data(format));
- QWindow *window = static_cast<QWaylandWindow *>(
- wl_surface_get_user_data(self->mFocusSurface))->window();
- QWindowSystemInterface::handleDrop(window, mimeData, self->mLastEventPos);
- // Drag finished with drop (source == target).
- QDragManager::self()->stopDrag();
- showDragPixmap(false);
- delete mgr->mCurrentOffer;
- qDebug() << " *** DRAG OVER WITH DROP, SOURCE == TARGET";
- } else {
- // ### TODO
- // This is a bit broken: The QMimeData will only contain the data for
- // the first type. The Wayland protocol and QDropEvents/QMimeData do not
- // match perfectly at the moment.
- QString format = self->mOfferedTypes.formats().first();
- QByteArray mimeTypeBa = format.toLatin1();
- int pipefd[2];
- if (pipe(pipefd) == -1) {
- qWarning("QWaylandDragOfferWrapper: pipe() failed");
- return;
- }
- fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL, 0) | O_NONBLOCK);
- wl_drag_offer_receive(offer, pipefd[1]);
- mgr->mPipeData.clear();
- mgr->mMimeFormat = format;
- mgr->mPipeWriteEnd = pipefd[1];
- mgr->mPipeWatcher = new QSocketNotifier(pipefd[0], QSocketNotifier::Read);
- QObject::connect(mgr->mPipeWatcher, SIGNAL(activated(int)), mgr, SLOT(pipeReadable(int)));
- }
}
-
-void QWaylandDrag::pipeReadable(int fd)
+void QWaylandDrag::drop(const QMouseEvent *me)
{
- if (mPipeWriteEnd) {
- close(mPipeWriteEnd);
- mPipeWriteEnd = 0;
- }
- char buf[256];
- int n;
- while ((n = read(fd, &buf, sizeof buf)) > 0 || errno == EINTR)
- if (n > 0)
- mPipeData.append(buf, n);
- if (n == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
- return;
- delete mPipeWatcher;
- close(fd);
-
- QMimeData *mimeData = platformDropData();
- mimeData->setData(mMimeFormat, mPipeData);
- foreach (const QString &format, mimeData->formats())
- qDebug() << " got type" << format << "with data" << mimeData->data(format);
-
- QWindow *window = static_cast<QWaylandWindow *>(
- wl_surface_get_user_data(mCurrentOffer->mFocusSurface))->window();
- QWindowSystemInterface::handleDrop(window, mimeData, mCurrentOffer->mLastEventPos);
-
- // Drag finished on target side with drop.
- delete mCurrentOffer;
- qDebug() << " *** DRAG OVER ON TARGET WITH DROP";
}
-void QWaylandDrag::createDragOffer(uint32_t id)
+void QWaylandDrag::cancel()
{
- delete mCurrentOffer;
- mCurrentOffer = new QWaylandDragOfferWrapper(mDisplay, mDropData, id);
+ m_display->dndSelectionHandler()->cancelDrag();
}
-void QWaylandDrag::startDrag()
+Qt::DropAction QWaylandDrag::executedDropAction() const
{
- QDragManager *manager = QDragManager::self();
-
- // No need for the traditional desktop-oriented event handling in QDragManager.
- manager->unmanageEvents();
-
- delete mCurrentDrag;
- mCurrentDrag = new QWaylandDragWrapper(mDisplay, manager->dropData());
+ Qt::CopyAction;
}
diff --git a/src/plugins/platforms/wayland/qwaylanddnd.h b/src/plugins/platforms/wayland/qwaylanddnd.h
index ebafd960e..b5f922519 100644
--- a/src/plugins/platforms/wayland/qwaylanddnd.h
+++ b/src/plugins/platforms/wayland/qwaylanddnd.h
@@ -46,41 +46,24 @@
#include <QtCore/QMimeData>
#include "qwaylanddisplay.h"
-class QWaylandDragWrapper;
-class QWaylandDragOfferWrapper;
-class QSocketNotifier;
-
-class QWaylandDrag : public QObject, public QPlatformDrag
+class QWaylandDrag : public QPlatformDrag
{
- Q_OBJECT
-
public:
- static QWaylandDrag *instance(QWaylandDisplay *display);
+ QWaylandDrag(QWaylandDisplay *display);
~QWaylandDrag();
- void createDragOffer(uint32_t id);
QMimeData *platformDropData();
- void startDrag();
- void move(const QMouseEvent *) { }
- void drop(const QMouseEvent *) { }
- void cancel() { }
-private slots:
- void pipeReadable(int fd);
+ void startDrag(QDrag *drag);
+ void move(const QMouseEvent *me);
+ bool canDrop() const;
+ void drop(const QMouseEvent *me);
+ void cancel();
-private:
- QWaylandDrag(QWaylandDisplay *display);
+ virtual Qt::DropAction executedDropAction() const;
- QWaylandDisplay *mDisplay;
- QMimeData *mDropData;
- QWaylandDragWrapper *mCurrentDrag;
- QWaylandDragOfferWrapper *mCurrentOffer;
- int mPipeWriteEnd;
- QSocketNotifier *mPipeWatcher;
- QByteArray mPipeData;
- QString mMimeFormat;
- friend class QWaylandDragWrapper;
- friend class QWaylandDragOfferWrapper;
+private:
+ QWaylandDisplay *m_display;
};
#endif // QWAYLANDDND_H
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
index ccaabee1d..0e32b24b8 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
@@ -44,6 +44,7 @@
#include "qwaylandintegration.h"
#include "qwaylandwindow.h"
#include "qwaylandbuffer.h"
+#include "qwaylanddatadevicemanager.h"
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/QPlatformWindow>
@@ -52,6 +53,8 @@
#include <unistd.h>
#include <fcntl.h>
+#include <QtGui/QGuiApplication>
+
#ifndef QT_NO_WAYLAND_XKB
#include <X11/extensions/XKBcommon.h>
#include <X11/keysym.h>
@@ -61,6 +64,7 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display,
uint32_t id)
: mQDisplay(display)
, mDisplay(display->wl_display())
+ , mTransferDevice(0)
, mPointerFocus(NULL)
, mKeyboardFocus(NULL)
, mButtons(0)
@@ -83,6 +87,10 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display,
mXkb = xkb_compile_keymap_from_rules(&names);
#endif
+
+ if (mQDisplay->dndSelectionHandler()) {
+ mTransferDevice = mQDisplay->dndSelectionHandler()->getDataDevice(this);
+ }
}
void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
@@ -93,6 +101,17 @@ void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
mKeyboardFocus = 0;
}
+void QWaylandInputDevice::setTransferDevice(struct wl_data_device *device)
+{
+ mTransferDevice = device;
+}
+
+struct wl_data_device *QWaylandInputDevice::transferDevice() const
+{
+ Q_ASSERT(mTransferDevice);
+ return mTransferDevice;
+}
+
void QWaylandInputDevice::inputHandleMotion(void *data,
struct wl_input_device *input_device,
uint32_t time,
@@ -345,9 +364,11 @@ void QWaylandInputDevice::inputHandleKeyboardFocus(void *data,
if (surface) {
window = (QWaylandWindow *) wl_surface_get_user_data(surface);
inputDevice->mKeyboardFocus = window;
+ inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(inputDevice);
QWindowSystemInterface::handleWindowActivated(window->window());
} else {
inputDevice->mKeyboardFocus = NULL;
+ inputDevice->mQDisplay->setLastKeyboardFocusInputDevice(0);
QWindowSystemInterface::handleWindowActivated(0);
}
}
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h
index 05ebe0596..b0f178721 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.h
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h
@@ -65,10 +65,14 @@ public:
struct wl_input_device *wl_input_device() const { return mInputDevice; }
QWaylandWindow *pointerFocus() const { return mPointerFocus; }
+ void setTransferDevice(struct wl_data_device *device);
+ struct wl_data_device *transferDevice() const;
+
private:
QWaylandDisplay *mQDisplay;
struct wl_display *mDisplay;
struct wl_input_device *mInputDevice;
+ struct wl_data_device *mTransferDevice;
QWaylandWindow *mPointerFocus;
QWaylandWindow *mKeyboardFocus;
static const struct wl_input_device_listener inputDeviceListener;
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp
index 57baa5768..0a81ca1c4 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.cpp
+++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp
@@ -72,6 +72,8 @@ QWaylandIntegration::QWaylandIntegration()
{
QGuiApplicationPrivate::instance()->setEventDispatcher(mEventDispatcher);
mDisplay = new QWaylandDisplay();
+ mClipboard = new QWaylandClipboard(mDisplay);
+ mDrag = new QWaylandDrag(mDisplay);
foreach (QPlatformScreen *screen, mDisplay->screens())
screenAdded(screen);
@@ -137,12 +139,12 @@ QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
QPlatformClipboard *QWaylandIntegration::clipboard() const
{
- return QWaylandClipboard::instance(mDisplay);
+ return mClipboard;
}
QPlatformDrag *QWaylandIntegration::drag() const
{
- return QWaylandDrag::instance(mDisplay);
+ return mDrag;
}
QPlatformInputContext *QWaylandIntegration::inputContext() const
diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h
index b891cdc1f..23f778165 100644
--- a/src/plugins/platforms/wayland/qwaylandintegration.h
+++ b/src/plugins/platforms/wayland/qwaylandintegration.h
@@ -75,6 +75,8 @@ public:
private:
QPlatformFontDatabase *mFontDb;
QAbstractEventDispatcher *mEventDispatcher;
+ QPlatformClipboard *mClipboard;
+ QPlatformDrag *mDrag;
QWaylandDisplay *mDisplay;
QPlatformNativeInterface *mNativeInterface;
QPlatformInputContext *mInputContext;
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index 7bbcb01ab..3df4cb737 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -12,11 +12,6 @@ mac {
DEFINES += QT_NO_WAYLAND_XKB
}
-QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG)
-isEqual(QT_WAYLAND_GL_CONFIG, wayland_egl) {
- DEFINES += QT_NO_WAYLAND_XKB
-}
-
QT += core-private gui-private opengl-private platformsupport-private
SOURCES = main.cpp \
@@ -31,7 +26,9 @@ SOURCES = main.cpp \
qwaylandshmwindow.cpp \
qwaylandclipboard.cpp \
qwaylanddnd.cpp \
- qwaylandmime.cpp
+ qwaylanddataoffer.cpp \
+ qwaylanddatadevicemanager.cpp \
+ qwaylanddatasource.cpp
HEADERS = qwaylandintegration.h \
qwaylandnativeinterface.h \
@@ -44,7 +41,9 @@ HEADERS = qwaylandintegration.h \
qwaylandshmwindow.h \
qwaylandclipboard.h \
qwaylanddnd.h \
- qwaylandmime.h
+ qwaylanddataoffer.h \
+ qwaylanddatadevicemanager.h \
+ qwaylanddatasource.h
INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
LIBS += $$QMAKE_LIBS_WAYLAND
@@ -59,3 +58,4 @@ INSTALLS += target
include ($$PWD/gl_integration/gl_integration.pri)
include ($$PWD/windowmanager_integration/windowmanager_integration.pri)
+
diff --git a/src/qt-compositor/compositor_api/waylandcompositor.cpp b/src/qt-compositor/compositor_api/waylandcompositor.cpp
index acfe1f29c..a21a7eaf2 100644
--- a/src/qt-compositor/compositor_api/waylandcompositor.cpp
+++ b/src/qt-compositor/compositor_api/waylandcompositor.cpp
@@ -43,6 +43,8 @@
#include "wayland_wrapper/wlcompositor.h"
#include "wayland_wrapper/wlsurface.h"
#include <QtCore/QCoreApplication>
+#include <QtCore/QStringList>
+
#include <QDebug>
#ifdef QT_COMPOSITOR_DECLARATIVE
@@ -120,9 +122,9 @@ Wayland::Compositor * WaylandCompositor::handle() const
void WaylandCompositor::setRetainedSelectionEnabled(bool enable)
{
- Wayland::Selection *sel = Wayland::Selection::instance();
- sel->setRetainedSelection(enable);
- sel->setRetainedSelectionWatcher(retainedSelectionChanged, this);
+// Wayland::Selection *sel = Wayland::Selection::instance();
+// sel->setRetainedSelection(enable);
+// sel->setRetainedSelectionWatcher(retainedSelectionChanged, this);
}
void WaylandCompositor::retainedSelectionChanged(QMimeData *mimeData, void *param)
@@ -137,8 +139,8 @@ void WaylandCompositor::retainedSelectionReceived(QMimeData *)
void WaylandCompositor::overrideSelection(QMimeData *data)
{
- Wayland::Selection *sel = Wayland::Selection::instance();
- sel->overrideSelection(data);
+// Wayland::Selection *sel = Wayland::Selection::instance();
+// sel->overrideSelection(data);
}
const char *WaylandCompositor::socketName() const
diff --git a/src/qt-compositor/wayland_wrapper/wayland_wrapper.pri b/src/qt-compositor/wayland_wrapper/wayland_wrapper.pri
index 623bc95fd..478b39982 100644
--- a/src/qt-compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/qt-compositor/wayland_wrapper/wayland_wrapper.pri
@@ -4,10 +4,12 @@ HEADERS += \
$$PWD/wloutput.h \
$$PWD/wlshmbuffer.h \
$$PWD/wlsurface.h \
- $$PWD/wlselection.h \
- $$PWD/wldrag.h \
- ../../src/qt-compositor/wayland_wrapper/wlshell.h \
- ../../src/qt-compositor/wayland_wrapper/wlinputdevice.h
+ $$PWD/wlshell.h \
+ $$PWD/wlinputdevice.h \
+ $$PWD/wldatadevicemanager.h \
+ $$PWD/wldatadevice.h \
+ $$PWD/wldataoffer.h \
+ $$PWD/wldatasource.h
SOURCES += \
$$PWD/wlcompositor.cpp \
@@ -15,11 +17,10 @@ SOURCES += \
$$PWD/wloutput.cpp \
$$PWD/wlshmbuffer.cpp \
$$PWD/wlsurface.cpp \
- $$PWD/wlselection.cpp \
- $$PWD/wldrag.cpp \
- ../../src/qt-compositor/wayland_wrapper/wlshell.cpp \
- ../../src/qt-compositor/wayland_wrapper/wlinputdevice.cpp
-
-
-
+ $$PWD/wlshell.cpp \
+ $$PWD/wlinputdevice.cpp \
+ $$PWD/wldatadevicemanager.cpp \
+ $$PWD/wldatadevice.cpp \
+ $$PWD/wldataoffer.cpp \
+ $$PWD/wldatasource.cpp
diff --git a/src/qt-compositor/wayland_wrapper/wlcompositor.cpp b/src/qt-compositor/wayland_wrapper/wlcompositor.cpp
index fe29be6c2..493c9e435 100644
--- a/src/qt-compositor/wayland_wrapper/wlcompositor.cpp
+++ b/src/qt-compositor/wayland_wrapper/wlcompositor.cpp
@@ -44,10 +44,10 @@
#include "wldisplay.h"
#include "wlshmbuffer.h"
#include "wlsurface.h"
-#include "wlselection.h"
-#include "wldrag.h"
#include "wlinputdevice.h"
#include "waylandcompositor.h"
+#include "wldatadevicemanager.h"
+#include "wldatadevice.h"
#include <QWindow>
#include <QSocketNotifier>
@@ -88,19 +88,21 @@ void destroy_surface(struct wl_resource *resource)
delete surface;
}
-typedef Object<struct wl_compositor> wl_compositor_object;
-
void compositor_create_surface(struct wl_client *client,
struct wl_resource *resource, uint32_t id)
{
- wl_compositor_object *second_super = static_cast<wl_compositor_object *>(resource->data);
- static_cast<Compositor *>(second_super)->createSurface(client,id);
+ static_cast<Compositor *>(resource->data)->createSurface(client,id);
}
const static struct wl_compositor_interface compositor_interface = {
compositor_create_surface
};
+void Compositor::bind_func(struct wl_client *client, void *data,
+ uint32_t version, uint32_t id)
+{
+ wl_client_add_object(client,&wl_compositor_interface, &compositor_interface, id,data);
+}
Compositor *Compositor::instance()
@@ -110,6 +112,7 @@ Compositor *Compositor::instance()
Compositor::Compositor(WaylandCompositor *qt_compositor)
: m_display(new Display)
+ , m_shell(this)
, m_shm(m_display)
, m_current_frame(0)
, m_last_queued_buf(-1)
@@ -121,7 +124,6 @@ Compositor::Compositor(WaylandCompositor *qt_compositor)
#if defined (QT_COMPOSITOR_WAYLAND_GL)
, m_graphics_hw_integration(0)
#endif
- , m_dragActive(false)
{
compositor = this;
qDebug() << "Compositor instance is" << this;
@@ -137,16 +139,15 @@ Compositor::Compositor(WaylandCompositor *qt_compositor)
SIGNAL(windowPropertyChanged(wl_client*,wl_surface*,QString,QVariant)),
SLOT(windowPropertyChanged(wl_client*,wl_surface*,QString,QVariant)));
- if (wl_compositor_init(base(), &compositor_interface, m_display->handle())) {
- fprintf(stderr, "Fatal: Error initializing compositor\n");
- exit(EXIT_FAILURE);
- }
+ wl_display_add_global(m_display->handle(),&wl_compositor_interface,this,Compositor::bind_func);
m_input = new InputDevice(this);
+ m_data_device_manager = new DataDeviceManager(this);
wl_display_add_global(m_display->handle(),&wl_output_interface,m_output.base(),Output::output_bind_func);
+
wl_display_add_global(m_display->handle(), &wl_shell_interface, m_shell.base(), Shell::bind_func);
- wl_display_add_global(m_display->handle(),&wl_input_device_interface,m_input,InputDevice::bind_func);
+
if (wl_display_add_socket(m_display->handle(), qt_compositor->socketName())) {
fprintf(stderr, "Fatal: Failed to open server socket\n");
@@ -159,10 +160,15 @@ Compositor::Compositor(WaylandCompositor *qt_compositor)
QSocketNotifier *sockNot = new QSocketNotifier(fd, QSocketNotifier::Read, this);
connect(sockNot, SIGNAL(activated(int)), this, SLOT(processWaylandEvents()));
+
+ //initialize distancefieldglyphcache here
}
Compositor::~Compositor()
{
+ delete m_input;
+ delete m_data_device_manager;
+
delete m_display;
}
@@ -282,18 +288,13 @@ void Compositor::destroyClientForSurface(Surface *surface)
void Compositor::setInputFocus(Surface *surface)
{
- wl_surface *base = surface ? surface->base() : 0;
-
- ulong time = currentTimeMsecs();
-
- m_keyFocusSurface = surface;
- m_pointerFocusSurface = surface;
- wl_input_device_set_keyboard_focus(m_input->base(), base, time);
- wl_input_device_set_pointer_focus(m_input->base(), base, time, 0, 0, 0, 0);
+ setKeyFocus(surface);
+ setPointerFocus(surface);
}
void Compositor::setKeyFocus(Surface *surface)
{
+ m_input->sendSelectionFocus(surface);
m_keyFocusSurface = surface;
wl_input_device_set_keyboard_focus(m_input->base(), surface ? surface->base() : 0, currentTimeMsecs());
}
@@ -400,18 +401,18 @@ QList<Wayland::Surface *> Compositor::surfacesForClient(wl_client *client)
bool Compositor::isDragging() const
{
- return m_dragActive;
+ return false;
}
void Compositor::sendDragMoveEvent(const QPoint &global, const QPoint &local,
Surface *surface)
{
- Drag::instance()->dragMove(global, local, surface);
+// Drag::instance()->dragMove(global, local, surface);
}
void Compositor::sendDragEndEvent()
{
- Drag::instance()->dragEnd();
+// Drag::instance()->dragEnd();
}
} // namespace Wayland
diff --git a/src/qt-compositor/wayland_wrapper/wlcompositor.h b/src/qt-compositor/wayland_wrapper/wlcompositor.h
index 4f83c2e6f..1eec5091f 100644
--- a/src/qt-compositor/wayland_wrapper/wlcompositor.h
+++ b/src/qt-compositor/wayland_wrapper/wlcompositor.h
@@ -58,8 +58,9 @@ namespace Wayland {
class Surface;
class InputDevice;
+class DataDeviceManager;
-class Compositor : public QObject, public Object<struct wl_compositor>
+class Compositor : public QObject
{
Q_OBJECT
@@ -135,6 +136,9 @@ private:
/* shm/*/
ShmHandler m_shm;
+
+ DataDeviceManager *m_data_device_manager;
+
QList<Surface *> m_surfaces;
QSet<Surface *> m_dirty_surfaces;
@@ -156,8 +160,8 @@ private:
#endif
WindowManagerServerIntegration *m_windowManagerWaylandProtocol;
- bool m_dragActive;
- friend class Drag;
+ static void bind_func(struct wl_client *client, void *data,
+ uint32_t version, uint32_t id);
};
}
diff --git a/src/qt-compositor/wayland_wrapper/wldatadevice.cpp b/src/qt-compositor/wayland_wrapper/wldatadevice.cpp
new file mode 100644
index 000000000..91a461634
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldatadevice.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**
+** Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include "wldatadevice.h"
+
+#include "wldatasource.h"
+#include "wldataoffer.h"
+#include "wldatadevicemanager.h"
+
+#include <stdlib.h>
+
+#include <QDebug>
+
+namespace Wayland {
+
+void DataDevice::start_drag(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *source,
+ struct wl_resource *surface,
+ uint32_t time)
+{
+ DataDevice *data_device = static_cast<DataDevice *>(resource->data);
+ DataSource *data_source = static_cast<DataSource *>(source->data);
+
+
+}
+
+void DataDevice::attach(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t time,
+ struct wl_resource *buffer,
+ int32_t x,
+ int32_t y)
+{
+
+}
+
+void DataDevice::set_selection(struct wl_client *client,
+ struct wl_resource *data_device_resource,
+ struct wl_resource *source,
+ uint32_t time)
+{
+ DataDevice *data_device = static_cast<DataDevice *>(data_device_resource->data);
+ DataSource *data_source = static_cast<DataSource *>(source->data);
+
+ data_device->m_data_device_manager->setCurrentSelectionSource(data_source);
+
+}
+
+const struct wl_data_device_interface DataDevice::data_device_interface = {
+ DataDevice::start_drag,
+ DataDevice::attach,
+ DataDevice::set_selection
+};
+
+void DataDevice::destroy_data_device_resource(struct wl_resource *resource)
+{
+ DataDevice *data_device = static_cast<DataDevice *>(resource->data);
+ delete data_device;
+ free(resource);
+}
+
+DataDevice::DataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id)
+ : m_data_device_manager(data_device_manager)
+ , m_sent_selection_time(0)
+{
+
+ static int i = 0;
+ qDebug() << "data device" << ++i;
+ m_data_device_resource =
+ wl_client_add_object(client,&wl_data_device_interface,&data_device_interface,id, this);
+
+}
+
+void DataDevice::sendSelectionFocus()
+{
+ //do for all clipboards
+ DataSource *source = m_data_device_manager->currentSelectionSource();
+ if (!source){
+ return;
+ }
+ if (source->time() > m_sent_selection_time) { //this makes sure we don't resend
+ if (source->client() != m_data_device_resource->client) { //don't send selection to the client that owns the selection
+ DataOffer *data_offer = m_data_device_manager->currentSelectionSource()->dataOffer();
+ wl_resource *client_resource =
+ data_offer->addDataDeviceResource(m_data_device_resource);
+ qDebug() << "sending data_offer for source" << source;
+ wl_resource_post_event(m_data_device_resource,WL_DATA_DEVICE_SELECTION,client_resource);
+ m_sent_selection_time = source->time();
+ }
+ }
+}
+
+struct wl_resource *DataDevice::dataDeviceResource() const
+{
+ return m_data_device_resource;
+}
+
+}
diff --git a/src/qt-compositor/wayland_wrapper/wldatadevice.h b/src/qt-compositor/wayland_wrapper/wldatadevice.h
new file mode 100644
index 000000000..ca49bf160
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldatadevice.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**
+** Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#ifndef WLDATADEVICE_H
+#define WLDATADEVICE_H
+
+#include "wldatadevicemanager.h"
+
+namespace Wayland {
+
+class DataSource;
+class DataDeviceManager;
+
+class DataDevice
+{
+public:
+ DataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id);
+
+ void createAndSetSelectionSource(struct wl_client *client, uint32_t id, const char *name, uint32_t time);
+ void sendSelectionFocus();
+
+ struct wl_resource *dataDeviceResource() const;
+
+ struct wl_display *display() const { return m_data_device_manager->display(); }
+private:
+ DataDeviceManager *m_data_device_manager;
+ uint32_t m_sent_selection_time;
+ struct wl_resource *m_data_device_resource;
+
+ static const struct wl_data_device_interface data_device_interface;
+ static void start_drag(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *source,
+ struct wl_resource *surface,
+ uint32_t time);
+ static void attach(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t time,
+ struct wl_resource *buffer,
+ int32_t x,
+ int32_t y);
+ static void set_selection(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *source,
+ uint32_t time);
+
+ static void destroy_data_device_resource(struct wl_resource *resource);
+};
+
+}
+
+#endif // WLDATADEVICE_H
diff --git a/src/qt-compositor/wayland_wrapper/wldatadevicemanager.cpp b/src/qt-compositor/wayland_wrapper/wldatadevicemanager.cpp
new file mode 100644
index 000000000..834ef9545
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldatadevicemanager.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**
+** Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include "wldatadevicemanager.h"
+
+#include "wldatadevice.h"
+#include "wldatasource.h"
+#include "wlinputdevice.h"
+#include "wlcompositor.h"
+#include "wldataoffer.h"
+
+#include <QtCore/QDebug>
+
+namespace Wayland {
+
+DataDeviceManager::DataDeviceManager(Compositor *compositor)
+ : m_compositor(compositor)
+ , m_current_selection_source(0)
+{
+ wl_display_add_global(compositor->wl_display(), &wl_data_device_manager_interface, base(), DataDeviceManager::bind_func_drag);
+}
+void DataDeviceManager::setCurrentSelectionSource(DataSource *source)
+{
+ if (m_current_selection_source) {
+ if (m_current_selection_source->time() >= source->time()) {
+ qDebug() << "Trying to set older selection";
+ return;
+ }
+ }
+ m_current_selection_source = source;
+}
+
+DataSource *DataDeviceManager::currentSelectionSource()
+{
+ return m_current_selection_source;
+}
+
+struct wl_display *DataDeviceManager::display() const
+{
+ return m_compositor->wl_display();
+}
+
+void DataDeviceManager::bind_func_drag(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+ wl_client_add_object(client,&wl_data_device_manager_interface,&drag_interface,id,data);
+}
+
+void DataDeviceManager::bind_func_data(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+}
+
+void DataDeviceManager::get_data_device(struct wl_client *client,
+ struct wl_resource *data_device_manager_resource,
+ uint32_t id,
+ struct wl_resource *input_device_resource)
+{
+ DataDeviceManager *data_device_manager = static_cast<DataDeviceManager *>(data_device_manager_resource->data);
+ InputDevice *input_device = reinterpret_cast<InputDevice *>(input_device_resource->data);
+ input_device->clientRequestedDataDevice(data_device_manager,client,id);
+}
+
+void DataDeviceManager::create_data_source(struct wl_client *client,
+ struct wl_resource *data_device_manager_resource,
+ uint32_t id)
+{
+ Q_UNUSED(data_device_manager_resource);
+ new DataSource(client,id, Compositor::currentTimeMsecs());
+}
+
+struct wl_data_device_manager_interface DataDeviceManager::drag_interface = {
+ DataDeviceManager::create_data_source,
+ DataDeviceManager::get_data_device
+};
+
+} //namespace
diff --git a/src/qt-compositor/wayland_wrapper/wldrag.h b/src/qt-compositor/wayland_wrapper/wldatadevicemanager.h
index b0f8b48e2..87398c4cf 100644
--- a/src/qt-compositor/wayland_wrapper/wldrag.h
+++ b/src/qt-compositor/wayland_wrapper/wldatadevicemanager.h
@@ -38,58 +38,53 @@
**
****************************************************************************/
-#ifndef WLDRAG_H
-#define WLDRAG_H
+#ifndef WLDATADEVICEMANAGER_H
+#define WLDATADEVICEMANAGER_H
-#include <QtCore/QObject>
-#include <QtCore/QStringList>
-#include <QtCore/QMimeData>
-#include <wayland-server.h>
+#include "waylandobject.h"
+
+#include "wlcompositor.h"
+
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtGui/QClipboard>
-QT_BEGIN_NAMESPACE
-class QSocketNotifier;
-QT_END_NAMESPACE
namespace Wayland {
-class Surface;
+class Compositor;
-class Drag : public QObject
-{
- Q_OBJECT
+class DataDevice;
+class DataSource;
+class DataDeviceManager : public Object<struct wl_object>
+{
public:
- static Drag *instance();
- Drag();
- void create(struct wl_client *client, uint32_t id);
- void dragMove(const QPoint &global, const QPoint &local, Surface *surface);
- void dragEnd();
+ DataDeviceManager(Compositor *compositor);
-private:
- static void destroyDrag(struct wl_resource *resource);
-
- static void dragOffer(struct wl_client *client, struct wl_resource *drag, const char *type);
- static void dragActivate(struct wl_client *client,
- struct wl_resource *drag,
- struct wl_resource *surface,
- struct wl_resource *device, uint32_t time);
- static void dragDestroy(struct wl_client *client, struct wl_resource *drag);
- static const struct wl_drag_interface dragInterface;
+ void setCurrentSelectionSource(DataSource *source);
+ DataSource *currentSelectionSource();
- static void dragOfferAccept(struct wl_client *client,
- struct wl_resource *offer, uint32_t time, const char *type);
- static void dragOfferReceive(struct wl_client *client,
- struct wl_resource *offer, int fd);
- static void dragOfferReject(struct wl_client *client, struct wl_resource *offer);
- static const struct wl_drag_offer_interface dragOfferInterface;
+ struct wl_display *display() const;
+private:
+ Compositor *m_compositor;
+ QList<DataDevice *> m_data_device_list;
- void setPointerFocus(wl_surface *surface, const QPoint &global, const QPoint &local);
- void done(bool sending);
+ DataSource *m_current_selection_source;
- QStringList m_offerList;
- wl_drag *m_drag;
+ static void bind_func_drag(struct wl_client *client, void *data,
+ uint32_t version, uint32_t id);
+ static void bind_func_data(struct wl_client *client, void *data,
+ uint32_t version, uint32_t id);
+ static void get_data_device(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id,
+ struct wl_resource *input_device);
+ static void create_data_source(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id);
+ static struct wl_data_device_manager_interface drag_interface;
};
}
-
-#endif // WLDRAG_H
+#endif // WLDATADEVICEMANAGER_H
diff --git a/src/qt-compositor/wayland_wrapper/wldataoffer.cpp b/src/qt-compositor/wayland_wrapper/wldataoffer.cpp
new file mode 100644
index 000000000..882337352
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldataoffer.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**
+** Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include "wldataoffer.h"
+
+#include "wldatadevice.h"
+
+#include <wayland-server.h>
+
+#include <sys/time.h>
+
+#include <QtCore/QDebug>
+
+namespace Wayland
+{
+
+DataOffer::DataOffer(DataSource *data_source)
+ : m_data_source(data_source)
+{
+
+}
+
+DataOffer::~DataOffer()
+{
+}
+
+struct wl_resource *DataOffer::addDataDeviceResource(struct wl_resource *data_device_resource)
+{
+ for (int i = 0; i < m_clients_data_resource.size(); i++) {
+ if (m_clients_data_resource.at(i)->client == data_device_resource->client) {
+ qDebug() << "This should not happen, the client tries to add twice to a data offer";
+ return 0;
+ }
+ }
+ struct wl_resource *new_object =
+ wl_client_new_object(data_device_resource->client,&wl_data_offer_interface,&data_interface,this);
+ wl_resource_post_event(data_device_resource,WL_DATA_DEVICE_DATA_OFFER,new_object);
+
+ m_clients_data_resource.append(new_object);
+ QList<QByteArray> offer_list = m_data_source->offerList();
+ for (int i = 0; i < offer_list.size(); i++) {
+ wl_resource_post_event(new_object, WL_DATA_OFFER_OFFER, offer_list.at(i).constData());
+ }
+ return new_object;
+}
+
+void DataOffer::removeClient(struct wl_client *client)
+{
+ for (int i = 0; i < m_clients_data_resource.size(); i++) {
+ struct wl_resource *resource = m_clients_data_resource.at(i);
+ if (resource->client == client) {
+ wl_resource_destroy(resource,Compositor::currentTimeMsecs());
+ m_clients_data_resource.removeAt(i);
+ break;
+ }
+ }
+}
+
+const struct wl_data_offer_interface DataOffer::data_interface = {
+ DataOffer::accept,
+ DataOffer::receive,
+ DataOffer::destroy
+};
+
+void DataOffer::accept(wl_client *client, wl_resource *resource, uint32_t time, const char *type)
+{
+
+}
+
+void DataOffer::receive(wl_client *client, wl_resource *resource, const char *mime_type, int32_t fd)
+{
+ Q_UNUSED(client);
+
+ DataOffer *offer = static_cast<DataOffer *>(resource->data);
+ offer->m_data_source->postSendEvent(mime_type,fd);
+ close(fd);
+}
+
+void DataOffer::destroy(wl_client *client, wl_resource *resource)
+{
+ qDebug() << "dataOFFER DESTROY!";
+ DataOffer *data_offer = static_cast<DataOffer *>(resource->data);
+ data_offer->removeClient(client);
+
+ if (data_offer->m_clients_data_resource.size() == 0) {
+ delete data_offer;
+ }
+}
+
+
+}
diff --git a/src/qt-compositor/wayland_wrapper/wldataoffer.h b/src/qt-compositor/wayland_wrapper/wldataoffer.h
new file mode 100644
index 000000000..5db80f62b
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldataoffer.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**
+** Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#ifndef WLDATAOFFER_H
+#define WLDATAOFFER_H
+
+#include "wldatasource.h"
+
+namespace Wayland
+{
+
+class DataOffer
+{
+public:
+ DataOffer(DataSource *data_source);
+ ~DataOffer();
+
+ struct wl_resource *addDataDeviceResource(struct wl_resource *client_resource);
+ void removeClient(struct wl_client *client);
+private:
+ DataSource *m_data_source;
+
+ QList<struct wl_resource *> m_clients_data_resource;
+
+ static void accept(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t time,
+ const char *type);
+ static void receive(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *mime_type,
+ int32_t fd);
+ static void destroy(struct wl_client *client,
+ struct wl_resource *resource);
+
+ static const struct wl_data_offer_interface data_interface;
+
+};
+
+}
+
+#endif // WLDATAOFFER_H
diff --git a/src/qt-compositor/wayland_wrapper/wldatasource.cpp b/src/qt-compositor/wayland_wrapper/wldatasource.cpp
new file mode 100644
index 000000000..57e4b17ce
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldatasource.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**
+** Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#include "wldatasource.h"
+
+#include "wldataoffer.h"
+
+#include <wayland-server.h>
+
+#include "wlcompositor.h"
+
+#include <QtCore/QDebug>
+
+namespace Wayland {
+
+
+DataSource::DataSource(struct wl_client *client, uint32_t id, uint32_t time)
+ : m_time(time)
+{
+ m_data_source_resource = wl_client_add_object(client, &wl_data_source_interface, &DataSource::data_source_interface,id,this);
+ m_data_offer = new DataOffer(this);
+}
+
+DataSource::~DataSource()
+{
+ qDebug() << "destorying source";
+ wl_resource_destroy(m_data_source_resource,Compositor::currentTimeMsecs());
+}
+
+uint32_t DataSource::time() const
+{
+ return m_time;
+}
+
+QList<QByteArray> DataSource::offerList() const
+{
+ return m_offers;
+}
+
+struct wl_data_source_interface DataSource::data_source_interface = {
+ DataSource::offer,
+ DataSource::destroy
+};
+
+void DataSource::offer(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *type)
+{
+ Q_UNUSED(client);
+ qDebug() << "received offer" << type;
+ static_cast<DataSource *>(resource->data)->m_offers.append(type);
+}
+
+void DataSource::destroy(struct wl_client *client,
+ struct wl_resource *resource)
+{
+ DataSource *self = static_cast<DataSource *>(resource->data);
+ delete self;
+}
+
+DataOffer * DataSource::dataOffer() const
+{
+ return m_data_offer;
+}
+
+void DataSource::postSendEvent(const QByteArray mimeType, int fd)
+{
+ if (m_data_source_resource) {
+ wl_resource_post_event(m_data_source_resource,WL_DATA_SOURCE_SEND,mimeType.constData(),fd);
+ }
+}
+
+struct wl_client *DataSource::client() const
+{
+ if (m_data_source_resource)
+ return m_data_source_resource->client;
+ return 0;
+}
+
+}
diff --git a/src/qt-compositor/wayland_wrapper/wldatasource.h b/src/qt-compositor/wayland_wrapper/wldatasource.h
new file mode 100644
index 000000000..a848fc474
--- /dev/null
+++ b/src/qt-compositor/wayland_wrapper/wldatasource.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** This file is part of QtCompositor**
+**
+** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+**
+** Contact: Nokia Corporation qt-info@nokia.com
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**
+** Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
+** names of its contributors may be used to endorse or promote products
+** derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+****************************************************************************/
+
+#ifndef WLDATASOURCE_H
+#define WLDATASOURCE_H
+
+#include <wayland-server-protocol.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+
+namespace Wayland {
+
+class DataOffer;
+
+class DataSource
+{
+public:
+ DataSource(struct wl_client *client, uint32_t id, uint32_t time);
+ ~DataSource();
+ uint32_t time() const;
+ QList<QByteArray> offerList() const;
+
+ DataOffer *dataOffer() const;
+
+ void postSendEvent(const QByteArray mimeType,int fd);
+ struct wl_client *client() const;
+
+private:
+ uint32_t m_time;
+ QList<QByteArray> m_offers;
+ struct wl_resource *m_data_source_resource;
+
+ DataOffer *m_data_offer;
+
+ static struct wl_data_source_interface data_source_interface;
+ static void offer(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *type);
+ static void destroy(struct wl_client *client,
+ struct wl_resource *resource);
+
+
+};
+
+}
+
+#endif // WLDATASOURCE_H
diff --git a/src/qt-compositor/wayland_wrapper/wldrag.cpp b/src/qt-compositor/wayland_wrapper/wldrag.cpp
deleted file mode 100644
index 02eac6e95..000000000
--- a/src/qt-compositor/wayland_wrapper/wldrag.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/****************************************************************************
-**
-** This file is part of QtCompositor**
-**
-** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-**
-** Contact: Nokia Corporation qt-info@nokia.com
-**
-** You may use this file under the terms of the BSD license as follows:
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-**
-** Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-**
-** Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-**
-** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#include "wldrag.h"
-#include "wlcompositor.h"
-#include "wlsurface.h"
-#include <wayland-util.h>
-#include <string.h>
-#include <unistd.h>
-#include <QDebug>
-
-namespace Wayland {
-
-void Drag::dragOfferAccept(struct wl_client *client,
- struct wl_resource *resource_offer, uint32_t time, const char *type)
-{
- Q_UNUSED(time);
- Drag *self = Drag::instance();
- struct wl_drag_offer *offer = reinterpret_cast<struct wl_drag_offer *>(resource_offer);
- struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
-
- qDebug() << "dragOfferAccept" << client << offer << type;
- drag->target = client;
- QString wantedType = QString::fromLatin1(type);
- if (!self->m_offerList.contains(wantedType)) {
- qWarning("dragOfferAccept: Client accepted type '%s' that has not been offered",
- qPrintable(type));
- type = 0;
- }
- wl_resource_post_event(&drag->resource,
- WL_DRAG_TARGET, type);
-}
-
-void Drag::dragOfferReceive(struct wl_client *client,
- struct wl_resource *resource_offer, int fd)
-{
- Q_UNUSED(client);
- struct wl_drag_offer *offer = reinterpret_cast<struct wl_drag_offer *>(resource_offer);
-
- qDebug() << "dragOfferReceive" << client << offer << fd;
- struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
- wl_resource_post_event(&drag->resource,
- WL_DRAG_FINISH, fd);
- close(fd);
-}
-
-void Drag::dragOfferReject(struct wl_client *client, struct wl_resource *resource_offer)
-{
- Q_UNUSED(client);
- struct wl_drag_offer *offer = reinterpret_cast<struct wl_drag_offer *>(resource_offer);
- qDebug() << "dragOfferReject" << client << offer;
-
- struct wl_drag *drag = container_of(offer, struct wl_drag, drag_offer);
- if (drag->target == client)
- drag->target = 0;
- wl_resource_post_event(&drag->resource,
- WL_DRAG_REJECT);
-}
-
-const struct wl_drag_offer_interface Drag::dragOfferInterface = {
- Drag::dragOfferAccept,
- Drag::dragOfferReceive,
- Drag::dragOfferReject
-};
-
-void Drag::dragOffer(struct wl_client *client, struct wl_resource *drag, const char *type)
-{
- qDebug() << "dragOffer" << client << drag << type;
- Q_UNUSED(client);
- Q_UNUSED(drag);
- instance()->m_offerList.append(QString::fromLatin1(type));
-}
-
-void Drag::dragActivate(struct wl_client *client,
- struct wl_resource *drag_resource,
- struct wl_resource *surface_resource,
- struct wl_resource *device_resource, uint32_t time)
-{
- struct wl_drag *drag = reinterpret_cast<struct wl_drag *>(drag_resource);
- struct wl_surface *surface = reinterpret_cast<struct wl_surface *>(surface_resource);
- struct wl_input_device *device = reinterpret_cast<struct wl_input_device *>(device_resource);
-
- qDebug() << "dragActivate" << client << drag << surface;
- Q_UNUSED(client);
- Q_UNUSED(device);
- Q_UNUSED(time);
- Drag *self = Drag::instance();
- drag->source = surface;
- drag->drag_offer.resource.object.interface = &wl_drag_offer_interface;
- drag->drag_offer.resource.object.implementation = (void (**)()) &dragOfferInterface;
- wl_display *dpy = Compositor::instance()->wl_display();
-// wl_display_add_object(dpy, &drag->drag_offer.resource.object);
-// wl_display_add_global(dpy, &drag->drag_offer.resource.object, 0);
- Surface *focus = Compositor::instance()->pointerFocus();
- QPoint pos;
- if (focus)
- pos = focus->lastMousePos();
- // ### Sending local as global, which is wrong, but oh well.
- self->setPointerFocus(surface, pos, pos);
-}
-
-void Drag::setPointerFocus(wl_surface *surface, const QPoint &global, const QPoint &local)
-{
- if (!m_drag)
- return;
-
- if (m_drag->drag_focus == surface)
- return;
-
- uint timestamp = Compositor::currentTimeMsecs();
- if (m_drag->drag_focus
- && (!surface || m_drag->drag_focus->resource.client != surface->resource.client)) {
- qDebug() << "WL_DRAG_OFFER_POINTER_FOCUS with null";
- wl_resource_post_event(&m_drag->drag_offer.resource,
- WL_DRAG_OFFER_POINTER_FOCUS,
- timestamp, 0, 0, 0, 0, 0);
- }
- if (surface
- && (!m_drag->drag_focus || m_drag->drag_focus->resource.client != surface->resource.client)) {
-// wl_client_post_global(surface->client,
-// &m_drag->drag_offer.object);
- foreach (const QString &format, m_offerList) {
- QByteArray mimeTypeBa = format.toLatin1();
- qDebug() << "WL_DRAG_OFFER_OFFER" << mimeTypeBa;
- wl_resource_post_event(&m_drag->drag_offer.resource,
- WL_DRAG_OFFER_OFFER, mimeTypeBa.constData());
- }
- }
-
- if (surface) {
- qDebug() << "WL_DRAG_OFFER_POINTER_FOCUS" << surface << global << local;
- wl_resource_post_event(&m_drag->drag_offer.resource,
- WL_DRAG_OFFER_POINTER_FOCUS,
- timestamp, surface,
- global.x(), global.y(), local.x(), local.y());
- Compositor::instance()->m_dragActive = true;
- }
-
- m_drag->drag_focus = surface;
- m_drag->target = 0;
-}
-
-void Drag::dragDestroy(struct wl_client *client, struct wl_resource *drag_resource)
-{
- Q_UNUSED(client);
- qDebug() << "dragDestroy";
- struct wl_drag *drag = reinterpret_cast<struct wl_drag *>(drag_resource);
- wl_resource_destroy(&drag->resource, Compositor::currentTimeMsecs());
-}
-
-const struct wl_drag_interface Drag::dragInterface = {
- Drag::dragOffer,
- Drag::dragActivate,
- Drag::dragDestroy
-};
-
-void Drag::destroyDrag(struct wl_resource *resource)
-{
- struct wl_drag *drag = container_of(resource, struct wl_drag, resource);
- wl_display *dpy = Compositor::instance()->wl_display();
-// wl_display_remove_global(dpy, &drag->drag_offer.object);
- delete drag;
-}
-
-void Drag::create(struct wl_client *client, uint32_t id)
-{
- Q_UNUSED(client);
- m_offerList.clear();
- wl_drag *drag = new wl_drag;
- memset(drag, 0, sizeof *drag);
- drag->resource.object.id = id;
- drag->resource.object.interface = &wl_drag_interface;
- drag->resource.object.implementation = (void (**)()) &dragInterface;
- drag->resource.destroy = destroyDrag;
- wl_client_add_resource(client, &drag->resource);
- m_drag = drag;
-}
-
-void Drag::done(bool sending)
-{
- qDebug() << "drag done";
- Compositor::instance()->m_dragActive = false;
- if (!sending) {
- setPointerFocus(0, QPoint(), QPoint());
- // ### hack: Send a pointerFocus with null surface to the source too, this is
- // mandatory even if the previous pointerFocus went to the same client, otherwise
- // Qt will not know the drag is over without a drop.
- wl_resource_post_event(&m_drag->drag_offer.resource,
- WL_DRAG_OFFER_POINTER_FOCUS,
- Compositor::instance()->currentTimeMsecs(),
- 0, 0, 0, 0, 0);
- }
- m_drag = 0;
-}
-
-void Drag::dragMove(const QPoint &global, const QPoint &local, Surface *surface)
-{
- if (!m_drag)
- return;
-// qDebug() << "dragMove" << global << local << surface;
- if (surface) {
- setPointerFocus(surface->base(), global, local);
- uint timestamp = Compositor::currentTimeMsecs();
- wl_resource_post_event(&m_drag->drag_offer.resource,
- WL_DRAG_OFFER_MOTION,
- timestamp,
- global.x(), global.y(), local.x(), local.y());
- } else {
- setPointerFocus(0, global, local);
- }
-}
-
-void Drag::dragEnd()
-{
- qDebug() << "dragEnd";
- if (!m_drag)
- return;
- if (m_drag->target) {
- qDebug() << "WL_DRAG_OFFER_DROP" << m_drag->target;
- wl_resource_post_event(&m_drag->drag_offer.resource,
- WL_DRAG_OFFER_DROP);
- done(true);
- } else {
- done(false);
- }
-}
-
-Q_GLOBAL_STATIC(Drag, globalInstance)
-
-Drag *Drag::instance()
-{
- return globalInstance();
-}
-
-Drag::Drag()
- : m_drag(0)
-{
-}
-
-}
diff --git a/src/qt-compositor/wayland_wrapper/wlinputdevice.cpp b/src/qt-compositor/wayland_wrapper/wlinputdevice.cpp
index 540bbe0d5..c0feecafa 100644
--- a/src/qt-compositor/wayland_wrapper/wlinputdevice.cpp
+++ b/src/qt-compositor/wayland_wrapper/wlinputdevice.cpp
@@ -42,6 +42,8 @@
#include "wlshmbuffer.h"
#include "wlcompositor.h"
+#include "wldatadevice.h"
+#include "wlsurface.h"
#include <QtCore/QDebug>
@@ -53,7 +55,44 @@ static ShmBuffer *currentCursor;
InputDevice::InputDevice(Compositor *compositor)
{
- wl_input_device_init(base(), compositor->base());
+ wl_input_device_init(base());
+ wl_display_add_global(compositor->wl_display(),&wl_input_device_interface,this,InputDevice::bind_func);
+}
+
+void InputDevice::clientRequestedDataDevice(DataDeviceManager *data_device_manager , struct wl_client *client, uint32_t id)
+{
+ for (int i = 0; i < m_data_devices.size(); i++) {
+ struct wl_resource *data_device_resource =
+ m_data_devices.at(i)->dataDeviceResource();
+ if (data_device_resource->client == client) {
+ qDebug() << "Client created data device, but allready has one; removing the old one!";
+ m_data_devices.removeAt(i);
+ delete data_device_resource;
+ break;
+ }
+ }
+ DataDevice *dataDevice = new DataDevice(data_device_manager,client,id);
+ m_data_devices.append(dataDevice);
+}
+
+void InputDevice::sendSelectionFocus(Surface *surface)
+{
+ if (!surface)
+ return;
+ DataDevice *device = dataDevice(surface->base()->resource.client);
+ if (device) {
+ device->sendSelectionFocus();
+ }
+}
+
+DataDevice *InputDevice::dataDevice(struct wl_client *client) const
+{
+ for (int i = 0; i < m_data_devices.size();i++) {
+ if (m_data_devices.at(i)->dataDeviceResource()->client == client) {
+ return m_data_devices.at(i);
+ }
+ }
+ return 0;
}
void InputDevice::bind_func(struct wl_client *client, void *data,
@@ -63,7 +102,6 @@ void InputDevice::bind_func(struct wl_client *client, void *data,
struct wl_resource *resource = wl_client_add_object(client,&wl_input_device_interface ,&input_device_interface,id,data);
struct wl_input_device *input_device = static_cast<struct wl_input_device *>(data);
- qDebug() << "InputDevice::bind_func" << resource;
resource->destroy = destroy_resource;
wl_list_insert(&input_device->resource_list,&resource->link);
}
@@ -80,10 +118,10 @@ void InputDevice::input_device_attach(struct wl_client *client,
struct wl_buffer *buffer = reinterpret_cast<struct wl_buffer *>(buffer_resource);
qDebug() << "Client input device attach" << client << buffer << x << y;
- Compositor *compositor = wayland_cast<Compositor *>(device_base->compositor);
+// Compositor *compositor = wayland_cast<Compositor *>(device_base->compositor);
ShmBuffer *shmBuffer = static_cast<ShmBuffer *>(buffer->user_data);
if (shmBuffer) {
- compositor->qtCompositor()->changeCursor(shmBuffer->image(), x, y);
+// compositor->qtCompositor()->changeCursor(shmBuffer->image(), x, y);
currentCursor = shmBuffer;
}
}
diff --git a/src/qt-compositor/wayland_wrapper/wlinputdevice.h b/src/qt-compositor/wayland_wrapper/wlinputdevice.h
index c12c1ff8b..7ea56a918 100644
--- a/src/qt-compositor/wayland_wrapper/wlinputdevice.h
+++ b/src/qt-compositor/wayland_wrapper/wlinputdevice.h
@@ -42,15 +42,25 @@
#define WLINPUTDEVICE_H
#include "waylandobject.h"
+#include <QtCore/QList>
namespace Wayland {
class Compositor;
+class DataDevice;
+class Surface;
+class DataDeviceManager;
+
class InputDevice : public Object<struct wl_input_device>
{
public:
InputDevice(Compositor *compositor);
+ void clientRequestedDataDevice(DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id);
+ DataDevice *dataDevice(struct wl_client *client) const;
+
+ void sendSelectionFocus(Surface *surface);
+
static void bind_func(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
static void input_device_attach(struct wl_client *client,
@@ -59,6 +69,10 @@ public:
struct wl_resource *buffer, int32_t x, int32_t y);
const static struct wl_input_device_interface input_device_interface;
static void destroy_resource(struct wl_resource *resource);
+
+private:
+ QList<DataDevice *>m_data_devices;
+
};
}
diff --git a/src/qt-compositor/wayland_wrapper/wlselection.cpp b/src/qt-compositor/wayland_wrapper/wlselection.cpp
deleted file mode 100644
index b1865b035..000000000
--- a/src/qt-compositor/wayland_wrapper/wlselection.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-/****************************************************************************
-**
-** This file is part of QtCompositor**
-**
-** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-**
-** Contact: Nokia Corporation qt-info@nokia.com
-**
-** You may use this file under the terms of the BSD license as follows:
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-**
-** Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-**
-** Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-**
-** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#include "wlselection.h"
-#include "wlcompositor.h"
-#include "wlinputdevice.h"
-
-#include <wayland-util.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <QtCore/QFile>
-#include <QtCore/QSocketNotifier>
-#include <QtCore/private/qcore_unix_p.h>
-
-#include <QtCore/QDebug>
-
-namespace Wayland {
-
-void Selection::send(struct wl_client *client,
- struct wl_resource *offer,
- const char *mime_type, int fd)
-{
- Q_UNUSED(client);
- Selection *self = instance();
- if (self->m_retainedSelection) {
- QByteArray data = self->m_retainedData.data(QString::fromLatin1(mime_type));
- if (!data.isEmpty()) {
- QFile f;
- if (f.open(fd, QIODevice::WriteOnly))
- f.write(data);
- }
- } else {
- struct wl_selection_offer *actual_offer = reinterpret_cast<struct wl_selection_offer *>(offer);
- struct wl_selection *selection = container_of(actual_offer, struct wl_selection, selection_offer);
- wl_resource_post_event(&selection->resource,
- WL_SELECTION_SEND, mime_type, fd);
- }
- close(fd);
-}
-
-const struct wl_selection_offer_interface Selection::selectionOfferInterface = {
- Selection::send
-};
-
-void Selection::selOffer(struct wl_client *client,
- struct wl_resource *selection,
- const char *type)
-{
- Q_UNUSED(client);
- Q_UNUSED(selection);
- instance()->m_offerList.append(QString::fromLatin1(type));
-}
-
-void Selection::selActivate(struct wl_client *client,
- struct wl_resource *selection_resource,
- struct wl_resource *device,
- uint32_t time)
-{
- Q_UNUSED(client);
- Q_UNUSED(device);
- Q_UNUSED(time);
- Selection *self = Selection::instance();
- struct wl_selection *selection = reinterpret_cast<struct wl_selection *>(selection_resource);
- selection->selection_offer.resource.object.interface = &wl_selection_offer_interface;
- selection->selection_offer.resource.object.implementation = (void (**)()) &selectionOfferInterface;
- wl_display *dpy = Compositor::instance()->wl_display();
- wl_display_add_global(dpy,&wl_selection_offer_interface,selection,0);
-
- QList<struct wl_client *> clients = Compositor::instance()->clients();
-
- if (self->m_currentSelection) {
- if (!clients.contains(self->m_currentSelection->client))
- self->m_currentSelection = 0;
- else
- wl_resource_post_event(&self->m_currentSelection->resource,
- WL_SELECTION_CANCELLED);
- }
- self->m_currentSelection = selection;
-
- if (self->m_currentOffer) {
- foreach (struct wl_resource *clientResource, self->m_selectionClientResources) {
- wl_resource_post_event(clientResource,
- WL_SELECTION_OFFER_KEYBOARD_FOCUS, 0);
- }
- self->m_selectionClientResources.clear();
- }
- self->m_currentOffer = &selection->selection_offer;
- foreach (struct wl_client *client, clients) {
- qDebug() << "sending to clients";
- selection->selection_offer.resource.client = client;
- foreach (const QString &mimeType, self->m_offerList) {
- QByteArray mimeTypeBa = mimeType.toLatin1();
- wl_resource_post_event(&selection->selection_offer.resource,
- WL_SELECTION_OFFER_OFFER, mimeTypeBa.constData());
- }
-
- wl_resource_post_event(&selection->selection_offer.resource,
- WL_SELECTION_OFFER_KEYBOARD_FOCUS, selection->input_device);
- }
-
- if (self->m_retainedSelectionEnabled && client) {
- self->m_retainedData.clear();
- self->m_retainedReadIndex = 0;
- self->retain();
- }
-}
-
-void Selection::retain()
-{
- finishReadFromClient();
- if (!m_currentSelection->client) // do not retain data created via overrideSelection()
- return;
- if (m_retainedReadIndex >= m_offerList.count()) {
- if (m_watchFunc)
- m_watchFunc(&m_retainedData, m_watchFuncParam);
- return;
- }
- QString mimeType = m_offerList.at(m_retainedReadIndex);
- m_retainedReadBuf.clear();
- QByteArray mimeTypeBa = mimeType.toLatin1();
- int fd[2];
- if (pipe(fd) == -1) {
- qWarning("Clipboard: Failed to create pipe");
- return;
- }
- fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL, 0) | O_NONBLOCK);
- wl_resource_post_event(&m_currentSelection->resource,
- WL_SELECTION_SEND, mimeTypeBa.constData(), fd[1]);
- close(fd[1]);
- m_retainedReadNotifier = new QSocketNotifier(fd[0], QSocketNotifier::Read, this);
- connect(m_retainedReadNotifier, SIGNAL(activated(int)), SLOT(readFromClient(int)));
-}
-
-void Selection::finishReadFromClient(bool exhausted)
-{
- if (m_retainedReadNotifier) {
- if (exhausted) {
- int fd = m_retainedReadNotifier->socket();
- delete m_retainedReadNotifier;
- close(fd);
- } else {
- // Do not close the handle or destroy the read notifier here
- // or else clients may SIGPIPE.
- m_obsoleteRetainedReadNotifiers.append(m_retainedReadNotifier);
- }
- m_retainedReadNotifier = 0;
- }
-}
-
-void Selection::readFromClient(int fd)
-{
- static char buf[4096];
- int obsCount = m_obsoleteRetainedReadNotifiers.count();
- for (int i = 0; i < obsCount; ++i) {
- QSocketNotifier *sn = m_obsoleteRetainedReadNotifiers.at(i);
- if (sn->socket() == fd) {
- // Read and drop the data, stopping to read and closing the handle
- // is not yet safe because that could kill the client with SIGPIPE
- // when it still tries to write.
- int n;
- do {
- n = QT_READ(fd, buf, sizeof buf);
- } while (n > 0);
- if (n != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) {
- m_obsoleteRetainedReadNotifiers.removeAt(i);
- delete sn;
- close(fd);
- }
- return;
- }
- }
- int n = QT_READ(fd, buf, sizeof buf);
- if (n <= 0) {
- if (n != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) {
- finishReadFromClient(true);
- QString mimeType = m_offerList.at(m_retainedReadIndex);
- m_retainedData.setData(mimeType, m_retainedReadBuf);
- ++m_retainedReadIndex;
- retain();
- }
- } else {
- m_retainedReadBuf.append(buf, n);
- }
-}
-
-void Selection::selDestroy(struct wl_client *client, struct wl_resource *selection)
-{
- wl_resource_destroy(selection, Compositor::currentTimeMsecs());
-}
-
-const struct wl_selection_interface Selection::selectionInterface = {
- Selection::selOffer,
- Selection::selActivate,
- Selection::selDestroy
-};
-
-void Selection::destroySelection(struct wl_resource *resource)
-{
- struct wl_selection *selection = container_of(resource, struct wl_selection, resource);
- Selection *self = Selection::instance();
- wl_display *dpy = Compositor::instance()->wl_display();
- if (self->m_currentSelection == selection)
- self->m_currentSelection = 0;
- if (self->m_currentOffer == &selection->selection_offer) {
- self->m_currentOffer = 0;
- if (self->m_retainedSelectionEnabled) {
- if (self->m_retainedSelection) {
-// wl_display_remove_global(dpy, &self->m_retainedSelection->selection_offer.object);
- delete self->m_retainedSelection;
- }
- self->m_retainedSelection = selection;
- return;
- }
- self->m_offerList.clear();
- foreach (struct wl_resource *resource, self->m_selectionClientResources)
- wl_resource_post_event(resource,
- WL_SELECTION_OFFER_KEYBOARD_FOCUS, 0);
- }
-// wl_display_remove_global(dpy, &selection->selection_offer.object);
- delete selection;
-}
-
-void Selection::create(struct wl_client *client, uint32_t id)
-{
- if (m_retainedSelection) {
- if (m_retainedSelection == m_currentSelection) { // this can happen only when overrideSelection() was called
- if (m_currentOffer == &m_currentSelection->selection_offer)
- m_currentOffer = 0;
- m_currentSelection = 0;
- }
-// wl_display_remove_global(Compositor::instance()->wl_display(),
-// &m_retainedSelection->selection_offer.object);
- delete m_retainedSelection;
- m_retainedSelection = 0;
- }
- m_offerList.clear();
- struct wl_selection *selection = new struct wl_selection;
- memset(selection, 0, sizeof *selection);
- selection->resource.object.id = id;
- selection->resource.object.interface = &wl_selection_interface;
- selection->resource.object.implementation = (void (**)()) &selectionInterface;
- selection->resource.destroy = destroySelection;
- selection->client = client;
- selection->input_device = Compositor::instance()->inputDevice()->base();
- wl_client_add_resource(client, &selection->resource);
-}
-
-void Selection::setRetainedSelection(bool enable)
-{
- m_retainedSelectionEnabled = enable;
-}
-
-void Selection::setRetainedSelectionWatcher(Watcher func, void *param)
-{
- m_watchFunc = func;
- m_watchFuncParam = param;
-}
-
-void Selection::onClientAdded(wl_client *client)
-{
- struct wl_selection *selection = m_currentSelection;
- struct wl_selection_offer *offer = m_currentOffer;
- if (m_retainedSelection) {
- selection = m_retainedSelection;
- offer = &m_retainedSelection->selection_offer;
- }
- if (selection && offer) {
- foreach (const QString &mimeType, m_offerList) {
- QByteArray mimeTypeBa = mimeType.toLatin1();
- wl_resource_post_event(&offer->resource,
- WL_SELECTION_OFFER_OFFER, mimeTypeBa.constData());
- }
- wl_resource_post_event(&offer->resource,
- WL_SELECTION_OFFER_KEYBOARD_FOCUS, selection->input_device);
- }
-}
-
-void Selection::clearSelection()
-{
- wl_display *dpy = Compositor::instance()->wl_display();
- QList<struct wl_client *> clients = Compositor::instance()->clients();
-
- if (m_currentSelection && clients.contains(m_currentSelection->client))
- wl_client_post_event(m_currentSelection->client,
- &m_currentSelection->resource.object,
- WL_SELECTION_CANCELLED);
-
- if (m_currentOffer)
- foreach (struct wl_client *client, clients)
- wl_client_post_event(client, &m_currentOffer->object,
- WL_SELECTION_OFFER_KEYBOARD_FOCUS, 0);
-
- m_currentSelection = 0;
- m_currentOffer = 0;
- m_offerList.clear();
-
- if (m_retainedSelection) {
- wl_display_remove_global(dpy, &m_retainedSelection->selection_offer.object);
- delete m_retainedSelection;
- m_retainedSelection = 0;
- }
-}
-
-void Selection::overrideSelection(QMimeData *data)
-{
- clearSelection();
-
- m_retainedSelection = new wl_selection;
- memset(m_retainedSelection, 0, sizeof *m_retainedSelection);
- m_retainedSelection->client = 0; // indicates there is a special selection active
- m_retainedSelection->input_device = Compositor::instance()->inputDevice(); // needed for keyboard_focus
-
- m_offerList.append(data->formats());
- m_retainedData.clear();
- foreach (const QString &format, m_offerList)
- m_retainedData.setData(format, data->data(format));
-
- selActivate(0, m_retainedSelection, 0, 0);
-}
-
-Q_GLOBAL_STATIC(Selection, globalInstance)
-
-Selection *Selection::instance()
-{
- return globalInstance();
-}
-
-Selection::Selection()
- : m_currentSelection(0), m_currentOffer(0),
- m_retainedReadNotifier(0), m_retainedSelection(0),
- m_retainedSelectionEnabled(false),
- m_watchFunc(0), m_watchFuncParam(0)
-{
- connect(Compositor::instance(), SIGNAL(clientAdded(wl_client*)), SLOT(onClientAdded(wl_client*)));
-}
-
-Selection::~Selection()
-{
- finishReadFromClient();
-}
-
-}
diff --git a/src/qt-compositor/wayland_wrapper/wlselection.h b/src/qt-compositor/wayland_wrapper/wlselection.h
deleted file mode 100644
index 51e55f479..000000000
--- a/src/qt-compositor/wayland_wrapper/wlselection.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** This file is part of QtCompositor**
-**
-** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-**
-** Contact: Nokia Corporation qt-info@nokia.com
-**
-** You may use this file under the terms of the BSD license as follows:
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-**
-** Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-**
-** Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-**
-** Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
-** names of its contributors may be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#ifndef WLSELECTION_H
-#define WLSELECTION_H
-
-#include <QtCore/QObject>
-#include <QtCore/QStringList>
-#include <QtCore/QMimeData>
-#include <wayland-server.h>
-
-QT_BEGIN_NAMESPACE
-class QSocketNotifier;
-QT_END_NAMESPACE
-
-namespace Wayland {
-
-class Selection : public QObject
-{
- Q_OBJECT
-
-public:
- static Selection *instance();
- Selection();
- ~Selection();
- void create(struct wl_client *client, uint32_t id);
- void setRetainedSelection(bool enable);
- typedef void (*Watcher)(QMimeData*, void*);
- void setRetainedSelectionWatcher(Watcher func, void *param);
- void clearSelection();
- void overrideSelection(QMimeData *data);
-
-private slots:
- void onClientAdded(wl_client *client);
- void readFromClient(int fd);
-
-private:
- static void destroySelection(struct wl_resource *resource);
- static void selOffer(struct wl_client *client,
- struct wl_resource *selection,
- const char *type);
- static void selActivate(struct wl_client *client,
- struct wl_resource *selection,
- struct wl_resource *device,
- uint32_t time);
- static void selDestroy(struct wl_client *client, struct wl_resource *selection);
- static const struct wl_selection_interface selectionInterface;
- static void send(struct wl_client *client,
- struct wl_resource *offer,
- const char *mime_type, int fd);
- static const struct wl_selection_offer_interface selectionOfferInterface;
-
- void retain();
- void finishReadFromClient(bool exhausted = false);
-
- QStringList m_offerList;
- struct wl_selection *m_currentSelection;
- struct wl_selection_offer *m_currentOffer;
- QMimeData m_retainedData;
- QSocketNotifier *m_retainedReadNotifier;
- QList<QSocketNotifier *> m_obsoleteRetainedReadNotifiers;
- int m_retainedReadIndex;
- QByteArray m_retainedReadBuf;
- struct wl_selection *m_retainedSelection;
- struct wl_global *m_retainedSelectionGlobal;
- bool m_retainedSelectionEnabled;
- Watcher m_watchFunc;
- void *m_watchFuncParam;
- QList<struct wl_resource *> m_selectionClientResources;
-};
-
-}
-
-#endif // WLSELECTION_H
diff --git a/src/qt-compositor/wayland_wrapper/wlshell.cpp b/src/qt-compositor/wayland_wrapper/wlshell.cpp
index 1b6470b88..e6ab73762 100644
--- a/src/qt-compositor/wayland_wrapper/wlshell.cpp
+++ b/src/qt-compositor/wayland_wrapper/wlshell.cpp
@@ -42,12 +42,14 @@
#include "wlcompositor.h"
+#include "wlcompositor.h"
+
#include <QtCore/qglobal.h>
#include <QtCore/QDebug>
namespace Wayland {
-Shell::Shell()
+Shell::Shell(Compositor *compositor)
{
}
@@ -88,24 +90,6 @@ void Shell::shell_resize(struct wl_client *client,
qDebug() << "shellResize";
}
-void Shell::shell_drag(struct wl_client *client,
- struct wl_resource *shell,
- uint32_t id)
-{
- Q_UNUSED(shell);
- qDebug() << "shellDrag";
- Drag::instance()->create(client, id);
-}
-
-void Shell::shell_selection(struct wl_client *client,
- struct wl_resource *shell,
- uint32_t id)
-{
- qDebug() << "shellSelection";
- Q_UNUSED(shell);
- Selection::instance()->create(client, id);
-}
-
void Shell::set_toplevel(struct wl_client *client,
struct wl_resource *wl_shell,
struct wl_resource *surface)
@@ -143,8 +127,6 @@ void Shell::set_fullscreen(struct wl_client *client,
const struct wl_shell_interface Shell::shell_interface = {
shell_move,
shell_resize,
- shell_drag,
- shell_selection,
set_toplevel,
set_transient,
set_fullscreen
diff --git a/src/qt-compositor/wayland_wrapper/wlshell.h b/src/qt-compositor/wayland_wrapper/wlshell.h
index bb2109fd4..a3e604976 100644
--- a/src/qt-compositor/wayland_wrapper/wlshell.h
+++ b/src/qt-compositor/wayland_wrapper/wlshell.h
@@ -45,10 +45,12 @@
namespace Wayland {
+class Compositor;
+
class Shell : public Object<struct wl_object>
{
public:
- Shell();
+ Shell(Compositor *compositor);
static void bind_func(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
@@ -63,12 +65,6 @@ public:
struct wl_resource *input_device,
uint32_t time,
uint32_t edges);
- static void shell_drag(struct wl_client *client,
- struct wl_resource *shell,
- uint32_t id);
- static void shell_selection(struct wl_client *client,
- struct wl_resource *shell,
- uint32_t id);
static void set_toplevel(struct wl_client *client,
struct wl_resource *shell,
struct wl_resource *surface);
diff --git a/src/qt-compositor/wayland_wrapper/wlsurface.cpp b/src/qt-compositor/wayland_wrapper/wlsurface.cpp
index a4f42744e..7b41e8e78 100644
--- a/src/qt-compositor/wayland_wrapper/wlsurface.cpp
+++ b/src/qt-compositor/wayland_wrapper/wlsurface.cpp
@@ -46,8 +46,6 @@
#include "wlshmbuffer.h"
#include "wlinputdevice.h"
-#include "waylandlist.h"
-
#include <QtCore/QDebug>
#include <wayland-server.h>
@@ -113,7 +111,7 @@ public:
bool emitMap = !surfaceBuffer;
if (surfaceBuffer && ! textureCreatedForBuffer && surfaceBuffer != directRenderBuffer) {
qWarning() << "### WaylandSurface::attach() releasing undisplayed buffer ###";
- wl_client_post_event(client,&surfaceBuffer->resource.object,WL_BUFFER_RELEASE);
+ wl_resource_post_event(&surfaceBuffer->resource, WL_BUFFER_RELEASE);
}
surfaceBuffer = buffer;
surfaceType = WaylandSurface::Invalid;
@@ -157,7 +155,7 @@ private:
void Surface::surface_destroy(struct wl_client *client, struct wl_resource *surface_resource)
{
Surface *surface = reinterpret_cast<Surface *>(surface_resource);
- delete surface;
+ wl_resource_destroy(surface_resource,Compositor::currentTimeMsecs());
}
void Surface::surface_attach(struct wl_client *client, struct wl_resource *surface,
@@ -190,17 +188,11 @@ void Surface::surface_frame(struct wl_client *client,
wl_client_add_resource(client,surface->d_func()->frame_callback);
}
-void Surface::surface_resource_destory(wl_resource *resource)
-{
- qDebug() << "destorying surface";
-}
-
Surface::Surface(struct wl_client *client, Compositor *compositor)
: d_ptr(new SurfacePrivate(client,compositor))
{
base()->resource.client = client;
d_ptr->qtSurface = new WaylandSurface(this);
- base()->resource.destroy = Surface::surface_resource_destory;
}
Surface::~Surface()
diff --git a/src/qt-compositor/wayland_wrapper/wlsurface.h b/src/qt-compositor/wayland_wrapper/wlsurface.h
index fbcd81f24..4d037a26e 100644
--- a/src/qt-compositor/wayland_wrapper/wlsurface.h
+++ b/src/qt-compositor/wayland_wrapper/wlsurface.h
@@ -130,8 +130,6 @@ private:
static void surface_frame(struct wl_client *client, struct wl_resource *resource,
uint32_t callback);
- static void surface_resource_destory(struct wl_resource *resource);
-
};
}
diff --git a/src/qt-compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp b/src/qt-compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp
index 35d8ef593..fef23bb0d 100644
--- a/src/qt-compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp
+++ b/src/qt-compositor/windowmanagerprotocol/waylandwindowmanagerintegration.cpp
@@ -143,14 +143,14 @@ void WindowManagerServerIntegration::authenticateWithToken(wl_client *client, co
void WindowManagerServerIntegration::setVisibilityOnScreen(wl_client *client, bool visible)
{
- wl_client_post_event(client, m_windowManagerObject->base(),
- WL_WINDOWMANAGER_CLIENT_ONSCREEN_VISIBILITY, visible ? 1 : 0);
+// wl_client_post_event(client, m_windowManagerObject->base(),
+// WL_WINDOWMANAGER_CLIENT_ONSCREEN_VISIBILITY, visible ? 1 : 0);
}
void WindowManagerServerIntegration::setScreenOrientation(wl_client *client, wl_object *output, Qt::ScreenOrientation orientation)
{
- wl_client_post_event(client, m_windowManagerObject->base(),
- WL_WINDOWMANAGER_SET_SCREEN_ROTATION, output, qint32(orientation));
+// wl_client_post_event(client, m_windowManagerObject->base(),
+// WL_WINDOWMANAGER_SET_SCREEN_ROTATION, output, qint32(orientation));
}
// client -> server