summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikko Levonmaa <mikko.levonmaa@lge.com>2014-09-18 12:32:57 +0300
committerMikko Levonmaa <mikko.levonmaa@lge.com>2014-10-06 07:53:53 +0200
commit0febf7c52f5cc4bc5c7767f7572ff87a5aa8a7af (patch)
tree4a7c5c0bea43b00722c3bd1c4dca6c0ac53fff04
parentb62ae0fd804633de07d68f2f5654d2373a83f8d7 (diff)
Allow client side input device customization
Introduces QWaylandInputDeviceIntegration plugins to allow customization of input device related behavior. The plugin can be activated via the environment variable QT_WAYLAND_INPUTDEVICE_INTEGRATION Change-Id: If5629737752afacb29161f51c1b7c6e171fb2758 Reviewed-by: Mikko Levonmaa <mikko.levonmaa@lge.com> Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com> Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com>
-rw-r--r--src/client/client.pro5
-rw-r--r--src/client/inputdeviceintegration/inputdeviceintegration.pri11
-rw-r--r--src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h64
-rw-r--r--src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory.cpp96
-rw-r--r--src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory_p.h61
-rw-r--r--src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin.cpp55
-rw-r--r--src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin_p.h69
-rw-r--r--src/client/qwaylanddisplay.cpp2
-rw-r--r--src/client/qwaylandinputdevice.cpp285
-rw-r--r--src/client/qwaylandinputdevice_p.h143
-rw-r--r--src/client/qwaylandintegration.cpp32
-rw-r--r--src/client/qwaylandintegration_p.h9
12 files changed, 654 insertions, 178 deletions
diff --git a/src/client/client.pro b/src/client/client.pro
index 6aaa25419..22271ee45 100644
--- a/src/client/client.pro
+++ b/src/client/client.pro
@@ -3,7 +3,9 @@ QT += core-private gui-private
QT_FOR_PRIVATE += platformsupport-private
MODULE=waylandclient
-MODULE_PLUGIN_TYPES = wayland-graphics-integration-client
+MODULE_PLUGIN_TYPES = \
+ wayland-graphics-integration-client \
+ wayland-inputdevice-integration
load(qt_module)
@@ -108,3 +110,4 @@ HEADERS += qwaylandintegration_p.h \
include(hardwareintegration/hardwareintegration.pri)
include(shellintegration/shellintegration.pri)
+include(inputdeviceintegration/inputdeviceintegration.pri)
diff --git a/src/client/inputdeviceintegration/inputdeviceintegration.pri b/src/client/inputdeviceintegration/inputdeviceintegration.pri
new file mode 100644
index 000000000..f16dfc3c9
--- /dev/null
+++ b/src/client/inputdeviceintegration/inputdeviceintegration.pri
@@ -0,0 +1,11 @@
+INCLUDEPATH += $$PWD
+
+SOURCES += \
+ $$PWD/qwaylandinputdeviceintegrationplugin.cpp \
+ $$PWD/qwaylandinputdeviceintegrationfactory.cpp
+
+HEADERS += \
+ $$PWD/qwaylandinputdeviceintegration_p.h \
+ $$PWD/qwaylandinputdeviceintegrationplugin_p.h \
+ $$PWD/qwaylandinputdeviceintegrationfactory_p.h
+
diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h b/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h
new file mode 100644
index 000000000..255a66854
--- /dev/null
+++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegration_p.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 LG Electronics Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDINPUTDEVICEINTEGRATION_H
+#define QWAYLANDINPUTDEVICEINTEGRATION_H
+
+#include <QtCore/qglobal.h>
+#include <QtWaylandClient/private/qwaylandclientexport_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandDisplay;
+class QWaylandInputDevice;
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDeviceIntegration
+{
+public:
+ QWaylandInputDeviceIntegration() {}
+ virtual ~QWaylandInputDeviceIntegration() {}
+
+ virtual QWaylandInputDevice *createInputDevice(QWaylandDisplay *d, uint32_t id) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDINPUTDEVICEINTEGRATION_H
diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory.cpp b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory.cpp
new file mode 100644
index 000000000..58a82fb2c
--- /dev/null
+++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 LG Electronics Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandinputdeviceintegrationfactory_p.h"
+#include "qwaylandinputdeviceintegrationplugin_p.h"
+#include "qwaylandinputdeviceintegration_p.h"
+#include <QtCore/private/qfactoryloader_p.h>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_LIBRARY
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
+ (QWaylandInputDeviceIntegrationFactoryInterface_iid, QLatin1String("/wayland-inputdevice-integration"), Qt::CaseInsensitive))
+Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
+ (QWaylandInputDeviceIntegrationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive))
+#endif
+
+QStringList QWaylandInputDeviceIntegrationFactory::keys(const QString &pluginPath)
+{
+#ifndef QT_NO_LIBRARY
+ QStringList list;
+ if (!pluginPath.isEmpty()) {
+ QCoreApplication::addLibraryPath(pluginPath);
+ list = directLoader()->keyMap().values();
+ if (!list.isEmpty()) {
+ const QString postFix = QStringLiteral(" (from ")
+ + QDir::toNativeSeparators(pluginPath)
+ + QLatin1Char(')');
+ const QStringList::iterator end = list.end();
+ for (QStringList::iterator it = list.begin(); it != end; ++it)
+ (*it).append(postFix);
+ }
+ }
+ list.append(loader()->keyMap().values());
+ return list;
+#else
+ return QStringList();
+#endif
+}
+
+QWaylandInputDeviceIntegration *QWaylandInputDeviceIntegrationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath)
+{
+#ifndef QT_NO_LIBRARY
+ // Try loading the plugin from platformPluginPath first:
+ if (!pluginPath.isEmpty()) {
+ QCoreApplication::addLibraryPath(pluginPath);
+ if (QWaylandInputDeviceIntegration *ret = qLoadPlugin1<QWaylandInputDeviceIntegration, QWaylandInputDeviceIntegrationPlugin>(directLoader(), name, args))
+ return ret;
+ }
+ if (QWaylandInputDeviceIntegration *ret = qLoadPlugin1<QWaylandInputDeviceIntegration, QWaylandInputDeviceIntegrationPlugin>(loader(), name, args))
+ return ret;
+#endif
+ return Q_NULLPTR;
+}
+
+QT_END_NAMESPACE
diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory_p.h b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory_p.h
new file mode 100644
index 000000000..13cddc24f
--- /dev/null
+++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationfactory_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 LG Electronics Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDINPUTDEVICEINTEGRATIONFACTORY_H
+#define QWAYLANDINPUTDEVICEINTEGRATIONFACTORY_H
+
+#include <QtWaylandClient/private/qwaylandclientexport_p.h>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandInputDeviceIntegration;
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDeviceIntegrationFactory
+{
+public:
+ static QStringList keys(const QString &pluginPath = QString());
+ static QWaylandInputDeviceIntegration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString());
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDINPUTDEVICENTEGRATIONFACTORY_H
diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin.cpp b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin.cpp
new file mode 100644
index 000000000..71a933254
--- /dev/null
+++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 LG Electronics Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandinputdeviceintegrationplugin_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QWaylandInputDeviceIntegrationPlugin::QWaylandInputDeviceIntegrationPlugin(QObject *parent)
+ : QObject(parent)
+{
+}
+
+QWaylandInputDeviceIntegrationPlugin::~QWaylandInputDeviceIntegrationPlugin()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin_p.h b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin_p.h
new file mode 100644
index 000000000..a0a062f4c
--- /dev/null
+++ b/src/client/inputdeviceintegration/qwaylandinputdeviceintegrationplugin_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 LG Electronics Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDINPUTDEVICEINTEGRATIONPLUGIN_H
+#define QWAYLANDINPUTDEVICEINTEGRATIONPLUGIN_H
+
+#include <QtWaylandClient/private/qwaylandclientexport_p.h>
+
+#include <QtCore/qplugin.h>
+#include <QtCore/qfactoryinterface.h>
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandInputDeviceIntegration;
+
+#define QWaylandInputDeviceIntegrationFactoryInterface_iid "org.qt-project.Qt.WaylandClient.QWaylandInputDeviceIntegrationFactoryInterface.5.3"
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDeviceIntegrationPlugin : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QWaylandInputDeviceIntegrationPlugin(QObject *parent = 0);
+ ~QWaylandInputDeviceIntegrationPlugin();
+
+ virtual QWaylandInputDeviceIntegration *create(const QString &key, const QStringList &paramList) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDINPUTDEVICEINTEGRATIONPLUGIN_H
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index edaac8fed..c4a702d74 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -241,7 +241,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
} else if (interface == QStringLiteral("wl_shell")){
mShell.reset(new QtWayland::wl_shell(registry, id, 1));
} else if (interface == QStringLiteral("wl_seat")) {
- QWaylandInputDevice *inputDevice = new QWaylandInputDevice(this, id);
+ QWaylandInputDevice *inputDevice = mWaylandIntegration->createInputDevice(this, id);
mInputDevices.append(inputDevice);
} else if (interface == QStringLiteral("wl_data_device_manager")) {
mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, id));
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
index 5198a9e31..4f72d6146 100644
--- a/src/client/qwaylandinputdevice.cpp
+++ b/src/client/qwaylandinputdevice.cpp
@@ -63,170 +63,99 @@
#include <QtGui/QGuiApplication>
-#ifndef QT_NO_WAYLAND_XKB
-#include <xkbcommon/xkbcommon.h>
-#include <xkbcommon/xkbcommon-keysyms.h>
-#endif
-
QT_BEGIN_NAMESPACE
-class QWaylandInputDevice::Keyboard : public QtWayland::wl_keyboard
-{
-public:
- Keyboard(QWaylandInputDevice *p)
- : mParent(p)
- , mFocus(0)
+QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p)
+ : mParent(p)
+ , mFocus(0)
#ifndef QT_NO_WAYLAND_XKB
- , mXkbContext(0)
- , mXkbMap(0)
- , mXkbState(0)
+ , mXkbContext(0)
+ , mXkbMap(0)
+ , mXkbState(0)
#endif
- , mFocusCallback(0)
- , mNativeModifiers(0)
- {
+ , mFocusCallback(0)
+ , mNativeModifiers(0)
+{
+ connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey()));
+}
+
#ifndef QT_NO_WAYLAND_XKB
- xkb_rule_names names;
- names.rules = strdup("evdev");
- names.model = strdup("pc105");
- names.layout = strdup("us");
- names.variant = strdup("");
- names.options = strdup("");
-
- mXkbContext = xkb_context_new(xkb_context_flags(0));
- if (mXkbContext) {
- mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0));
- if (mXkbMap) {
- mXkbState = xkb_state_new(mXkbMap);
- }
- }
+bool QWaylandInputDevice::Keyboard::createDefaultKeyMap()
+{
+ if (mXkbContext && mXkbMap && mXkbState) {
+ return true;
+ }
- if (!mXkbContext || !mXkbMap || !mXkbState)
- qWarning() << "xkb_map_new_from_names failed, no key input";
-#endif
+ xkb_rule_names names;
+ names.rules = strdup("evdev");
+ names.model = strdup("pc105");
+ names.layout = strdup("us");
+ names.variant = strdup("");
+ names.options = strdup("");
+
+ mXkbContext = xkb_context_new(xkb_context_flags(0));
+ if (mXkbContext) {
+ mXkbMap = xkb_map_new_from_names(mXkbContext, &names, xkb_map_compile_flags(0));
+ if (mXkbMap) {
+ mXkbState = xkb_state_new(mXkbMap);
+ }
}
- ~Keyboard()
- {
-#ifndef QT_NO_WAYLAND_XKB
- if (mXkbState)
- xkb_state_unref(mXkbState);
- if (mXkbMap)
- xkb_map_unref(mXkbMap);
- if (mXkbContext)
- xkb_context_unref(mXkbContext);
-#endif
- wl_keyboard_destroy(object());
+
+ if (!mXkbContext || !mXkbMap || !mXkbState) {
+ qWarning() << "xkb_map_new_from_names failed, no key input";
+ return false;
}
+ return true;
+}
- void keyboard_keymap(uint32_t format,
- int32_t fd,
- uint32_t size) Q_DECL_OVERRIDE;
- void keyboard_enter(uint32_t time,
- struct wl_surface *surface,
- struct wl_array *keys) Q_DECL_OVERRIDE;
- void keyboard_leave(uint32_t time,
- struct wl_surface *surface) Q_DECL_OVERRIDE;
- void keyboard_key(uint32_t serial, uint32_t time,
- uint32_t key, uint32_t state) Q_DECL_OVERRIDE;
- void keyboard_modifiers(uint32_t serial,
- uint32_t mods_depressed,
- uint32_t mods_latched,
- uint32_t mods_locked,
- uint32_t group) Q_DECL_OVERRIDE;
-
- QWaylandInputDevice *mParent;
- QWaylandWindow *mFocus;
-#ifndef QT_NO_WAYLAND_XKB
- xkb_context *mXkbContext;
- xkb_keymap *mXkbMap;
- xkb_state *mXkbState;
+void QWaylandInputDevice::Keyboard::releaseKeyMap()
+{
+ if (mXkbState)
+ xkb_state_unref(mXkbState);
+ if (mXkbMap)
+ xkb_map_unref(mXkbMap);
+ if (mXkbContext)
+ xkb_context_unref(mXkbContext);
+}
#endif
- struct wl_callback *mFocusCallback;
- uint32_t mNativeModifiers;
- int mRepeatKey;
- uint32_t mRepeatCode;
- uint32_t mRepeatTime;
- QString mRepeatText;
+QWaylandInputDevice::Keyboard::~Keyboard()
+{
#ifndef QT_NO_WAYLAND_XKB
- xkb_keysym_t mRepeatSym;
+ releaseKeyMap();
#endif
+ wl_keyboard_destroy(object());
+}
- static const wl_callback_listener callback;
- static void focusCallback(void *data, struct wl_callback *callback, uint32_t time);
-};
+void QWaylandInputDevice::Keyboard::stopRepeat()
+{
+ mRepeatTimer.stop();
+}
-class QWaylandInputDevice::Pointer : public QtWayland::wl_pointer
+QWaylandInputDevice::Pointer::Pointer(QWaylandInputDevice *p)
+ : mParent(p)
+ , mFocus(0)
+ , mEnterSerial(0)
+ , mCursorSerial(0)
+ , mButtons(0)
{
-public:
- Pointer(QWaylandInputDevice *p)
- : mParent(p)
- , mFocus(0)
- , mEnterSerial(0)
- , mCursorSerial(0)
- , mButtons(0)
- {
- }
- ~Pointer()
- {
- wl_pointer_destroy(object());
- }
+}
- void pointer_enter(uint32_t serial, struct wl_surface *surface,
- wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE;
- void pointer_leave(uint32_t time, struct wl_surface *surface);
- void pointer_motion(uint32_t time,
- wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE;
- void pointer_button(uint32_t serial, uint32_t time,
- uint32_t button, uint32_t state) Q_DECL_OVERRIDE;
- void pointer_axis(uint32_t time,
- uint32_t axis,
- wl_fixed_t value) Q_DECL_OVERRIDE;
-
- QWaylandInputDevice *mParent;
- QWaylandWindow *mFocus;
- uint32_t mEnterSerial;
- uint32_t mCursorSerial;
- QPointF mSurfacePos;
- QPointF mGlobalPos;
- Qt::MouseButtons mButtons;
-};
+QWaylandInputDevice::Pointer::~Pointer()
+{
+ wl_pointer_destroy(object());
+}
-class QWaylandInputDevice::Touch : public QtWayland::wl_touch
+QWaylandInputDevice::Touch::Touch(QWaylandInputDevice *p)
+ : mParent(p)
+ , mFocus(0)
{
-public:
- Touch(QWaylandInputDevice *p)
- : mParent(p)
- , mFocus(0)
- {
- }
- ~Touch()
- {
- wl_touch_destroy(object());
- }
+}
- void touch_down(uint32_t serial,
- uint32_t time,
- struct wl_surface *surface,
- int32_t id,
- wl_fixed_t x,
- wl_fixed_t y) Q_DECL_OVERRIDE;
- void touch_up(uint32_t serial,
- uint32_t time,
- int32_t id) Q_DECL_OVERRIDE;
- void touch_motion(uint32_t time,
- int32_t id,
- wl_fixed_t x,
- wl_fixed_t y) Q_DECL_OVERRIDE;
- void touch_frame() Q_DECL_OVERRIDE;
- void touch_cancel() Q_DECL_OVERRIDE;
-
- bool allTouchPointsReleased();
-
- QWaylandInputDevice *mParent;
- QWaylandWindow *mFocus;
- QList<QWindowSystemInterface::TouchPoint> mTouchPoints;
- QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints;
-};
+QWaylandInputDevice::Touch::~Touch()
+{
+ wl_touch_destroy(object());
+}
QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id)
: QObject()
@@ -246,7 +175,6 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, uint32_t id)
mDataDevice = mQDisplay->dndSelectionHandler()->getDataDevice(this);
}
- connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey()));
}
QWaylandInputDevice::~QWaylandInputDevice()
@@ -261,16 +189,15 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps)
mCaps = caps;
if (caps & WL_SEAT_CAPABILITY_KEYBOARD && !mKeyboard) {
- mKeyboard = new Keyboard(this);
+ mKeyboard = createKeyboard(this);
mKeyboard->init(get_keyboard());
} else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && mKeyboard) {
delete mKeyboard;
mKeyboard = 0;
- mRepeatTimer.stop();
}
if (caps & WL_SEAT_CAPABILITY_POINTER && !mPointer) {
- mPointer = new Pointer(this);
+ mPointer = createPointer(this);
mPointer->init(get_pointer());
pointerSurface = mQDisplay->createSurface(this);
} else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && mPointer) {
@@ -279,7 +206,7 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps)
}
if (caps & WL_SEAT_CAPABILITY_TOUCH && !mTouch) {
- mTouch = new Touch(this);
+ mTouch = createTouch(this);
mTouch->init(get_touch());
if (!mTouchDevice) {
@@ -294,13 +221,28 @@ void QWaylandInputDevice::seat_capabilities(uint32_t caps)
}
}
+QWaylandInputDevice::Keyboard *QWaylandInputDevice::createKeyboard(QWaylandInputDevice *device)
+{
+ return new Keyboard(device);
+}
+
+QWaylandInputDevice::Pointer *QWaylandInputDevice::createPointer(QWaylandInputDevice *device)
+{
+ return new Pointer(device);
+}
+
+QWaylandInputDevice::Touch *QWaylandInputDevice::createTouch(QWaylandInputDevice *device)
+{
+ return new Touch(device);
+}
+
void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
{
if (mPointer && window == mPointer->mFocus)
mPointer->mFocus = 0;
if (mKeyboard && window == mKeyboard->mFocus) {
mKeyboard->mFocus = 0;
- mRepeatTimer.stop();
+ mKeyboard->stopRepeat();
}
}
@@ -341,20 +283,25 @@ Qt::KeyboardModifiers QWaylandInputDevice::modifiers() const
if (!mKeyboard)
return Qt::NoModifier;
+ return mKeyboard->modifiers();
+}
+
+Qt::KeyboardModifiers QWaylandInputDevice::Keyboard::modifiers() const
+{
Qt::KeyboardModifiers ret = Qt::NoModifier;
#ifndef QT_NO_WAYLAND_XKB
xkb_state_component cstate = static_cast<xkb_state_component>(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED);
- if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Shift", cstate))
+ if (xkb_state_mod_name_is_active(mXkbState, "Shift", cstate))
ret |= Qt::ShiftModifier;
- if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Control", cstate))
+ if (xkb_state_mod_name_is_active(mXkbState, "Control", cstate))
ret |= Qt::ControlModifier;
- if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Alt", cstate))
+ if (xkb_state_mod_name_is_active(mXkbState, "Alt", cstate))
ret |= Qt::AltModifier;
- if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Mod1", cstate))
+ if (xkb_state_mod_name_is_active(mXkbState, "Mod1", cstate))
ret |= Qt::AltModifier;
- if (xkb_state_mod_name_is_active(mKeyboard->mXkbState, "Mod4", cstate))
+ if (xkb_state_mod_name_is_active(mXkbState, "Mod4", cstate))
ret |= Qt::MetaModifier;
#endif
@@ -682,6 +629,11 @@ void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd,
return;
}
+ // Release the old keymap resources in the case they were already created in
+ // the key event or when the compositor issues a new map
+ releaseKeyMap();
+
+ mXkbContext = xkb_context_new(xkb_context_flags(0));
mXkbMap = xkb_map_new_from_string(mXkbContext, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, (xkb_keymap_compile_flags)0);
munmap(map_str, size);
close(fd);
@@ -731,7 +683,7 @@ void QWaylandInputDevice::Keyboard::keyboard_leave(uint32_t time, struct wl_surf
mFocusCallback = wl_display_sync(mParent->mDisplay);
wl_callback_add_listener(mFocusCallback, &QWaylandInputDevice::Keyboard::callback, this);
}
- mParent->mRepeatTimer.stop();
+ mRepeatTimer.stop();
}
const wl_callback_listener QWaylandInputDevice::Keyboard::callback = {
@@ -769,8 +721,9 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time,
}
#ifndef QT_NO_WAYLAND_XKB
- if (!mXkbMap)
+ if (!createDefaultKeyMap()) {
return;
+ }
const xkb_keysym_t sym = xkb_state_key_get_one_sym(mXkbState, code);
xkb_state_update_key(mXkbState, code, isDown ? XKB_KEY_DOWN : XKB_KEY_UP);
@@ -807,26 +760,26 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time,
#ifndef QT_NO_WAYLAND_XKB
mRepeatSym = sym;
#endif
- mParent->mRepeatTimer.setInterval(400);
- mParent->mRepeatTimer.start();
+ mRepeatTimer.setInterval(400);
+ mRepeatTimer.start();
} else if (mRepeatCode == code) {
- mParent->mRepeatTimer.stop();
+ mRepeatTimer.stop();
}
}
-void QWaylandInputDevice::repeatKey()
+void QWaylandInputDevice::Keyboard::repeatKey()
{
mRepeatTimer.setInterval(25);
- QWindowSystemInterface::handleExtendedKeyEvent(mKeyboard->mFocus->window(),
- mKeyboard->mRepeatTime, QEvent::KeyPress, mKeyboard->mRepeatKey,
+ QWindowSystemInterface::handleExtendedKeyEvent(mFocus->window(),
+ mRepeatTime, QEvent::KeyPress, mRepeatKey,
modifiers(),
- mKeyboard->mRepeatCode,
+ mRepeatCode,
#ifndef QT_NO_WAYLAND_XKB
- mKeyboard->mRepeatSym, mKeyboard->mNativeModifiers,
+ mRepeatSym, mNativeModifiers,
#else
0, 0,
#endif
- mKeyboard->mRepeatText, true);
+ mRepeatText, true);
}
void QWaylandInputDevice::Keyboard::keyboard_modifiers(uint32_t serial,
diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h
index 23e1fc740..0c6ecfb64 100644
--- a/src/client/qwaylandinputdevice_p.h
+++ b/src/client/qwaylandinputdevice_p.h
@@ -56,15 +56,17 @@
#include <QtWaylandClient/private/qwayland-wayland.h>
#ifndef QT_NO_WAYLAND_XKB
-struct xkb_context;
-struct xkb_keymap;
-struct xkb_state;
+#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-keysyms.h>
#endif
+#include <QtCore/QDebug>
+
struct wl_cursor_image;
QT_BEGIN_NAMESPACE
+
class QWaylandWindow;
class QWaylandDisplay;
class QWaylandDataDevice;
@@ -75,6 +77,10 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice
{
Q_OBJECT
public:
+ class Keyboard;
+ class Pointer;
+ class Touch;
+
QWaylandInputDevice(QWaylandDisplay *display, uint32_t id);
~QWaylandInputDevice();
@@ -100,14 +106,11 @@ public:
uint32_t serial() const;
uint32_t cursorSerial() const;
-private slots:
- void repeatKey();
+ virtual Keyboard *createKeyboard(QWaylandInputDevice *device);
+ virtual Pointer *createPointer(QWaylandInputDevice *device);
+ virtual Touch *createTouch(QWaylandInputDevice *device);
private:
- class Keyboard;
- class Pointer;
- class Touch;
-
QWaylandDisplay *mQDisplay;
struct wl_display *mDisplay;
@@ -123,7 +126,6 @@ private:
uint32_t mTime;
uint32_t mSerial;
- QTimer mRepeatTimer;
void seat_capabilities(uint32_t caps) Q_DECL_OVERRIDE;
void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state);
@@ -139,6 +141,127 @@ inline uint32_t QWaylandInputDevice::serial() const
return mSerial;
}
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice::Keyboard : public QObject, public QtWayland::wl_keyboard
+{
+ Q_OBJECT
+
+public:
+ Keyboard(QWaylandInputDevice *p);
+ virtual ~Keyboard();
+
+ void stopRepeat();
+
+ void keyboard_keymap(uint32_t format,
+ int32_t fd,
+ uint32_t size) Q_DECL_OVERRIDE;
+ void keyboard_enter(uint32_t time,
+ struct wl_surface *surface,
+ struct wl_array *keys) Q_DECL_OVERRIDE;
+ void keyboard_leave(uint32_t time,
+ struct wl_surface *surface) Q_DECL_OVERRIDE;
+ void keyboard_key(uint32_t serial, uint32_t time,
+ uint32_t key, uint32_t state) Q_DECL_OVERRIDE;
+ void keyboard_modifiers(uint32_t serial,
+ uint32_t mods_depressed,
+ uint32_t mods_latched,
+ uint32_t mods_locked,
+ uint32_t group) Q_DECL_OVERRIDE;
+
+ QWaylandInputDevice *mParent;
+ QWaylandWindow *mFocus;
+#ifndef QT_NO_WAYLAND_XKB
+ xkb_context *mXkbContext;
+ xkb_keymap *mXkbMap;
+ xkb_state *mXkbState;
+#endif
+ struct wl_callback *mFocusCallback;
+ uint32_t mNativeModifiers;
+
+ int mRepeatKey;
+ uint32_t mRepeatCode;
+ uint32_t mRepeatTime;
+ QString mRepeatText;
+#ifndef QT_NO_WAYLAND_XKB
+ xkb_keysym_t mRepeatSym;
+#endif
+ QTimer mRepeatTimer;
+
+ static const wl_callback_listener callback;
+ static void focusCallback(void *data, struct wl_callback *callback, uint32_t time);
+
+ Qt::KeyboardModifiers modifiers() const;
+
+private slots:
+ void repeatKey();
+
+private:
+#ifndef QT_NO_WAYLAND_XKB
+ bool createDefaultKeyMap();
+ void releaseKeyMap();
+#endif
+
+};
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice::Pointer : public QtWayland::wl_pointer
+{
+
+public:
+ Pointer(QWaylandInputDevice *p);
+ virtual ~Pointer();
+
+ void pointer_enter(uint32_t serial, struct wl_surface *surface,
+ wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE;
+ void pointer_leave(uint32_t time, struct wl_surface *surface);
+ void pointer_motion(uint32_t time,
+ wl_fixed_t sx, wl_fixed_t sy) Q_DECL_OVERRIDE;
+ void pointer_button(uint32_t serial, uint32_t time,
+ uint32_t button, uint32_t state) Q_DECL_OVERRIDE;
+ void pointer_axis(uint32_t time,
+ uint32_t axis,
+ wl_fixed_t value) Q_DECL_OVERRIDE;
+
+ QWaylandInputDevice *mParent;
+ QWaylandWindow *mFocus;
+ uint32_t mEnterSerial;
+ uint32_t mCursorSerial;
+ QPointF mSurfacePos;
+ QPointF mGlobalPos;
+ Qt::MouseButtons mButtons;
+};
+
+class Q_WAYLAND_CLIENT_EXPORT QWaylandInputDevice::Touch : public QtWayland::wl_touch
+{
+public:
+ Touch(QWaylandInputDevice *p);
+ virtual ~Touch();
+
+ void touch_down(uint32_t serial,
+ uint32_t time,
+ struct wl_surface *surface,
+ int32_t id,
+ wl_fixed_t x,
+ wl_fixed_t y) Q_DECL_OVERRIDE;
+ void touch_up(uint32_t serial,
+ uint32_t time,
+ int32_t id) Q_DECL_OVERRIDE;
+ void touch_motion(uint32_t time,
+ int32_t id,
+ wl_fixed_t x,
+ wl_fixed_t y) Q_DECL_OVERRIDE;
+ void touch_frame() Q_DECL_OVERRIDE;
+ void touch_cancel() Q_DECL_OVERRIDE;
+
+ bool allTouchPointsReleased();
+
+ QWaylandInputDevice *mParent;
+ QWaylandWindow *mFocus;
+ QList<QWindowSystemInterface::TouchPoint> mTouchPoints;
+ QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints;
+};
+
+
+
QT_END_NAMESPACE
#endif
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
index d9bf82e4f..ad99c67b9 100644
--- a/src/client/qwaylandintegration.cpp
+++ b/src/client/qwaylandintegration.cpp
@@ -43,6 +43,7 @@
#include "qwaylanddisplay_p.h"
#include "qwaylandshmwindow_p.h"
+#include "qwaylandinputdevice_p.h"
#include "qwaylandinputcontext_p.h"
#include "qwaylandshmbackingstore_p.h"
#include "qwaylandnativeinterface_p.h"
@@ -76,6 +77,9 @@
#include "qwaylandshellintegration_p.h"
#include "qwaylandshellintegrationfactory_p.h"
+#include "qwaylandinputdeviceintegration_p.h"
+#include "qwaylandinputdeviceintegrationfactory_p.h"
+
QT_BEGIN_NAMESPACE
class GenericWaylandTheme: public QGenericUnixTheme
@@ -113,6 +117,7 @@ public:
QWaylandIntegration::QWaylandIntegration()
: mClientBufferIntegration(0)
, mShellIntegration(Q_NULLPTR)
+ , mInputDeviceIntegration(Q_NULLPTR)
, mFontDb(new QGenericUnixFontDatabase())
, mNativeInterface(new QWaylandNativeInterface(this))
#ifndef QT_NO_ACCESSIBILITY
@@ -124,6 +129,7 @@ QWaylandIntegration::QWaylandIntegration()
, mServerBufferIntegrationInitialized(false)
, mShellIntegrationInitialized(false)
{
+ initializeInputDeviceIntegration();
mDisplay = new QWaylandDisplay(this);
mClipboard = new QWaylandClipboard(mDisplay);
mDrag = new QWaylandDrag(mDisplay);
@@ -361,4 +367,30 @@ void QWaylandIntegration::initializeShellIntegration()
}
}
+QWaylandInputDevice *QWaylandIntegration::createInputDevice(QWaylandDisplay *display, uint32_t id)
+{
+ if (mInputDeviceIntegration) {
+ return mInputDeviceIntegration->createInputDevice(display, id);
+ }
+ return new QWaylandInputDevice(display, id);
+}
+
+void QWaylandIntegration::initializeInputDeviceIntegration()
+{
+ QByteArray integrationName = qgetenv("QT_WAYLAND_INPUTDEVICE_INTEGRATION");
+ QString targetKey = QString::fromLocal8Bit(integrationName);
+
+ if (targetKey.isEmpty()) {
+ return;
+ }
+
+ QStringList keys = QWaylandInputDeviceIntegrationFactory::keys();
+ if (keys.contains(targetKey)) {
+ mInputDeviceIntegration = QWaylandInputDeviceIntegrationFactory::create(targetKey, QStringList());
+ qDebug("Using the '%s' input device integration", qPrintable(targetKey));
+ } else {
+ qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h
index bbe982853..9741b1a78 100644
--- a/src/client/qwaylandintegration_p.h
+++ b/src/client/qwaylandintegration_p.h
@@ -52,6 +52,8 @@ class QWaylandDisplay;
class QWaylandClientBufferIntegration;
class QWaylandServerBufferIntegration;
class QWaylandShellIntegration;
+class QWaylandInputDeviceIntegration;
+class QWaylandInputDevice;
class Q_WAYLAND_CLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration
{
@@ -89,17 +91,24 @@ public:
QPlatformTheme *createPlatformTheme(const QString &name) const;
+ QWaylandInputDevice *createInputDevice(QWaylandDisplay *display, uint32_t id);
+
virtual QWaylandClientBufferIntegration *clientBufferIntegration() const;
virtual QWaylandServerBufferIntegration *serverBufferIntegration() const;
virtual QWaylandShellIntegration *shellIntegration() const;
+
protected:
QWaylandClientBufferIntegration *mClientBufferIntegration;
QWaylandServerBufferIntegration *mServerBufferIntegration;
QWaylandShellIntegration *mShellIntegration;
+ QWaylandInputDeviceIntegration *mInputDeviceIntegration;
+
private:
void initializeClientBufferIntegration();
void initializeServerBufferIntegration();
void initializeShellIntegration();
+ void initializeInputDeviceIntegration();
+
QPlatformFontDatabase *mFontDb;
QPlatformClipboard *mClipboard;
QPlatformDrag *mDrag;