summaryrefslogtreecommitdiffstats
path: root/src/compositor/compositor_api/qwaylandinput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor/compositor_api/qwaylandinput.cpp')
-rw-r--r--src/compositor/compositor_api/qwaylandinput.cpp405
1 files changed, 328 insertions, 77 deletions
diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandinput.cpp
index 4e106f5fe..be566c70d 100644
--- a/src/compositor/compositor_api/qwaylandinput.cpp
+++ b/src/compositor/compositor_api/qwaylandinput.cpp
@@ -3,52 +3,135 @@
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
-** This file is part of the Qt Compositor.
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
-** "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 The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
**
-**
-** 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."
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later 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 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwaylandinput.h"
+#include "qwaylandinput_p.h"
-#include "qwlinputdevice_p.h"
-#include "qwlkeyboard_p.h"
#include "qwaylandcompositor.h"
-#include "qwlsurface_p.h"
-#include "qwlcompositor_p.h"
-#include "qwaylandsurfaceview.h"
+#include "qwaylandview.h"
+#include <QtWaylandCompositor/QWaylandDrag>
+#include <QtWaylandCompositor/QWaylandTouch>
+#include <QtWaylandCompositor/QWaylandPointer>
+#include <QtWaylandCompositor/private/qwlinputmethod_p.h>
+#include <QtWaylandCompositor/private/qwaylandinput_p.h>
+#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
+#include <QtWaylandCompositor/private/qwldatadevice_p.h>
+
+#include "extensions/qwlqtkey_p.h"
QT_BEGIN_NAMESPACE
+QWaylandInputDevicePrivate::QWaylandInputDevicePrivate(QWaylandInputDevice *inputdevice, QWaylandCompositor *compositor)
+ : QObjectPrivate()
+ , QtWaylandServer::wl_seat(compositor->display(), 3)
+ , compositor(compositor)
+ , mouseFocus(Q_NULLPTR)
+ , capabilities()
+ , data_device()
+ , drag_handle(new QWaylandDrag(inputdevice))
+{
+}
+
+QWaylandInputDevicePrivate::~QWaylandInputDevicePrivate()
+{
+}
+
+void QWaylandInputDevicePrivate::setCapabilities(QWaylandInputDevice::CapabilityFlags caps)
+{
+ Q_Q(QWaylandInputDevice);
+ if (capabilities != caps) {
+ QWaylandInputDevice::CapabilityFlags changed = caps ^ capabilities;
+
+ if (changed & QWaylandInputDevice::Pointer) {
+ pointer.reset(pointer.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreatePointerDevice(q) : 0);
+ }
+
+ if (changed & QWaylandInputDevice::Keyboard) {
+ keyboard.reset(keyboard.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateKeyboardDevice(q) : 0);
+ }
+
+ if (changed & QWaylandInputDevice::Touch) {
+ touch.reset(touch.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateTouchDevice(q) : 0);
+ }
+
+ capabilities = caps;
+ QList<Resource *> resources = resourceMap().values();
+ for (int i = 0; i < resources.size(); i++) {
+ wl_seat::send_capabilities(resources.at(i)->handle, (uint32_t)capabilities);
+ }
+ }
+}
+
+void QWaylandInputDevicePrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *, struct wl_client *client, uint32_t id)
+{
+ Q_Q(QWaylandInputDevice);
+ if (!data_device)
+ data_device.reset(new QtWayland::DataDevice(q));
+ data_device->add(client, id, 1);
+}
+
+void QWaylandInputDevicePrivate::seat_destroy_resource(wl_seat::Resource *)
+{
+// cleanupDataDeviceForClient(resource->client(), true);
+}
+
+void QWaylandInputDevicePrivate::seat_bind_resource(wl_seat::Resource *resource)
+{
+ // The order of capabilities matches the order defined in the wayland protocol
+ wl_seat::send_capabilities(resource->handle, (uint32_t)capabilities);
+}
+
+void QWaylandInputDevicePrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id)
+{
+ if (!pointer.isNull()) {
+ pointer->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
+ }
+}
+
+void QWaylandInputDevicePrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id)
+{
+ if (!keyboard.isNull()) {
+ keyboard->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
+ }
+}
+
+void QWaylandInputDevicePrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id)
+{
+ if (!touch.isNull()) {
+ touch->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
+ }
+}
+
QWaylandKeymap::QWaylandKeymap(const QString &layout, const QString &variant, const QString &options, const QString &model, const QString &rules)
: m_layout(layout)
, m_variant(variant)
@@ -59,134 +142,302 @@ QWaylandKeymap::QWaylandKeymap(const QString &layout, const QString &variant, co
}
+/*!
+ * \class QWaylandInputDevice
+ * \inmodule QtWaylandCompositor
+ * \brief The QWaylandInputDevice class provides access to keyboard, mouse and touch input.
+ *
+ * The QWaylandInputDevice provides access to different types of user input and maintains
+ * a keyboard focus and a mouse pointer. It corresponds to the wl_seat interface in the Wayland protocol.
+ */
-QWaylandInputDevice::QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags caps)
- : d(new QtWayland::InputDevice(this,compositor->handle(), caps))
-{
-}
+/*!
+ * \enum QWaylandInputDevice::CapabilityFlag
+ *
+ * This enum type describes the capabilities of a QWaylandInputDevice.
+ *
+ * \value Pointer The QWaylandInputDevice supports pointer input.
+ * \value Keyboard The QWaylandInputDevice supports keyboard input.
+ * \value Touch The QWaylandInputDevice supports touch input.
+ */
-QWaylandInputDevice::~QWaylandInputDevice()
+/*!
+ * Constructs a QWaylandInputDevice for the given \a compositor and with the given \a capabilityFlags.
+ */
+QWaylandInputDevice::QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags)
+ : QWaylandObject(*new QWaylandInputDevicePrivate(this,compositor))
{
- delete d;
+ d_func()->setCapabilities(capabilityFlags);
}
-void QWaylandInputDevice::sendMousePressEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos)
+/*!
+ * Destroys the QWaylandInputDevice
+ */
+QWaylandInputDevice::~QWaylandInputDevice()
{
- d->sendMousePressEvent(button,localPos,globalPos);
}
-void QWaylandInputDevice::sendMouseReleaseEvent(Qt::MouseButton button, const QPointF &localPos, const QPointF &globalPos)
+/*!
+ * Sends a mouse press event for \a button to the QWaylandInputDevice's pointer device.
+ */
+void QWaylandInputDevice::sendMousePressEvent(Qt::MouseButton button)
{
- d->sendMouseReleaseEvent(button,localPos,globalPos);
+ Q_D(QWaylandInputDevice);
+ d->pointer->sendMousePressEvent(button);
}
-void QWaylandInputDevice::sendMouseMoveEvent(const QPointF &localPos, const QPointF &globalPos)
+/*!
+ * Sends a mouse release event for \a button to the QWaylandInputDevice's pointer device.
+ */
+void QWaylandInputDevice::sendMouseReleaseEvent(Qt::MouseButton button)
{
- d->sendMouseMoveEvent(localPos,globalPos);
+ Q_D(QWaylandInputDevice);
+ d->pointer->sendMouseReleaseEvent(button);
}
-/** Convenience function that will set the mouse focus to the surface, then send the mouse move event.
- * If the mouse focus is the same surface as the surface passed in, then only the move event is sent
+/*!
+ * Sets the mouse focus to \a view and sends a mouse move event to the pointer device with the
+ * local position \a localPos and output space position \a outputSpacePos.
**/
-void QWaylandInputDevice::sendMouseMoveEvent(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos)
+void QWaylandInputDevice::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos)
{
- d->sendMouseMoveEvent(surface,localPos,globalPos);
+ Q_D(QWaylandInputDevice);
+ d->pointer->sendMouseMoveEvent(view, localPos, outputSpacePos);
}
+/*!
+ * Sends a mouse wheel event to the QWaylandInputDevice's pointer device with the given \a orientation and \a delta.
+ */
void QWaylandInputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta)
{
- d->sendMouseWheelEvent(orientation, delta);
+ Q_D(QWaylandInputDevice);
+ d->pointer->sendMouseWheelEvent(orientation, delta);
}
+/*!
+ * Sends a key press event with the key \a code to the keyboard device.
+ */
void QWaylandInputDevice::sendKeyPressEvent(uint code)
{
- d->keyboardDevice()->sendKeyPressEvent(code);
+ Q_D(QWaylandInputDevice);
+ d->keyboard->sendKeyPressEvent(code);
}
+/*!
+ * Sends a key release event with the key \a code to the keyboard device.
+ */
void QWaylandInputDevice::sendKeyReleaseEvent(uint code)
{
- d->keyboardDevice()->sendKeyReleaseEvent(code);
+ Q_D(QWaylandInputDevice);
+ d->keyboard->sendKeyReleaseEvent(code);
}
-void QWaylandInputDevice::sendTouchPointEvent(int id, double x, double y, Qt::TouchPointState state)
+/*!
+ * Sends a touch point event with the given \a id and \a state to the touch device. The position
+ * of the touch point is given by \a point.
+ */
+void QWaylandInputDevice::sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state)
{
- d->sendTouchPointEvent(id,x,y,state);
+ Q_D(QWaylandInputDevice);
+ if (d->touch.isNull()) {
+ return;
+ }
+ d->touch->sendTouchPointEvent(id, point,state);
}
+/*!
+ * Sends a frame event to the touch device.
+ */
void QWaylandInputDevice::sendTouchFrameEvent()
{
- d->sendTouchFrameEvent();
+ Q_D(QWaylandInputDevice);
+ if (!d->touch.isNull()) {
+ d->touch->sendFrameEvent();
+ }
}
+/*!
+ * Sends a cancel event to the touch device.
+ */
void QWaylandInputDevice::sendTouchCancelEvent()
{
- d->sendTouchCancelEvent();
+ Q_D(QWaylandInputDevice);
+ if (!d->touch.isNull()) {
+ d->touch->sendCancelEvent();
+ }
}
+/*!
+ * Sends the \a event to the touch device.
+ */
void QWaylandInputDevice::sendFullTouchEvent(QTouchEvent *event)
{
- d->sendFullTouchEvent(event);
+ Q_D(QWaylandInputDevice);
+ if (!mouseFocus()) {
+ qWarning("Cannot send touch event, no pointer focus, fix the compositor");
+ return;
+ }
+
+ if (!d->touch)
+ return;
+
+ d->touch->sendFullTouchEvent(event);
}
+/*!
+ * Sends the \a event to the keyboard device.
+ */
void QWaylandInputDevice::sendFullKeyEvent(QKeyEvent *event)
{
- d->sendFullKeyEvent(event);
+ Q_D(QWaylandInputDevice);
+ if (!keyboardFocus()) {
+ qWarning("Cannot send key event, no keyboard focus, fix the compositor");
+ return;
+ }
+
+ QtWayland::QtKeyExtensionGlobal *ext = QtWayland::QtKeyExtensionGlobal::findIn(d->compositor);
+ if (ext && ext->postQtKeyEvent(event, keyboardFocus()))
+ return;
+
+ if (!d->keyboard.isNull() && !event->isAutoRepeat()) {
+ if (event->type() == QEvent::KeyPress)
+ d->keyboard->sendKeyPressEvent(event->nativeScanCode());
+ else if (event->type() == QEvent::KeyRelease)
+ d->keyboard->sendKeyReleaseEvent(event->nativeScanCode());
+ }
}
-void QWaylandInputDevice::sendFullKeyEvent(QWaylandSurface *surface, QKeyEvent *event)
+/*!
+ * Returns the keyboard for this input device.
+ */
+QWaylandKeyboard *QWaylandInputDevice::keyboard() const
{
- d->sendFullKeyEvent(surface->handle(), event);
+ Q_D(const QWaylandInputDevice);
+ return d->keyboard.data();
}
+/*!
+ * Returns the current focused surface for keyboard input.
+ */
QWaylandSurface *QWaylandInputDevice::keyboardFocus() const
{
- QtWayland::Surface *wlsurface = d->keyboardFocus();
- if (wlsurface)
- return wlsurface->waylandSurface();
- return 0;
+ Q_D(const QWaylandInputDevice);
+ if (d->keyboard.isNull() || !d->keyboard->focus())
+ return Q_NULLPTR;
+
+ return d->keyboard->focus();
}
+/*!
+ * Sets the current keyboard focus to \a surface.
+ */
bool QWaylandInputDevice::setKeyboardFocus(QWaylandSurface *surface)
{
- QtWayland::Surface *wlsurface = surface?surface->handle():0;
- return d->setKeyboardFocus(wlsurface);
+ Q_D(QWaylandInputDevice);
+ if (surface && surface->isDestroyed())
+ return false;
+
+ if (surface == keyboardFocus())
+ return true;
+
+ if (!d->keyboard.isNull() && d->keyboard->setFocus(surface)) {
+ if (d->data_device)
+ d->data_device->setFocus(d->keyboard->focusClient());
+ return true;
+ }
+ return false;
}
+/*!
+ * Sets the key map of this QWaylandInputDevice to \a keymap.
+ */
void QWaylandInputDevice::setKeymap(const QWaylandKeymap &keymap)
{
- if (handle()->keyboardDevice())
- handle()->keyboardDevice()->setKeymap(keymap);
+ if (keyboard())
+ keyboard()->setKeymap(keymap);
}
-QWaylandSurfaceView *QWaylandInputDevice::mouseFocus() const
+/*!
+ * Returns the pointer device for this QWaylandInputDevice.
+ */
+QWaylandPointer *QWaylandInputDevice::pointer() const
{
- return d->mouseFocus();
+ Q_D(const QWaylandInputDevice);
+ return d->pointer.data();
}
-void QWaylandInputDevice::setMouseFocus(QWaylandSurfaceView *surface, const QPointF &localPos, const QPointF &globalPos)
+/*!
+ * Returns the view that currently has mouse focus.
+ */
+QWaylandView *QWaylandInputDevice::mouseFocus() const
{
- d->setMouseFocus(surface,localPos,globalPos);
+ Q_D(const QWaylandInputDevice);
+ return d->mouseFocus;
}
+/*!
+ * Sets the current mouse focus to \a view.
+ */
+void QWaylandInputDevice::setMouseFocus(QWaylandView *view)
+{
+ Q_D(QWaylandInputDevice);
+ if (view == d->mouseFocus)
+ return;
+
+ QWaylandView *oldFocus = d->mouseFocus;
+ d->mouseFocus = view;
+ emit mouseFocusChanged(d->mouseFocus, oldFocus);
+}
+
+/*!
+ * Returns the compositor for this QWaylandInputDevice.
+ */
QWaylandCompositor *QWaylandInputDevice::compositor() const
{
- return d->compositor()->waylandCompositor();
+ Q_D(const QWaylandInputDevice);
+ return d->compositor;
}
-QtWayland::InputDevice *QWaylandInputDevice::handle() const
+/*!
+ * Returns the drag object for this QWaylandInputDevice.
+ */
+QWaylandDrag *QWaylandInputDevice::drag() const
{
- return d;
+ Q_D(const QWaylandInputDevice);
+ return d->drag_handle.data();
}
-QWaylandInputDevice::CapabilityFlags QWaylandInputDevice::capabilities()
+/*!
+ * Returns the capability flags for this QWaylandInputDevice.
+ */
+QWaylandInputDevice::CapabilityFlags QWaylandInputDevice::capabilities() const
{
- return d->capabilities();
+ Q_D(const QWaylandInputDevice);
+ return d->capabilities;
}
-bool QWaylandInputDevice::isOwner(QInputEvent *inputEvent)
+/*!
+ * \internal
+ */
+bool QWaylandInputDevice::isOwner(QInputEvent *inputEvent) const
{
Q_UNUSED(inputEvent);
return true;
}
+/*!
+ * Returns the QWaylandInputDevice corresponding to the \a resource. The \a resource is expected
+ * to have the type wl_seat.
+ */
+QWaylandInputDevice *QWaylandInputDevice::fromSeatResource(struct ::wl_resource *resource)
+{
+ return static_cast<QWaylandInputDevicePrivate *>(QWaylandInputDevicePrivate::Resource::fromResource(resource)->seat_object)->q_func();
+}
+
+/*!
+ * \fn void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus)
+ *
+ * This signal is emitted when the mouse focus has changed from \a oldFocus to \a newFocus.
+ */
+
QT_END_NAMESPACE