diff options
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 |