summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>2012-01-17 15:32:32 +0200
committerJørgen Lind <jorgen.lind@nokia.com>2012-01-17 17:30:52 +0100
commitd458c31998f5e4fcf85cf31e4b9033fd18f77052 (patch)
tree112f8830e3b87a36012c7b4dd638680b64bf0ac7 /src
parentc4d4ca361744c689a6dd9b2436931fdcb5aa6df8 (diff)
downloadqtwayland-d458c31998f5e4fcf85cf31e4b9033fd18f77052.tar.gz
Implement selection offers from compositor to clients.
It is a hack but works beautifully. It allows the compositor to participate in copy-paste which becomes mandatory when there is UI running in the compositor process. Change-Id: I1993d8705a26159eff0c9947244b66e954b9f460 Sanity-Review: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/compositor/wayland_wrapper/wayland_wrapper.pri8
-rw-r--r--src/compositor/wayland_wrapper/wlcompositor.cpp3
-rw-r--r--src/compositor/wayland_wrapper/wldatadevice.cpp4
-rw-r--r--src/compositor/wayland_wrapper/wldatadevicemanager.cpp74
-rw-r--r--src/compositor/wayland_wrapper/wldatadevicemanager.h18
-rw-r--r--src/plugins/platforms/wayland/qwaylanddataoffer.cpp43
-rw-r--r--src/plugins/platforms/wayland/qwaylanddataoffer.h6
-rw-r--r--src/plugins/platforms/wayland/qwaylanddatasource.cpp2
-rw-r--r--src/plugins/platforms/wayland/wayland.pro9
-rw-r--r--src/shared/qwaylandmimehelper.cpp83
-rw-r--r--src/shared/qwaylandmimehelper.h55
11 files changed, 248 insertions, 57 deletions
diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri
index 4c1f6ee1..843f3d6d 100644
--- a/src/compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri
@@ -20,7 +20,8 @@ HEADERS += \
$$PWD/wlextendedsurface.h \
$$PWD/wlextendedoutput.h \
$$PWD/wlsubsurface.h \
- $$PWD/wltouch.h
+ $$PWD/wltouch.h \
+ $$PWD/../../shared/qwaylandmimehelper.h
SOURCES += \
$$PWD/wlcompositor.cpp \
@@ -37,5 +38,8 @@ SOURCES += \
$$PWD/wlextendedsurface.cpp \
$$PWD/wlextendedoutput.cpp \
$$PWD/wlsubsurface.cpp \
- $$PWD/wltouch.cpp
+ $$PWD/wltouch.cpp \
+ $$PWD/../../shared/qwaylandmimehelper.cpp
+
+INCLUDEPATH += $$PWD/../../shared
diff --git a/src/compositor/wayland_wrapper/wlcompositor.cpp b/src/compositor/wayland_wrapper/wlcompositor.cpp
index 3c453d0a..23e22525 100644
--- a/src/compositor/wayland_wrapper/wlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/wlcompositor.cpp
@@ -402,8 +402,7 @@ void Compositor::feedRetainedSelectionData(QMimeData *data)
void Compositor::overrideSelection(QMimeData *data)
{
- Q_UNUSED(data);
- // ### TODO implement
+ m_data_device_manager->overrideSelection(*data);
}
bool Compositor::isDragging() const
diff --git a/src/compositor/wayland_wrapper/wldatadevice.cpp b/src/compositor/wayland_wrapper/wldatadevice.cpp
index f4b2f2b4..bdabf29a 100644
--- a/src/compositor/wayland_wrapper/wldatadevice.cpp
+++ b/src/compositor/wayland_wrapper/wldatadevice.cpp
@@ -103,7 +103,9 @@ DataDevice::DataDevice(DataDeviceManager *data_device_manager, struct wl_client
void DataDevice::sendSelectionFocus()
{
- //do for all clipboards
+ if (m_data_device_manager->offerFromCompositorToClient(m_data_device_resource))
+ return;
+
DataSource *source = m_data_device_manager->currentSelectionSource();
if (!source) {
return;
diff --git a/src/compositor/wayland_wrapper/wldatadevicemanager.cpp b/src/compositor/wayland_wrapper/wldatadevicemanager.cpp
index ba8510bc..d3e3fb78 100644
--- a/src/compositor/wayland_wrapper/wldatadevicemanager.cpp
+++ b/src/compositor/wayland_wrapper/wldatadevicemanager.cpp
@@ -45,11 +45,14 @@
#include "wlinputdevice.h"
#include "wlcompositor.h"
#include "wldataoffer.h"
+#include "wlsurface.h"
+#include "qwaylandmimehelper.h"
#include <QtCore/QDebug>
#include <QtCore/QSocketNotifier>
#include <fcntl.h>
#include <QtCore/private/qcore_unix_p.h>
+#include <QtCore/QFile>
namespace Wayland {
@@ -57,6 +60,7 @@ DataDeviceManager::DataDeviceManager(Compositor *compositor)
: m_compositor(compositor)
, m_current_selection_source(0)
, m_retainedReadNotifier(0)
+ , m_compositorOwnsSelection(false)
{
wl_display_add_global(compositor->wl_display(), &wl_data_device_manager_interface, this, DataDeviceManager::bind_func_drag);
}
@@ -69,6 +73,8 @@ void DataDeviceManager::setCurrentSelectionSource(DataSource *source)
return;
}
+ m_compositorOwnsSelection = false;
+
finishReadFromClient();
m_current_selection_source = source;
@@ -210,4 +216,72 @@ struct wl_data_device_manager_interface DataDeviceManager::drag_interface = {
DataDeviceManager::get_data_device
};
+void DataDeviceManager::overrideSelection(const QMimeData &mimeData)
+{
+ QStringList formats = mimeData.formats();
+ if (formats.isEmpty())
+ return;
+
+ m_retainedData.clear();
+ foreach (const QString &format, formats)
+ m_retainedData.setData(format, mimeData.data(format));
+
+ m_compositor->feedRetainedSelectionData(&m_retainedData);
+
+ m_compositorOwnsSelection = true;
+
+ InputDevice *dev = m_compositor->defaultInputDevice();
+ Surface *focusSurface = dev->keyboardFocus();
+ if (focusSurface)
+ offerFromCompositorToClient(
+ dev->dataDevice(focusSurface->base()->resource.client)->dataDeviceResource());
+}
+
+bool DataDeviceManager::offerFromCompositorToClient(wl_resource *clientDataDeviceResource)
+{
+ if (!m_compositorOwnsSelection)
+ return false;
+
+ wl_client *client = clientDataDeviceResource->client;
+ qDebug("compositor offers %d types to %p", m_retainedData.formats().count(), client);
+
+ struct wl_resource *selectionOffer =
+ wl_client_new_object(client, &wl_data_offer_interface, &compositor_offer_interface, this);
+ wl_resource_post_event(clientDataDeviceResource, WL_DATA_DEVICE_DATA_OFFER, selectionOffer);
+ foreach (const QString &format, m_retainedData.formats()) {
+ QByteArray ba = format.toLatin1();
+ wl_resource_post_event(selectionOffer, WL_DATA_OFFER_OFFER, ba.constData());
+ }
+ wl_resource_post_event(clientDataDeviceResource, WL_DATA_DEVICE_SELECTION, selectionOffer);
+
+ return true;
+}
+
+void DataDeviceManager::comp_accept(wl_client *, wl_resource *, uint32_t, const char *)
+{
+}
+
+void DataDeviceManager::comp_receive(wl_client *client, wl_resource *resource, const char *mime_type, int32_t fd)
+{
+ DataDeviceManager *self = static_cast<DataDeviceManager *>(resource->data);
+ qDebug("client %p wants data for type %s from compositor", client, mime_type);
+ QByteArray content = QWaylandMimeHelper::getByteArray(&self->m_retainedData, QString::fromLatin1(mime_type));
+ if (!content.isEmpty()) {
+ QFile f;
+ if (f.open(fd, QIODevice::WriteOnly))
+ f.write(content);
+ }
+ close(fd);
+}
+
+void DataDeviceManager::comp_destroy(wl_client *, wl_resource *)
+{
+}
+
+const struct wl_data_offer_interface DataDeviceManager::compositor_offer_interface = {
+ DataDeviceManager::comp_accept,
+ DataDeviceManager::comp_receive,
+ DataDeviceManager::comp_destroy
+};
+
} //namespace
diff --git a/src/compositor/wayland_wrapper/wldatadevicemanager.h b/src/compositor/wayland_wrapper/wldatadevicemanager.h
index af26cb0e..75844d20 100644
--- a/src/compositor/wayland_wrapper/wldatadevicemanager.h
+++ b/src/compositor/wayland_wrapper/wldatadevicemanager.h
@@ -71,6 +71,9 @@ public:
void sourceDestroyed(DataSource *source);
+ void overrideSelection(const QMimeData &mimeData);
+ bool offerFromCompositorToClient(wl_resource *clientDataDeviceResource);
+
private slots:
void readFromClient(int fd);
@@ -102,6 +105,21 @@ private:
int m_retainedReadIndex;
QByteArray m_retainedReadBuf;
+ bool m_compositorOwnsSelection;
+
+
+ static void comp_accept(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t time,
+ const char *type);
+ static void comp_receive(struct wl_client *client,
+ struct wl_resource *resource,
+ const char *mime_type,
+ int32_t fd);
+ static void comp_destroy(struct wl_client *client,
+ struct wl_resource *resource);
+
+ static const struct wl_data_offer_interface compositor_offer_interface;
};
}
diff --git a/src/plugins/platforms/wayland/qwaylanddataoffer.cpp b/src/plugins/platforms/wayland/qwaylanddataoffer.cpp
index 0ef52a05..06a550f6 100644
--- a/src/plugins/platforms/wayland/qwaylanddataoffer.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddataoffer.cpp
@@ -40,56 +40,13 @@
****************************************************************************/
#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;
- if (mimeType == QLatin1String("text/plain")) {
- content = mimeData->text().toUtf8();
- } else if (mimeData->hasImage()
- && (mimeType == QLatin1String("application/x-qt-image")
- || mimeType.startsWith("image/"))) {
- QImage image = qvariant_cast<QImage>(mimeData->imageData());
- if (!image.isNull()) {
- QBuffer buf;
- buf.open(QIODevice::ReadWrite);
- QByteArray fmt = "BMP";
- if (mimeType.startsWith("image/")) {
- QByteArray imgFmt = mimeType.mid(6).toUpper().toAscii();
- if (QImageWriter::supportedImageFormats().contains(imgFmt))
- fmt = imgFmt;
- }
- QImageWriter wr(&buf, fmt);
- wr.write(image);
- content = buf.buffer();
- }
- } else if (mimeType == QLatin1String("application/x-color")) {
- content = qvariant_cast<QColor>(mimeData->colorData()).name().toAscii();
- } else if (mimeType == QLatin1String("text/uri-list")) {
- QList<QUrl> urls = mimeData->urls();
- for (int i = 0; i < urls.count(); ++i) {
- content.append(urls.at(i).toEncoded());
- content.append('\n');
- }
- } else {
- content = mimeData->data(mimeType);
- }
- return content;
-}
-
void QWaylandDataOffer::offer_sync_callback(void *data,
struct wl_callback *wl_callback,
diff --git a/src/plugins/platforms/wayland/qwaylanddataoffer.h b/src/plugins/platforms/wayland/qwaylanddataoffer.h
index 26cec393..d51f52d0 100644
--- a/src/plugins/platforms/wayland/qwaylanddataoffer.h
+++ b/src/plugins/platforms/wayland/qwaylanddataoffer.h
@@ -53,12 +53,6 @@
class QWaylandDisplay;
-class QWaylandMimeHelper
-{
-public:
- static QByteArray getByteArray(QMimeData *mimeData, const QString &mimeType);
-};
-
class QWaylandDataOffer : public QInternalMimeData
{
public:
diff --git a/src/plugins/platforms/wayland/qwaylanddatasource.cpp b/src/plugins/platforms/wayland/qwaylanddatasource.cpp
index 80015095..3b3e072e 100644
--- a/src/plugins/platforms/wayland/qwaylanddatasource.cpp
+++ b/src/plugins/platforms/wayland/qwaylanddatasource.cpp
@@ -40,9 +40,9 @@
****************************************************************************/
#include "qwaylanddatasource.h"
-
#include "qwaylanddataoffer.h"
#include "qwaylandinputdevice.h"
+#include "qwaylandmimehelper.h"
#include <QtCore/QFile>
diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro
index 05fa21f6..a3ad15d1 100644
--- a/src/plugins/platforms/wayland/wayland.pro
+++ b/src/plugins/platforms/wayland/wayland.pro
@@ -41,7 +41,8 @@ SOURCES = main.cpp \
qwaylandextendedoutput.cpp \
qwaylandextendedsurface.cpp \
qwaylandsubsurface.cpp \
- qwaylandtouch.cpp
+ qwaylandtouch.cpp \
+ $$PWD/../../../shared/qwaylandmimehelper.cpp
HEADERS = qwaylandintegration.h \
qwaylandnativeinterface.h \
@@ -62,9 +63,13 @@ HEADERS = qwaylandintegration.h \
qwaylandextendedoutput.h \
qwaylandextendedsurface.h \
qwaylandsubsurface.h \
- qwaylandtouch.h
+ qwaylandtouch.h \
+ $$PWD/../../../shared/qwaylandmimehelper.h
+
+INCLUDEPATH += $$PWD/../../../shared
INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND
+
LIBS += $$QMAKE_LIBS_WAYLAND
mac {
LIBS += -lwayland-client
diff --git a/src/shared/qwaylandmimehelper.cpp b/src/shared/qwaylandmimehelper.cpp
new file mode 100644
index 00000000..ffdaeef2
--- /dev/null
+++ b/src/shared/qwaylandmimehelper.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 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 "qwaylandmimehelper.h"
+#include <QImage>
+#include <QColor>
+#include <QUrl>
+#include <QBuffer>
+#include <QImageWriter>
+
+QByteArray QWaylandMimeHelper::getByteArray(QMimeData *mimeData, const QString &mimeType)
+{
+ QByteArray content;
+ if (mimeType == QLatin1String("text/plain")) {
+ content = mimeData->text().toUtf8();
+ } else if (mimeData->hasImage()
+ && (mimeType == QLatin1String("application/x-qt-image")
+ || mimeType.startsWith(QLatin1String("image/")))) {
+ QImage image = qvariant_cast<QImage>(mimeData->imageData());
+ if (!image.isNull()) {
+ QBuffer buf;
+ buf.open(QIODevice::ReadWrite);
+ QByteArray fmt = "BMP";
+ if (mimeType.startsWith(QLatin1String("image/"))) {
+ QByteArray imgFmt = mimeType.mid(6).toUpper().toAscii();
+ if (QImageWriter::supportedImageFormats().contains(imgFmt))
+ fmt = imgFmt;
+ }
+ QImageWriter wr(&buf, fmt);
+ wr.write(image);
+ content = buf.buffer();
+ }
+ } else if (mimeType == QLatin1String("application/x-color")) {
+ content = qvariant_cast<QColor>(mimeData->colorData()).name().toAscii();
+ } else if (mimeType == QLatin1String("text/uri-list")) {
+ QList<QUrl> urls = mimeData->urls();
+ for (int i = 0; i < urls.count(); ++i) {
+ content.append(urls.at(i).toEncoded());
+ content.append('\n');
+ }
+ } else {
+ content = mimeData->data(mimeType);
+ }
+ return content;
+}
diff --git a/src/shared/qwaylandmimehelper.h b/src/shared/qwaylandmimehelper.h
new file mode 100644
index 00000000..f38c74b9
--- /dev/null
+++ b/src/shared/qwaylandmimehelper.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 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 QWAYLANDMIMEHELPER_H
+#define QWAYLANDMIMEHELPER_H
+
+#include <QString>
+#include <QByteArray>
+#include <QMimeData>
+
+class QWaylandMimeHelper
+{
+public:
+ static QByteArray getByteArray(QMimeData *mimeData, const QString &mimeType);
+};
+
+#endif