summaryrefslogtreecommitdiffstats
path: root/src/compositor/wayland_wrapper
diff options
context:
space:
mode:
authorJan Arne Petersen <jan.petersen@kdab.com>2013-11-01 12:46:22 +0100
committerJørgen Lind <jorgen.lind@digia.com>2013-11-22 15:46:38 +0100
commitd06c04238238c780b6d0019b305b4ae8c99de425 (patch)
treefa5fbf0a960e63b4525168d309ccfc78de4927fc /src/compositor/wayland_wrapper
parent19992cf8f509e178b0cb0e31df28ba30b8020057 (diff)
Add Drag&Drop support to compositor
Change-Id: Ic606ac4dfbb1c55ddb81ac8a912132102753455c Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Diffstat (limited to 'src/compositor/wayland_wrapper')
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor.cpp11
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor_p.h3
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevice.cpp188
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevice_p.h53
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevicemanager.cpp66
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevicemanager_p.h21
-rw-r--r--src/compositor/wayland_wrapper/qwldataoffer.cpp68
-rw-r--r--src/compositor/wayland_wrapper/qwldataoffer_p.h32
-rw-r--r--src/compositor/wayland_wrapper/qwldatasource.cpp71
-rw-r--r--src/compositor/wayland_wrapper/qwldatasource_p.h35
-rw-r--r--src/compositor/wayland_wrapper/qwlinputdevice.cpp56
-rw-r--r--src/compositor/wayland_wrapper/qwlinputdevice_p.h10
12 files changed, 302 insertions, 312 deletions
diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp
index be55e425d..3a6b91b45 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp
@@ -486,6 +486,17 @@ QList<QtWayland::Surface *> Compositor::surfacesForClient(wl_client *client)
return ret;
}
+Surface *Compositor::pickSurface(const QPointF &globalPosition)
+{
+ QWaylandSurface *surface = m_qt_compositor->pickSurface(globalPosition);
+ return surface ? surface->handle() : 0;
+}
+
+QPointF Compositor::mapToSurface(Surface *surface, const QPointF &globalPosition)
+{
+ return m_qt_compositor->mapToSurface(surface->waylandSurface(), globalPosition);
+}
+
void Compositor::configureTouchExtension(int flags)
{
if (m_touchExtension)
diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h
index 65dfe3607..c8e8b2587 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor_p.h
+++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h
@@ -113,6 +113,9 @@ public:
QList<Surface*> surfacesForClient(wl_client* client);
QWaylandCompositor *waylandCompositor() const { return m_qt_compositor; }
+ Surface *pickSurface(const QPointF &globalPosition);
+ QPointF mapToSurface(Surface *surface, const QPointF &globalPosition);
+
struct wl_display *wl_display() const { return m_display->handle(); }
static Compositor *instance();
diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp
index 89fa7a08e..2257455f4 100644
--- a/src/compositor/wayland_wrapper/qwldatadevice.cpp
+++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp
@@ -40,11 +40,16 @@
#include "qwldatadevice_p.h"
+#include "qwlcompositor_p.h"
#include "qwldatasource_p.h"
#include "qwldataoffer_p.h"
-#include "qwldatadevicemanager_p.h"
+#include "qwlinputdevice_p.h"
+#include "qwlkeyboard_p.h"
+#include "qwlpointer_p.h"
+#include "qwlsurface_p.h"
+#include "qwltouch_p.h"
-#include <stdlib.h>
+#include "qwaylanddrag.h"
#include <QDebug>
@@ -52,78 +57,155 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
-void DataDevice::start_drag(struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *source,
- struct wl_resource *surface,
- struct wl_resource *icon,
- uint32_t time)
+DataDevice::DataDevice(InputDevice *inputDevice)
+ : wl_data_device()
+ , m_compositor(inputDevice->compositor())
+ , m_inputDevice(inputDevice)
+ , m_selectionSource(0)
+ , m_dragClient(0)
+ , m_dragDataSource(0)
+ , m_dragFocus(0)
+ , m_dragFocusResource(0)
+ , m_dragIcon(0)
{
- Q_UNUSED(client);
- Q_UNUSED(surface);
- Q_UNUSED(icon);
- Q_UNUSED(time);
- DataDevice *data_device = static_cast<DataDevice *>(resource->data);
- DataSource *data_source = static_cast<DataSource *>(source->data);
- Q_UNUSED(data_device);
- Q_UNUSED(data_source);
}
-void DataDevice::set_selection(struct wl_client *client,
- struct wl_resource *data_device_resource,
- struct wl_resource *source,
- uint32_t time)
+void DataDevice::setFocus(QtWaylandServer::wl_keyboard::Resource *focusResource)
{
- Q_UNUSED(client);
- Q_UNUSED(time);
- DataDevice *data_device = static_cast<DataDevice *>(data_device_resource->data);
- DataSource *data_source = static_cast<DataSource *>(source->data);
+ if (!focusResource)
+ return;
+
+ Resource *resource = resourceMap().value(focusResource->client());
+
+ if (!resource)
+ return;
+
+ if (m_selectionSource) {
+ DataOffer *offer = new DataOffer(m_selectionSource, resource);
+ send_selection(resource->handle, offer->resource()->handle);
+ }
+}
+
+void DataDevice::setDragFocus(Surface *focus, const QPointF &localPosition)
+{
+ if (m_dragFocusResource) {
+ send_leave(m_dragFocusResource->handle);
+ m_dragFocus = 0;
+ m_dragFocusResource = 0;
+ }
+
+ if (!focus)
+ return;
+
+ if (!m_dragDataSource && m_dragClient != focus->resource()->client())
+ return;
+
+ Resource *resource = resourceMap().value(focus->resource()->client());
+
+ if (!resource)
+ return;
+
+ uint32_t serial = wl_display_next_serial(m_compositor->wl_display());
+
+ DataOffer *offer = m_dragDataSource ? new DataOffer(m_dragDataSource, resource) : 0;
+
+ if (m_dragDataSource && !offer)
+ return;
- data_device->m_data_device_manager->setCurrentSelectionSource(data_source);
+ send_enter(resource->handle, serial, focus->resource()->handle,
+ wl_fixed_from_double(localPosition.x()), wl_fixed_from_double(localPosition.y()),
+ offer->resource()->handle);
+ m_dragFocus = focus;
+ m_dragFocusResource = resource;
}
-const struct wl_data_device_interface DataDevice::data_device_interface = {
- DataDevice::start_drag,
- DataDevice::set_selection
-};
+Surface *DataDevice::dragIcon() const
+{
+ return m_dragIcon;
+}
-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)
+void DataDevice::focus()
{
+ Surface *focus = m_compositor->pickSurface(m_pointer->currentPosition());
- //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);
+ if (focus != m_dragFocus)
+ setDragFocus(focus, m_compositor->mapToSurface(focus, m_pointer->currentPosition()));
}
-void DataDevice::sendSelectionFocus()
+void DataDevice::motion(uint32_t time)
{
- if (m_data_device_manager->offerFromCompositorToClient(m_data_device_resource))
- return;
+ if (m_dragIcon) {
+ m_dragIcon->setPos(m_pointer->currentPosition());
+ }
- DataSource *source = m_data_device_manager->currentSelectionSource();
- if (!source || !source->client()) {
- m_data_device_manager->offerRetainedSelection(m_data_device_resource);
- return;
+ if (m_dragFocusResource && m_dragFocus) {
+ const QPointF &surfacePoint = m_compositor->mapToSurface(m_dragFocus, m_pointer->currentPosition());
+ qDebug() << Q_FUNC_INFO << m_pointer->currentPosition() << surfacePoint;
+ send_motion(m_dragFocusResource->handle, time,
+ wl_fixed_from_double(surfacePoint.x()), wl_fixed_from_double(surfacePoint.y()));
}
- 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 = source->dataOffer();
- wl_resource *client_resource =
- data_offer->addDataDeviceResource(m_data_device_resource);
- //qDebug() << "sending data_offer for source" << source;
- wl_data_device_send_selection(m_data_device_resource,client_resource);
- m_sent_selection_time = source->time();
+}
+
+void DataDevice::button(uint32_t time, Qt::MouseButton button, uint32_t state)
+{
+ Q_UNUSED(time);
+
+ if (m_dragFocusResource &&
+ m_pointer->grabButton() == button &&
+ state == Pointer::button_state_released)
+ send_drop(m_dragFocusResource->handle);
+
+ if (!m_pointer->buttonPressed() &&
+ state == Pointer::button_state_released) {
+
+ if (m_dragIcon) {
+ m_dragIcon = 0;
+ Q_EMIT m_inputDevice->dragHandle()->iconChanged();
}
+
+ setDragFocus(0, QPointF());
+ m_pointer->endGrab();
+ }
+}
+
+void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial)
+{
+ if (m_inputDevice->pointerDevice()->grabSerial() == serial) {
+ if (!m_inputDevice->pointerDevice()->buttonPressed() ||
+ m_inputDevice->pointerDevice()->focusSurface() != Surface::fromResource(origin))
+ return;
+
+ m_dragClient = resource->client();
+ m_dragDataSource = source != 0 ? DataSource::fromResource(source) : 0;
+ m_dragIcon = icon != 0 ? Surface::fromResource(icon) : 0;
+ Q_EMIT m_inputDevice->dragHandle()->iconChanged();
+
+ m_inputDevice->pointerDevice()->setFocus(0, QPointF());
+ m_inputDevice->pointerDevice()->startGrab(this);
}
}
-struct wl_resource *DataDevice::dataDeviceResource() const
+void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *source, uint32_t serial)
{
- return m_data_device_resource;
+ Q_UNUSED(serial);
+
+ DataSource *dataSource = source ? DataSource::fromResource(source) : 0;
+
+ if (m_selectionSource)
+ m_selectionSource->cancel();
+
+ m_selectionSource = dataSource;
+
+ QtWaylandServer::wl_keyboard::Resource *focusResource = m_inputDevice->keyboardDevice()->focusResource();
+ Resource *resource = focusResource ? resourceMap().value(focusResource->client()) : 0;
+
+ if (resource && m_selectionSource) {
+ DataOffer *offer = new DataOffer(m_selectionSource, resource);
+ send_selection(resource->handle, offer->resource()->handle);
+ } else if (resource) {
+ send_selection(resource->handle, 0);
+ }
}
}
diff --git a/src/compositor/wayland_wrapper/qwldatadevice_p.h b/src/compositor/wayland_wrapper/qwldatadevice_p.h
index 2b4acdc9d..edbb517c5 100644
--- a/src/compositor/wayland_wrapper/qwldatadevice_p.h
+++ b/src/compositor/wayland_wrapper/qwldatadevice_p.h
@@ -41,42 +41,49 @@
#ifndef WLDATADEVICE_H
#define WLDATADEVICE_H
-#include <private/qwldatadevicemanager_p.h>
+#include <qwayland-server-wayland.h>
+#include <qwlpointer_p.h>
QT_BEGIN_NAMESPACE
namespace QtWayland {
+class Compositor;
class DataSource;
-class DataDeviceManager;
+class InputDevice;
+class Surface;
-class DataDevice
+class DataDevice : public QtWaylandServer::wl_data_device, public PointerGrabber
{
public:
- DataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id);
+ DataDevice(InputDevice *inputDevice);
- void createAndSetSelectionSource(struct wl_client *client, uint32_t id, const char *name, uint32_t time);
- void sendSelectionFocus();
+ void setFocus(QtWaylandServer::wl_keyboard::Resource *focusResource);
- struct wl_resource *dataDeviceResource() const;
+ void setDragFocus(Surface *focus, const QPointF &localPosition);
+
+ Surface *dragIcon() const;
+
+ void focus() Q_DECL_OVERRIDE;
+ void motion(uint32_t time) Q_DECL_OVERRIDE;
+ void button(uint32_t time, Qt::MouseButton button, uint32_t state) Q_DECL_OVERRIDE;
+protected:
+ void data_device_start_drag(Resource *resource, struct ::wl_resource *source, struct ::wl_resource *origin, struct ::wl_resource *icon, uint32_t serial) Q_DECL_OVERRIDE;
+ void data_device_set_selection(Resource *resource, struct ::wl_resource *source, uint32_t serial) Q_DECL_OVERRIDE;
- 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,
- struct wl_resource *icon,
- uint32_t time);
- static void set_selection(struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *source,
- uint32_t time);
+ Compositor *m_compositor;
+ InputDevice *m_inputDevice;
+
+ DataSource *m_selectionSource;
+
+ struct ::wl_client *m_dragClient;
+ DataSource *m_dragDataSource;
+
+ Surface *m_dragFocus;
+ Resource *m_dragFocusResource;
+
+ Surface *m_dragIcon;
};
}
diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
index c27aa514f..289108563 100644
--- a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
+++ b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
@@ -59,12 +59,13 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
DataDeviceManager::DataDeviceManager(Compositor *compositor)
- : m_compositor(compositor)
+ : QObject(0)
+ , wl_data_device_manager(compositor->wl_display())
+ , 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);
}
void DataDeviceManager::setCurrentSelectionSource(DataSource *source)
@@ -104,13 +105,13 @@ void DataDeviceManager::sourceDestroyed(DataSource *source)
void DataDeviceManager::retain()
{
- QList<QByteArray> offers = m_current_selection_source->offerList();
+ QList<QString> offers = m_current_selection_source->mimeTypes();
finishReadFromClient();
if (m_retainedReadIndex >= offers.count()) {
m_compositor->feedRetainedSelectionData(&m_retainedData);
return;
}
- QByteArray mimeType = offers.at(m_retainedReadIndex);
+ QString mimeType = offers.at(m_retainedReadIndex);
m_retainedReadBuf.clear();
int fd[2];
if (pipe(fd) == -1) {
@@ -118,8 +119,7 @@ void DataDeviceManager::retain()
return;
}
fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL, 0) | O_NONBLOCK);
- m_current_selection_source->postSendEvent(mimeType, fd[1]);
- close(fd[1]);
+ m_current_selection_source->send(mimeType, fd[1]);
m_retainedReadNotifier = new QSocketNotifier(fd[0], QSocketNotifier::Read, this);
connect(m_retainedReadNotifier, SIGNAL(activated(int)), SLOT(readFromClient(int)));
}
@@ -167,8 +167,8 @@ void DataDeviceManager::readFromClient(int fd)
if (n <= 0) {
if (n != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) {
finishReadFromClient(true);
- QList<QByteArray> offers = m_current_selection_source->offerList();
- QString mimeType = QString::fromLatin1(offers.at(m_retainedReadIndex));
+ QList<QString> offers = m_current_selection_source->mimeTypes();
+ QString mimeType = offers.at(m_retainedReadIndex);
m_retainedData.setData(mimeType, m_retainedReadBuf);
++m_retainedReadIndex;
retain();
@@ -188,43 +188,6 @@ 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)
-{
- Q_UNUSED(version);
- 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)
-{
- Q_UNUSED(client);
- Q_UNUSED(data);
- Q_UNUSED(version);
- Q_UNUSED(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 = InputDevice::fromSeatResource(input_device_resource);
- 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
-};
-
void DataDeviceManager::overrideSelection(const QMimeData &mimeData)
{
QStringList formats = mimeData.formats();
@@ -243,7 +206,7 @@ void DataDeviceManager::overrideSelection(const QMimeData &mimeData)
Surface *focusSurface = dev->keyboardFocus();
if (focusSurface)
offerFromCompositorToClient(
- dev->dataDevice(focusSurface->resource()->client())->dataDeviceResource());
+ dev->dataDevice()->resourceMap().value(focusSurface->resource()->client())->handle);
}
bool DataDeviceManager::offerFromCompositorToClient(wl_resource *clientDataDeviceResource)
@@ -275,6 +238,17 @@ void DataDeviceManager::offerRetainedSelection(wl_resource *clientDataDeviceReso
offerFromCompositorToClient(clientDataDeviceResource);
}
+void DataDeviceManager::data_device_manager_create_data_source(Resource *resource, uint32_t id)
+{
+ new DataSource(resource->client(), id, Compositor::currentTimeMsecs());
+}
+
+void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat)
+{
+ InputDevice *input_device = InputDevice::fromSeatResource(seat);
+ input_device->clientRequestedDataDevice(this, resource->client(), id);
+}
+
void DataDeviceManager::comp_accept(wl_client *, wl_resource *, uint32_t, const char *)
{
}
diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h b/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h
index 11510e63b..dcb51e16b 100644
--- a/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h
+++ b/src/compositor/wayland_wrapper/qwldatadevicemanager_p.h
@@ -48,6 +48,8 @@
#include <QtGui/QClipboard>
#include <QtCore/QMimeData>
+#include <qwayland-server-wayland.h>
+
QT_BEGIN_NAMESPACE
class QSocketNotifier;
@@ -59,7 +61,7 @@ class Compositor;
class DataDevice;
class DataSource;
-class DataDeviceManager : public QObject
+class DataDeviceManager : public QObject, public QtWaylandServer::wl_data_device_manager
{
Q_OBJECT
@@ -77,6 +79,10 @@ public:
bool offerFromCompositorToClient(wl_resource *clientDataDeviceResource);
void offerRetainedSelection(wl_resource *clientDataDeviceResource);
+protected:
+ void data_device_manager_create_data_source(Resource *resource, uint32_t id) Q_DECL_OVERRIDE;
+ void data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE;
+
private slots:
void readFromClient(int fd);
@@ -89,19 +95,6 @@ private:
DataSource *m_current_selection_source;
- 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;
-
QMimeData m_retainedData;
QSocketNotifier *m_retainedReadNotifier;
QList<QSocketNotifier *> m_obsoleteRetainedReadNotifiers;
diff --git a/src/compositor/wayland_wrapper/qwldataoffer.cpp b/src/compositor/wayland_wrapper/qwldataoffer.cpp
index c2bfea35a..86db2dc36 100644
--- a/src/compositor/wayland_wrapper/qwldataoffer.cpp
+++ b/src/compositor/wayland_wrapper/qwldataoffer.cpp
@@ -41,78 +41,52 @@
#include "qwldataoffer_p.h"
#include "qwldatadevice_p.h"
+#include "qwldatasource_p.h"
-#include <wayland-server.h>
-
-#include <sys/time.h>
#include <unistd.h>
-#include <QtCore/QDebug>
-
QT_BEGIN_NAMESPACE
namespace QtWayland
{
-DataOffer::DataOffer(DataSource *data_source)
- : m_data_source(data_source)
+DataOffer::DataOffer(DataSource *dataSource, QtWaylandServer::wl_data_device::Resource *target)
+ : QtWaylandServer::wl_data_offer(dataSource->resource()->client(), 0)
+ , m_dataSource(dataSource)
{
-
+ // FIXME: connect to dataSource and reset m_dataSource on destroy
+ target->data_device->send_data_offer(target->handle, resource()->handle);
+ Q_FOREACH (const QString &mimeType, dataSource->mimeTypes()) {
+ send_offer(mimeType);
+ }
}
DataOffer::~DataOffer()
{
}
-struct wl_resource *DataOffer::addDataDeviceResource(struct wl_resource *data_device_resource)
+void DataOffer::data_offer_accept(Resource *resource, uint32_t serial, const QString &mimeType)
{
- if (resourceForClient(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_data_device_send_data_offer(data_device_resource, new_object);
-
- registerResource(new_object);
- QList<QByteArray> offer_list = m_data_source->offerList();
- for (int i = 0; i < offer_list.size(); i++) {
- wl_data_offer_send_offer(new_object, offer_list.at(i).constData());
- }
- return new_object;
+ if (m_dataSource)
+ m_dataSource->accept(mimeType);
}
-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::data_offer_receive(Resource *resource, const QString &mimeType, int32_t fd)
{
- Q_UNUSED(client);
- Q_UNUSED(resource);
- Q_UNUSED(time);
- Q_UNUSED(type);
+ if (m_dataSource)
+ m_dataSource->send(mimeType, fd);
+ else
+ close(fd);
}
-void DataOffer::receive(wl_client *client, wl_resource *resource, const char *mime_type, int32_t fd)
+void DataOffer::data_offer_destroy(Resource *resource)
{
- Q_UNUSED(client);
-
- DataOffer *offer = static_cast<DataOffer *>(resource->data);
- offer->m_data_source->postSendEvent(mime_type,fd);
- close(fd);
+ wl_resource_destroy(resource->handle);
}
-void DataOffer::destroy(wl_client *client, wl_resource *resource)
+void DataOffer::data_offer_destroy_resource(Resource *)
{
- Q_UNUSED(client);
- DataOffer *data_offer = static_cast<DataOffer *>(resource->data);
-
- if (data_offer->resourceListIsEmpty()) {
- delete data_offer;
- }
+ delete this;
}
}
diff --git a/src/compositor/wayland_wrapper/qwldataoffer_p.h b/src/compositor/wayland_wrapper/qwldataoffer_p.h
index 579434450..d29658576 100644
--- a/src/compositor/wayland_wrapper/qwldataoffer_p.h
+++ b/src/compositor/wayland_wrapper/qwldataoffer_p.h
@@ -41,37 +41,29 @@
#ifndef WLDATAOFFER_H
#define WLDATAOFFER_H
-#include <private/qwldatasource_p.h>
-#include <QtCompositor/qwaylandresourcecollection.h>
+#include <qwayland-server-wayland.h>
QT_BEGIN_NAMESPACE
namespace QtWayland
{
-class DataOffer : public ResourceCollection
+class DataSource;
+
+class DataOffer : public QtWaylandServer::wl_data_offer
{
public:
- DataOffer(DataSource *data_source);
+ DataOffer(DataSource *data_source, QtWaylandServer::wl_data_device::Resource *target);
~DataOffer();
- struct wl_resource *addDataDeviceResource(struct wl_resource *client_resource);
-private:
- DataSource *m_data_source;
-
- 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;
+protected:
+ void data_offer_accept(Resource *resource, uint32_t serial, const QString &mime_type) Q_DECL_OVERRIDE;
+ void data_offer_receive(Resource *resource, const QString &mime_type, int32_t fd) Q_DECL_OVERRIDE;
+ void data_offer_destroy(Resource *resource) Q_DECL_OVERRIDE;
+ void data_offer_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;
+private:
+ DataSource *m_dataSource;
};
}
diff --git a/src/compositor/wayland_wrapper/qwldatasource.cpp b/src/compositor/wayland_wrapper/qwldatasource.cpp
index d60ec5108..a31ed8e70 100644
--- a/src/compositor/wayland_wrapper/qwldatasource.cpp
+++ b/src/compositor/wayland_wrapper/qwldatasource.cpp
@@ -40,23 +40,20 @@
#include "qwldatasource_p.h"
#include "qwldataoffer_p.h"
+#include "qwldatadevice_p.h"
#include "qwldatadevicemanager_p.h"
#include "qwlcompositor_p.h"
-#include <wayland-wayland-server-protocol.h>
-
-#include <QtCore/QDebug>
+#include <unistd.h>
QT_BEGIN_NAMESPACE
namespace QtWayland {
DataSource::DataSource(struct wl_client *client, uint32_t id, uint32_t time)
- : m_time(time)
+ : QtWaylandServer::wl_data_source(client, id)
+ , m_time(time)
{
- m_data_source_resource = wl_client_add_object(client, &wl_data_source_interface, &DataSource::data_source_interface,id,this);
- m_data_source_resource->destroy = resource_destroy;
- m_data_offer = new DataOffer(this);
m_manager = 0;
}
@@ -64,71 +61,57 @@ DataSource::~DataSource()
{
if (m_manager)
m_manager->sourceDestroyed(this);
- wl_resource_destroy(m_data_source_resource);
}
-void DataSource::resource_destroy(wl_resource *resource)
+uint32_t DataSource::time() const
{
- DataSource *source = static_cast<DataSource *>(resource->data);
- if (source && source->m_data_source_resource == resource)
- source->m_data_source_resource = 0;
- free(resource);
+ return m_time;
}
-uint32_t DataSource::time() const
+QList<QString> DataSource::mimeTypes() const
{
- return m_time;
+ return m_mimeTypes;
}
-QList<QByteArray> DataSource::offerList() const
+void DataSource::accept(const QString &mimeType)
{
- return m_offers;
+ send_target(mimeType);
}
-struct wl_data_source_interface DataSource::data_source_interface = {
- DataSource::offer,
- DataSource::destroy
-};
+void DataSource::send(const QString &mimeType, int fd)
+{
+ send_send(mimeType, fd);
+ close(fd);
+}
-void DataSource::offer(struct wl_client *client,
- struct wl_resource *resource,
- const char *type)
+void DataSource::cancel()
{
- Q_UNUSED(client);
- //qDebug() << "received offer" << type;
- static_cast<DataSource *>(resource->data)->m_offers.append(type);
+ send_cancelled();
}
-void DataSource::destroy(struct wl_client *client,
- struct wl_resource *resource)
+void DataSource::setManager(DataDeviceManager *mgr)
{
- Q_UNUSED(client);
- DataSource *self = static_cast<DataSource *>(resource->data);
- delete self;
+ m_manager = mgr;
}
-DataOffer * DataSource::dataOffer() const
+DataSource *DataSource::fromResource(struct ::wl_resource *resource)
{
- return m_data_offer;
+ return static_cast<DataSource *>(Resource::fromResource(resource)->data_source);
}
-void DataSource::postSendEvent(const QByteArray &mimeType, int fd)
+void DataSource::data_source_offer(Resource *, const QString &mime_type)
{
- if (m_data_source_resource) {
- wl_data_source_send_send(m_data_source_resource, mimeType.constData(), fd);
- }
+ m_mimeTypes.append(mime_type);
}
-struct wl_client *DataSource::client() const
+void DataSource::data_source_destroy(Resource *resource)
{
- if (m_data_source_resource)
- return m_data_source_resource->client;
- return 0;
+ wl_resource_destroy(resource->handle);
}
-void DataSource::setManager(DataDeviceManager *mgr)
+void DataSource::data_source_destroy_resource(QtWaylandServer::wl_data_source::Resource *resource)
{
- m_manager = mgr;
+ delete this;
}
}
diff --git a/src/compositor/wayland_wrapper/qwldatasource_p.h b/src/compositor/wayland_wrapper/qwldatasource_p.h
index be855d8da..c46e71380 100644
--- a/src/compositor/wayland_wrapper/qwldatasource_p.h
+++ b/src/compositor/wayland_wrapper/qwldatasource_p.h
@@ -41,9 +41,8 @@
#ifndef WLDATASOURCE_H
#define WLDATASOURCE_H
-#include <wayland-server.h>
+#include <qwayland-server-wayland.h>
-#include <QtCore/QByteArray>
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
@@ -53,38 +52,32 @@ namespace QtWayland {
class DataOffer;
class DataDeviceManager;
-class DataSource
+class DataSource : public QtWaylandServer::wl_data_source
{
public:
DataSource(struct wl_client *client, uint32_t id, uint32_t time);
~DataSource();
uint32_t time() const;
- QList<QByteArray> offerList() const;
+ QList<QString> mimeTypes() const;
- DataOffer *dataOffer() const;
-
- void postSendEvent(const QByteArray &mimeType,int fd);
- struct wl_client *client() const;
+ void accept(const QString &mimeType);
+ void send(const QString &mimeType,int fd);
+ void cancel();
void setManager(DataDeviceManager *mgr);
+ static DataSource *fromResource(struct ::wl_resource *resource);
+
+protected:
+ void data_source_offer(Resource *resource, const QString &mime_type) Q_DECL_OVERRIDE;
+ void data_source_destroy(Resource *resource) Q_DECL_OVERRIDE;
+ void data_source_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;
+
private:
uint32_t m_time;
- QList<QByteArray> m_offers;
- struct wl_resource *m_data_source_resource;
-
- DataOffer *m_data_offer;
+ QList<QString> m_mimeTypes;
DataDeviceManager *m_manager;
-
- 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);
-
- static void resource_destroy(struct wl_resource *resource);
};
}
diff --git a/src/compositor/wayland_wrapper/qwlinputdevice.cpp b/src/compositor/wayland_wrapper/qwlinputdevice.cpp
index bde898995..de448c53b 100644
--- a/src/compositor/wayland_wrapper/qwlinputdevice.cpp
+++ b/src/compositor/wayland_wrapper/qwlinputdevice.cpp
@@ -47,6 +47,7 @@
#include "qwlqttouch_p.h"
#include "qwlqtkey_p.h"
#include "qwaylandcompositor.h"
+#include "qwaylanddrag.h"
#include "qwlpointer_p.h"
#include "qwlkeyboard_p.h"
#include "qwltouch_p.h"
@@ -60,17 +61,18 @@ namespace QtWayland {
InputDevice::InputDevice(QWaylandInputDevice *handle, Compositor *compositor)
: QtWaylandServer::wl_seat(compositor->wl_display())
, m_handle(handle)
+ , m_dragHandle(new QWaylandDrag(this))
, m_compositor(compositor)
, m_pointer(new Pointer(m_compositor, this))
, m_keyboard(new Keyboard(m_compositor, this))
, m_touch(new Touch(m_compositor))
, m_inputMethod(m_compositor->extensions() & QWaylandCompositor::TextInputExtension ? new InputMethod(m_compositor, this) : 0)
+ , m_data_device()
{
}
InputDevice::~InputDevice()
{
- qDeleteAll(m_data_devices);
}
Pointer *InputDevice::pointerDevice()
@@ -108,9 +110,9 @@ const Touch *InputDevice::touchDevice() const
return m_touch.data();
}
-void InputDevice::seat_destroy_resource(wl_seat::Resource *resource)
+void InputDevice::seat_destroy_resource(wl_seat::Resource *)
{
- cleanupDataDeviceForClient(resource->client(), true);
+// cleanupDataDeviceForClient(resource->client(), true);
}
void InputDevice::seat_bind_resource(wl_seat::Resource *resource)
@@ -254,8 +256,8 @@ bool InputDevice::setKeyboardFocus(Surface *surface)
if (surface && surface->transientInactive())
return false;
- sendSelectionFocus(surface);
m_keyboard->setFocus(surface);
+ m_data_device->setFocus(m_keyboard->focusResource());
return true;
}
@@ -273,35 +275,11 @@ void InputDevice::setMouseFocus(Surface *surface, const QPointF &localPos, const
m_touch->setFocus(surface);
}
-void InputDevice::cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev)
+void InputDevice::clientRequestedDataDevice(DataDeviceManager *, 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) {
- if (destroyDev)
- delete m_data_devices.at(i);
- m_data_devices.removeAt(i);
- break;
- }
- }
-}
-
-void InputDevice::clientRequestedDataDevice(DataDeviceManager *data_device_manager, struct wl_client *client, uint32_t id)
-{
- cleanupDataDeviceForClient(client, false);
- 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->resource()->client());
- if (device) {
- device->sendSelectionFocus();
- }
+ if (!m_data_device)
+ m_data_device.reset(new DataDevice(this));
+ m_data_device->add(client, id);
}
Compositor *InputDevice::compositor() const
@@ -314,14 +292,14 @@ QWaylandInputDevice *InputDevice::handle() const
return m_handle;
}
-DataDevice *InputDevice::dataDevice(struct wl_client *client) const
+QWaylandDrag *InputDevice::dragHandle() 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;
+ return m_dragHandle;
+}
+
+const DataDevice *InputDevice::dataDevice() const
+{
+ return m_data_device.data();
}
}
diff --git a/src/compositor/wayland_wrapper/qwlinputdevice_p.h b/src/compositor/wayland_wrapper/qwlinputdevice_p.h
index c3c8fe570..3f7e4cc87 100644
--- a/src/compositor/wayland_wrapper/qwlinputdevice_p.h
+++ b/src/compositor/wayland_wrapper/qwlinputdevice_p.h
@@ -60,6 +60,7 @@ QT_BEGIN_NAMESPACE
class QKeyEvent;
class QTouchEvent;
class QWaylandInputDevice;
+class QWaylandDrag;
namespace QtWayland {
@@ -98,11 +99,11 @@ public:
void setMouseFocus(Surface *surface, const QPointF &localPos, const QPointF &globalPos);
void clientRequestedDataDevice(DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id);
- DataDevice *dataDevice(struct wl_client *client) const;
- void sendSelectionFocus(Surface *surface);
+ const DataDevice *dataDevice() const;
Compositor *compositor() const;
QWaylandInputDevice *handle() const;
+ QWaylandDrag *dragHandle() const;
Pointer *pointerDevice();
Keyboard *keyboardDevice();
@@ -119,16 +120,15 @@ public:
}
private:
- void cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev);
-
QWaylandInputDevice *m_handle;
+ QWaylandDrag *m_dragHandle;
Compositor *m_compositor;
- QList<DataDevice *> m_data_devices;
QScopedPointer<Pointer> m_pointer;
QScopedPointer<Keyboard> m_keyboard;
QScopedPointer<Touch> m_touch;
QScopedPointer<InputMethod> m_inputMethod;
+ QScopedPointer<DataDevice> m_data_device;
void seat_bind_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE;