summaryrefslogtreecommitdiffstats
path: root/src/plugins/generic
diff options
context:
space:
mode:
authorOleksandr Tymoshenko <gonzo@bluezbox.com>2016-06-16 22:54:43 -0700
committerOleksandr Tymoshenko <gonzo@bluezbox.com>2016-07-05 18:28:48 +0000
commitc9366c10bd2f1aef0c06866085383f1aff048009 (patch)
tree8327f44a3801a9fda917ae9d3cd3716b62b26c54 /src/plugins/generic
parent9a1af81ae12f1c642bdbb2aa6eb4ef7989590cdd (diff)
Added bsdmouse and bsdkeyboard input plugins for FreeBSD
bsdmouse implements basic and extended level of psm(4) protocol. On extended level only x and y coordinates are used. Plugin specification is device filename, default value is /dev/sysmouse. bsdkeyboard implements keyboard input for raw terminal mode. Plugin specification is device name, normally /dev/ttyv[0-9], if not provided STDIN file descriptor is used. [ChangeLog][Platform Specific Changes] Added bsdmouse and bsdkeyboard input plugins for FreeBSD. Change-Id: I3c7b6f5cc22b4f1e405d56efc8b7ef2daa1dac74 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src/plugins/generic')
-rw-r--r--src/plugins/generic/bsdkeyboard/bsdkeyboard.json3
-rw-r--r--src/plugins/generic/bsdkeyboard/bsdkeyboard.pro16
-rw-r--r--src/plugins/generic/bsdkeyboard/main.cpp59
-rw-r--r--src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp404
-rw-r--r--src/plugins/generic/bsdkeyboard/qbsdkeyboard.h139
-rw-r--r--src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h622
-rw-r--r--src/plugins/generic/bsdmouse/bsdmouse.json3
-rw-r--r--src/plugins/generic/bsdmouse/bsdmouse.pro16
-rw-r--r--src/plugins/generic/bsdmouse/main.cpp58
-rw-r--r--src/plugins/generic/bsdmouse/qbsdmouse.cpp161
-rw-r--r--src/plugins/generic/bsdmouse/qbsdmouse.h70
-rw-r--r--src/plugins/generic/generic.pro4
12 files changed, 1555 insertions, 0 deletions
diff --git a/src/plugins/generic/bsdkeyboard/bsdkeyboard.json b/src/plugins/generic/bsdkeyboard/bsdkeyboard.json
new file mode 100644
index 0000000000..46a8127c46
--- /dev/null
+++ b/src/plugins/generic/bsdkeyboard/bsdkeyboard.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "BsdKeyboard" ]
+}
diff --git a/src/plugins/generic/bsdkeyboard/bsdkeyboard.pro b/src/plugins/generic/bsdkeyboard/bsdkeyboard.pro
new file mode 100644
index 0000000000..c14c38c839
--- /dev/null
+++ b/src/plugins/generic/bsdkeyboard/bsdkeyboard.pro
@@ -0,0 +1,16 @@
+TARGET = qbsdkeyboardplugin
+
+PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
+PLUGIN_CLASS_NAME = QBsdKeyboardPlugin
+load(qt_plugin)
+
+QT += core gui-private
+
+HEADERS = qbsdkeyboard.h
+SOURCES = main.cpp \
+ qbsdkeyboard.cpp
+
+OTHER_FILES += \
+ qbsdkeyboard.json
+
diff --git a/src/plugins/generic/bsdkeyboard/main.cpp b/src/plugins/generic/bsdkeyboard/main.cpp
new file mode 100644
index 0000000000..f48af0ae28
--- /dev/null
+++ b/src/plugins/generic/bsdkeyboard/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qgenericplugin.h>
+#include "qbsdkeyboard.h"
+
+QT_BEGIN_NAMESPACE
+
+class QBsdKeyboardPlugin : public QGenericPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "bsdkeyboard.json")
+
+public:
+ QObject *create(const QString &key, const QString &specification) override;
+};
+
+QObject *QBsdKeyboardPlugin::create(const QString &key,
+ const QString &specification)
+{
+ if (!key.compare(QLatin1String("BsdKeyboard"), Qt::CaseInsensitive))
+ return new QBsdKeyboardHandler(key, specification);
+
+ return nullptr;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp b/src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp
new file mode 100644
index 0000000000..3814563eef
--- /dev/null
+++ b/src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbsdkeyboard.h"
+
+#include <QByteArray>
+#include <QFile>
+#include <QGuiApplication>
+#include <QPoint>
+#include <QSocketNotifier>
+#include <QString>
+#include <QStringList>
+
+#include <QtCore/qglobal.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <private/qcore_unix_p.h>
+
+#include <qdebug.h>
+#include <cstdio>
+
+#include <cerrno>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <termios.h>
+#include <sys/kbio.h>
+
+// #define QT_BSD_KEYBOARD_DEBUG
+
+#ifdef QT_BSD_KEYBOARD_DEBUG
+#include <qdebug.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ Bsd_KeyCodeMask = 0x7f,
+ Bsd_KeyPressedMask = 0x80
+};
+
+#include "qbsdkeyboard_defaultmap.h"
+
+QBsdKeyboardHandler::QBsdKeyboardHandler(const QString &key, const QString &specification)
+{
+ Q_UNUSED(key);
+
+ setObjectName(QLatin1String("BSD Keyboard Handler"));
+
+ QByteArray device;
+ if (specification.startsWith("/dev/"))
+ device = QFile::encodeName(specification);
+
+ if (device.isEmpty()) {
+ device = QByteArrayLiteral("STDIN");
+ m_fd = fileno(stdin);
+ }
+ else {
+ m_fd = QT_OPEN(device.constData(), O_RDONLY);
+ if (!m_fd) {
+ qErrnoWarning(errno, "open(%s) failed", device.constData());
+ return;
+ }
+ m_shouldClose = true;
+ }
+
+ if (ioctl(m_fd, KDGKBMODE, &m_origKbdMode)) {
+ qErrnoWarning(errno, "ioctl(%s, KDGKBMODE) failed", device.constData());
+ revertTTYSettings();
+ return;
+ }
+
+ if (ioctl(m_fd, KDSKBMODE, K_CODE) < 0) {
+ qErrnoWarning(errno, "ioctl(%s, KDSKBMODE) failed", device.constData());
+ revertTTYSettings();
+ return;
+ }
+
+ termios kbdtty;
+ if (tcgetattr(m_fd, &kbdtty) == 0) {
+
+ m_kbdOrigTty.reset(new termios);
+ *m_kbdOrigTty = kbdtty;
+
+ kbdtty.c_iflag = IGNPAR | IGNBRK;
+ kbdtty.c_oflag = 0;
+ kbdtty.c_cflag = CREAD | CS8;
+ kbdtty.c_lflag = 0;
+ kbdtty.c_cc[VTIME] = 0;
+ kbdtty.c_cc[VMIN] = 0;
+ cfsetispeed(&kbdtty, 9600);
+ cfsetospeed(&kbdtty, 9600);
+ if (tcsetattr(m_fd, TCSANOW, &kbdtty) < 0) {
+ qErrnoWarning(errno, "tcsetattr(%s) failed", device.constData());
+
+ // TTY is still at old settings so we can
+ // dispose of original termios data
+ m_kbdOrigTty.reset();
+
+ revertTTYSettings();
+ return;
+ }
+ } else {
+ qErrnoWarning(errno, "tcgetattr(%s) failed", device.constData());
+ revertTTYSettings();
+ return;
+ }
+
+ if (fcntl(m_fd, F_SETFL, O_NONBLOCK)) {
+ qErrnoWarning(errno, "fcntl(%s, F_SETFL, O_NONBLOCK) failed", device.constData());
+ revertTTYSettings();
+ return;
+ }
+
+ resetKeymap();
+
+ m_notifier.reset(new QSocketNotifier(m_fd, QSocketNotifier::Read, this));
+ connect(m_notifier.data(), &QSocketNotifier::activated, this, &QBsdKeyboardHandler::readKeyboardData);
+}
+
+QBsdKeyboardHandler::~QBsdKeyboardHandler()
+{
+ revertTTYSettings();
+}
+
+void QBsdKeyboardHandler::revertTTYSettings()
+{
+ if (m_fd >= 0) {
+ if (m_kbdOrigTty) {
+ tcsetattr(m_fd, TCSANOW, m_kbdOrigTty.data());
+ m_kbdOrigTty.reset();
+ }
+
+ if (m_origKbdMode != Bsd_NoKeyMode) {
+ ioctl(m_fd, KDSKBMODE, m_origKbdMode);
+ m_origKbdMode = Bsd_NoKeyMode;
+ }
+
+ if (m_shouldClose)
+ close(m_fd);
+ m_fd = -1;
+ }
+}
+
+void QBsdKeyboardHandler::readKeyboardData()
+{
+
+ for (;;) {
+ uint8_t buffer[32];
+ int bytesRead = qt_safe_read(m_fd, buffer, sizeof(buffer));
+
+ if (!bytesRead) {
+ qWarning("Got EOF from the input device.");
+ return;
+ } else if (bytesRead < 0) {
+ if (errno != EINTR && errno != EAGAIN)
+ qWarning("Could not read from input device: %s", strerror(errno));
+ return;
+ }
+
+ for (int i = 0; i < bytesRead; ++i) {
+ const quint16 code = buffer[i] & Bsd_KeyCodeMask;
+ const bool pressed = (buffer[i] & Bsd_KeyPressedMask) ? false : true;
+
+ processKeycode(code, pressed, false);
+ }
+ }
+}
+
+void QBsdKeyboardHandler::processKeyEvent(int nativecode, int unicode, int qtcode,
+ Qt::KeyboardModifiers modifiers, bool isPress,
+ bool autoRepeat)
+{
+ const QString text = (unicode != 0xffff ) ? QString(unicode) : QString();
+ const QEvent::Type eventType = isPress ? QEvent::KeyPress : QEvent::KeyRelease;
+
+ QWindowSystemInterface::handleExtendedKeyEvent(0, eventType, qtcode, modifiers, nativecode, 0,
+ int(modifiers), text, autoRepeat);
+}
+
+void QBsdKeyboardHandler::processKeycode(quint16 keycode, bool pressed, bool autorepeat)
+{
+ const bool first_press = pressed && !autorepeat;
+
+ const QBsdKeyboardMap::Mapping *map_plain = nullptr;
+ const QBsdKeyboardMap::Mapping *map_withmod = nullptr;
+
+ quint8 modifiers = m_modifiers;
+
+ // get a specific and plain mapping for the keycode and the current modifiers
+ for (const QBsdKeyboardMap::Mapping &m : m_keymap) {
+ if (m.keycode == keycode) {
+ if (m.modifiers == 0)
+ map_plain = &m;
+
+ quint8 testmods = m_modifiers;
+ if (m_capsLock && (m.flags & QBsdKeyboardMap::IsLetter))
+ testmods ^= QBsdKeyboardMap::ModShift;
+ if (m.modifiers == testmods)
+ map_withmod = &m;
+ }
+ }
+
+ if (m_capsLock && map_withmod && (map_withmod->flags & QBsdKeyboardMap::IsLetter))
+ modifiers ^= QBsdKeyboardMap::ModShift;
+
+#ifdef QT_BSD_KEYBOARD_DEBUG
+ qWarning("Processing key event: keycode=%3d, modifiers=%02x pressed=%d, autorepeat=%d", \
+ keycode, modifiers, pressed ? 1 : 0, autorepeat ? 1 : 0);
+#endif
+
+ const QBsdKeyboardMap::Mapping *it = map_withmod ? map_withmod : map_plain;
+
+ if (!it) {
+#ifdef QT_BSD_KEYBOARD_DEBUG
+ // we couldn't even find a plain mapping
+ qWarning("Could not find a suitable mapping for keycode: %3d, modifiers: %02x", keycode, modifiers);
+#endif
+ return;
+ }
+
+ bool skip = false;
+ quint16 unicode = it->unicode;
+ quint32 qtcode = it->qtcode;
+
+ if ((it->flags & QBsdKeyboardMap::IsModifier) && it->special) {
+ // this is a modifier, i.e. Shift, Alt, ...
+ if (pressed)
+ m_modifiers |= quint8(it->special);
+ else
+ m_modifiers &= ~quint8(it->special);
+ } else if (qtcode >= Qt::Key_CapsLock && qtcode <= Qt::Key_ScrollLock) {
+ // (Caps|Num|Scroll)Lock
+ if (first_press) {
+ switch (qtcode) {
+ case Qt::Key_CapsLock:
+ m_capsLock = !m_capsLock;
+ switchLed(LED_CAP, m_capsLock);
+ break;
+ case Qt::Key_NumLock:
+ m_numLock = !m_numLock;
+ switchLed(LED_NUM, m_numLock);
+ break;
+ case Qt::Key_ScrollLock:
+ m_scrollLock = !m_scrollLock;
+ switchLed(LED_SCR, m_scrollLock);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (!skip) {
+ // a normal key was pressed
+ const int modmask = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier
+ | Qt::MetaModifier | Qt::KeypadModifier;
+
+ // we couldn't find a specific mapping for the current modifiers,
+ // or that mapping didn't have special modifiers:
+ // so just report the plain mapping with additional modifiers.
+ if ((it == map_plain && it != map_withmod) ||
+ (map_withmod && !(map_withmod->qtcode & modmask))) {
+ qtcode |= QBsdKeyboardHandler::toQtModifiers(modifiers);
+ }
+
+#ifdef QT_BSD_KEYBOARD_DEBUG
+ qWarning("Processing: uni=%04x, qt=%08x, qtmod=%08x", unicode, qtcode & ~modmask, (qtcode & modmask));
+#endif
+ //If NumLockOff and keypad key pressed remap event sent
+ if (!m_numLock &&
+ (qtcode & Qt::KeypadModifier)) {
+ unicode = 0xffff;
+ const int oldMask = (qtcode & modmask);
+ switch (qtcode & ~modmask) {
+ case Qt::Key_7: //7 --> Home
+ qtcode = Qt::Key_Home;
+ break;
+ case Qt::Key_8: //8 --> Up
+ qtcode = Qt::Key_Up;
+ break;
+ case Qt::Key_9: //9 --> PgUp
+ qtcode = Qt::Key_PageUp;
+ break;
+ case Qt::Key_4: //4 --> Left
+ qtcode = Qt::Key_Left;
+ break;
+ case Qt::Key_5: //5 --> Clear
+ qtcode = Qt::Key_Clear;
+ break;
+ case Qt::Key_6: //6 --> right
+ qtcode = Qt::Key_Right;
+ break;
+ case Qt::Key_1: //1 --> End
+ qtcode = Qt::Key_End;
+ break;
+ case Qt::Key_2: //2 --> Down
+ qtcode = Qt::Key_Down;
+ break;
+ case Qt::Key_3: //3 --> PgDn
+ qtcode = Qt::Key_PageDown;
+ break;
+ case Qt::Key_0: //0 --> Ins
+ qtcode = Qt::Key_Insert;
+ break;
+ case Qt::Key_Period: //. --> Del
+ qtcode = Qt::Key_Delete;
+ break;
+ }
+ qtcode |= oldMask;
+ }
+
+ // send the result to the server
+ processKeyEvent(keycode, unicode, qtcode & ~modmask,
+ Qt::KeyboardModifiers(qtcode & modmask), pressed, autorepeat);
+ }
+}
+
+void QBsdKeyboardHandler::switchLed(int led, bool state)
+{
+#ifdef QT_BSD_KEYBOARD_DEBUG
+ qWarning() << "switchLed" << led << state;
+#endif
+ int leds = 0;
+ if (ioctl(m_fd, KDGETLED, &leds) < 0) {
+ qWarning("switchLed: Failed to query led states.");
+ return;
+ }
+
+ if (state)
+ leds |= led;
+ else
+ leds &= ~led;
+
+ if (ioctl(m_fd, KDSETLED, leds) < 0)
+ qWarning("switchLed: Failed to set led states.");
+}
+
+void QBsdKeyboardHandler::resetKeymap()
+{
+#ifdef QT_BSD_KEYBOARD_DEBUG
+ qWarning() << "Unload current keymap and restore built-in";
+#endif
+
+ m_keymap.clear();
+
+ const size_t mappingSize = sizeof(keymapDefault) / sizeof(keymapDefault[0]);
+ m_keymap.resize(mappingSize);
+ std::copy_n( &keymapDefault[0], mappingSize, m_keymap.begin() );
+
+ // reset state, so we could switch keymaps at runtime
+ m_modifiers = 0;
+ m_capsLock = false;
+ m_numLock = false;
+ m_scrollLock = false;
+
+ //Set locks according to keyboard leds
+ int leds = 0;
+ if (ioctl(m_fd, KDGETLED, &leds) < 0) {
+ qWarning("Failed to query led states. Settings numlock & capslock off");
+ switchLed(LED_NUM, false);
+ switchLed(LED_CAP, false);
+ switchLed(LED_SCR, false);
+ } else {
+ if ((leds & LED_CAP) > 0)
+ m_capsLock = true;
+ if ((leds & LED_NUM) > 0)
+ m_numLock = true;
+ if ((leds & LED_SCR) > 0)
+ m_scrollLock = true;
+#ifdef QT_BSD_KEYBOARD_DEBUG
+ qWarning("numlock=%d , capslock=%d, scrolllock=%d",m_numLock, m_capsLock, m_scrollLock);
+#endif
+ }
+}
diff --git a/src/plugins/generic/bsdkeyboard/qbsdkeyboard.h b/src/plugins/generic/bsdkeyboard/qbsdkeyboard.h
new file mode 100644
index 0000000000..1a7cbc1f9a
--- /dev/null
+++ b/src/plugins/generic/bsdkeyboard/qbsdkeyboard.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBSDKEYBOARD_H
+#define QBSDKEYBOARD_H
+
+#include <qobject.h>
+#include <QDataStream>
+#include <QVector>
+
+QT_BEGIN_NAMESPACE
+
+class QSocketNotifier;
+
+struct termios;
+
+enum {
+ Bsd_NoKeyMode = -1
+};
+
+namespace QBsdKeyboardMap {
+ const quint32 FileMagic = 0x514d4150; // 'QMAP'
+
+ struct Mapping {
+ quint16 keycode;
+ quint16 unicode;
+ quint32 qtcode;
+ quint8 modifiers;
+ quint8 flags;
+ quint16 special;
+
+ };
+
+ enum Flags {
+ NoFlags = 0x00,
+ IsLetter = 0x01,
+ IsModifier = 0x02
+ };
+
+ enum Modifiers {
+ ModPlain = 0x00,
+ ModShift = 0x01,
+ ModAltGr = 0x02,
+ ModControl = 0x04,
+ ModAlt = 0x08,
+ ModShiftL = 0x10,
+ ModShiftR = 0x20,
+ ModCtrlL = 0x40,
+ ModCtrlR = 0x80
+ // ModCapsShift = 0x100, // not supported!
+ };
+}
+
+inline QDataStream &operator>>(QDataStream &ds, QBsdKeyboardMap::Mapping &m)
+{
+ return ds >> m.keycode >> m.unicode >> m.qtcode >> m.modifiers >> m.flags >> m.special;
+}
+
+class QBsdKeyboardHandler : public QObject
+{
+ Q_OBJECT
+
+public:
+ QBsdKeyboardHandler(const QString &key, const QString &specification);
+ ~QBsdKeyboardHandler() override;
+
+ static Qt::KeyboardModifiers toQtModifiers(quint8 mod)
+ {
+ Qt::KeyboardModifiers qtmod = Qt::NoModifier;
+
+ if (mod & (QBsdKeyboardMap::ModShift | QBsdKeyboardMap::ModShiftL | QBsdKeyboardMap::ModShiftR))
+ qtmod |= Qt::ShiftModifier;
+ if (mod & (QBsdKeyboardMap::ModControl | QBsdKeyboardMap::ModCtrlL | QBsdKeyboardMap::ModCtrlR))
+ qtmod |= Qt::ControlModifier;
+ if (mod & QBsdKeyboardMap::ModAlt)
+ qtmod |= Qt::AltModifier;
+
+ return qtmod;
+ }
+
+protected:
+ void switchLed(int led, bool state);
+ void processKeycode(quint16 keycode, bool pressed, bool autorepeat);
+ void processKeyEvent(int nativecode, int unicode, int qtcode,
+ Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat);
+ void revertTTYSettings();
+ void resetKeymap();
+ void readKeyboardData();
+
+private:
+ QScopedPointer<QSocketNotifier> m_notifier;
+ QScopedPointer<termios> m_kbdOrigTty;
+ int m_origKbdMode = Bsd_NoKeyMode;
+ int m_fd = -1;
+ bool m_shouldClose = false;
+ QString m_spec;
+
+ // keymap handling
+ quint8 m_modifiers = 0;
+ bool m_capsLock = false;
+ bool m_numLock = false;
+ bool m_scrollLock = false;
+
+ QVector<QBsdKeyboardMap::Mapping> m_keymap;
+};
+
+QT_END_NAMESPACE
+
+#endif // QBSDKEYBOARD_H
diff --git a/src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h b/src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h
new file mode 100644
index 0000000000..45cf5944bc
--- /dev/null
+++ b/src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h
@@ -0,0 +1,622 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBSDKEYBOARD_DEFAULTMAP_P_H
+#define QBSDKEYBOARD_DEFAULTMAP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qnamespace.h"
+
+// no QT_BEGIN_NAMESPACE, since we include it internally...
+using namespace QBsdKeyboardMap;
+
+#define QCTRL(x) ((x) | Qt::ControlModifier)
+#define QALT(x) ((x) | Qt::AltModifier)
+#define QKEYPAD(x) ((x) | Qt::KeypadModifier)
+
+const QBsdKeyboardMap::Mapping keymapDefault[] = {
+ { 1, 0xffff, Qt::Key_Escape, ModPlain, NoFlags, 0x0000 },
+ { 2, 0x0031, Qt::Key_1, ModPlain, NoFlags, 0x0000 },
+ { 2, 0x0021, Qt::Key_Exclam, ModShift, NoFlags, 0x0000 },
+ { 3, 0x0032, Qt::Key_2, ModPlain, NoFlags, 0x0000 },
+ { 3, 0x0040, Qt::Key_At, ModShift, NoFlags, 0x0000 },
+ { 3, 0x0040, Qt::Key_At, ModAltGr, NoFlags, 0x0000 },
+ { 4, 0x0033, Qt::Key_3, ModPlain, NoFlags, 0x0000 },
+ { 4, 0x0023, Qt::Key_NumberSign, ModShift, NoFlags, 0x0000 },
+ { 4, 0xffff, Qt::Key_Escape, ModControl, NoFlags, 0x0000 },
+ { 5, 0x0034, Qt::Key_4, ModPlain, NoFlags, 0x0000 },
+ { 5, 0x0024, Qt::Key_Dollar, ModShift, NoFlags, 0x0000 },
+ { 5, 0x0024, Qt::Key_Dollar, ModAltGr, NoFlags, 0x0000 },
+ { 5, 0x005c, QCTRL(Qt::Key_Backslash), ModControl, NoFlags, 0x0000 },
+ { 6, 0x0035, Qt::Key_5, ModPlain, NoFlags, 0x0000 },
+ { 6, 0x0025, Qt::Key_Percent, ModShift, NoFlags, 0x0000 },
+ { 6, 0x005d, QCTRL(Qt::Key_BracketRight), ModControl, NoFlags, 0x0000 },
+ { 7, 0x0036, Qt::Key_6, ModPlain, NoFlags, 0x0000 },
+ { 7, 0x005e, Qt::Key_AsciiCircum, ModShift, NoFlags, 0x0000 },
+ { 7, 0x005e, QCTRL(Qt::Key_AsciiCircum), ModControl, NoFlags, 0x0000 },
+ { 8, 0x0037, Qt::Key_7, ModPlain, NoFlags, 0x0000 },
+ { 8, 0x0026, Qt::Key_Ampersand, ModShift, NoFlags, 0x0000 },
+ { 8, 0x007b, Qt::Key_BraceLeft, ModAltGr, NoFlags, 0x0000 },
+ { 8, 0x005f, QCTRL(Qt::Key_Underscore), ModControl, NoFlags, 0x0000 },
+ { 9, 0x0038, Qt::Key_8, ModPlain, NoFlags, 0x0000 },
+ { 9, 0x002a, Qt::Key_Asterisk, ModShift, NoFlags, 0x0000 },
+ { 9, 0x005b, Qt::Key_BracketLeft, ModAltGr, NoFlags, 0x0000 },
+ { 9, 0xffff, Qt::Key_Backspace, ModControl, NoFlags, 0x0000 },
+ { 10, 0x0039, Qt::Key_9, ModPlain, NoFlags, 0x0000 },
+ { 10, 0x0028, Qt::Key_ParenLeft, ModShift, NoFlags, 0x0000 },
+ { 10, 0x005d, Qt::Key_BracketRight, ModAltGr, NoFlags, 0x0000 },
+ { 11, 0x0030, Qt::Key_0, ModPlain, NoFlags, 0x0000 },
+ { 11, 0x0029, Qt::Key_ParenRight, ModShift, NoFlags, 0x0000 },
+ { 11, 0x007d, Qt::Key_BraceRight, ModAltGr, NoFlags, 0x0000 },
+ { 12, 0x002d, Qt::Key_Minus, ModPlain, NoFlags, 0x0000 },
+ { 12, 0x005f, Qt::Key_Underscore, ModShift, NoFlags, 0x0000 },
+ { 12, 0x005c, Qt::Key_Backslash, ModAltGr, NoFlags, 0x0000 },
+ { 12, 0x005f, QCTRL(Qt::Key_Underscore), ModControl, NoFlags, 0x0000 },
+ { 12, 0x005f, QCTRL(Qt::Key_Underscore), ModShift | ModControl, NoFlags, 0x0000 },
+ { 13, 0x003d, Qt::Key_Equal, ModPlain, NoFlags, 0x0000 },
+ { 13, 0x002b, Qt::Key_Plus, ModShift, NoFlags, 0x0000 },
+ { 14, 0xffff, Qt::Key_Backspace, ModPlain, NoFlags, 0x0000 },
+ { 15, 0xffff, Qt::Key_Tab, ModPlain, NoFlags, 0x0000 },
+ { 16, 0x0071, Qt::Key_Q, ModPlain, IsLetter, 0x0000 },
+ { 16, 0x0051, Qt::Key_Q, ModShift, IsLetter, 0x0000 },
+ { 16, 0x0071, Qt::Key_Q, ModAltGr, IsLetter, 0x0000 },
+ { 16, 0x0051, Qt::Key_Q, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 16, 0x0071, QCTRL(Qt::Key_Q), ModControl, IsLetter, 0x0000 },
+ { 16, 0x0071, QCTRL(Qt::Key_Q), ModShift | ModControl, IsLetter, 0x0000 },
+ { 16, 0x0071, QCTRL(Qt::Key_Q), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 16, 0x0071, QCTRL(Qt::Key_Q), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 16, 0x0071, QALT(Qt::Key_Q), ModAlt, IsLetter, 0x0000 },
+ { 16, 0x0071, QALT(Qt::Key_Q), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 16, 0x0071, QALT(Qt::Key_Q), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 16, 0x0071, QALT(Qt::Key_Q), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 16, 0x0071, QCTRL(QALT(Qt::Key_Q)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 16, 0x0071, QCTRL(QALT(Qt::Key_Q)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 16, 0x0071, QCTRL(QALT(Qt::Key_Q)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 16, 0x0071, QCTRL(QALT(Qt::Key_Q)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 17, 0x0077, Qt::Key_W, ModPlain, IsLetter, 0x0000 },
+ { 17, 0x0057, Qt::Key_W, ModShift, IsLetter, 0x0000 },
+ { 17, 0x0077, Qt::Key_W, ModAltGr, IsLetter, 0x0000 },
+ { 17, 0x0057, Qt::Key_W, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 17, 0x0077, QCTRL(Qt::Key_W), ModControl, IsLetter, 0x0000 },
+ { 17, 0x0077, QCTRL(Qt::Key_W), ModShift | ModControl, IsLetter, 0x0000 },
+ { 17, 0x0077, QCTRL(Qt::Key_W), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 17, 0x0077, QCTRL(Qt::Key_W), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 17, 0x0077, QALT(Qt::Key_W), ModAlt, IsLetter, 0x0000 },
+ { 17, 0x0077, QALT(Qt::Key_W), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 17, 0x0077, QALT(Qt::Key_W), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 17, 0x0077, QALT(Qt::Key_W), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 17, 0x0077, QCTRL(QALT(Qt::Key_W)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 17, 0x0077, QCTRL(QALT(Qt::Key_W)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 17, 0x0077, QCTRL(QALT(Qt::Key_W)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 17, 0x0077, QCTRL(QALT(Qt::Key_W)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 18, 0x0065, Qt::Key_E, ModPlain, IsLetter, 0x0000 },
+ { 18, 0x0045, Qt::Key_E, ModShift, IsLetter, 0x0000 },
+ { 18, 0x0065, Qt::Key_E, ModAltGr, IsLetter, 0x0000 },
+ { 18, 0x0045, Qt::Key_E, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 18, 0x0065, QCTRL(Qt::Key_E), ModControl, IsLetter, 0x0000 },
+ { 18, 0x0065, QCTRL(Qt::Key_E), ModShift | ModControl, IsLetter, 0x0000 },
+ { 18, 0x0065, QCTRL(Qt::Key_E), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 18, 0x0065, QCTRL(Qt::Key_E), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 18, 0x0065, QALT(Qt::Key_E), ModAlt, IsLetter, 0x0000 },
+ { 18, 0x0065, QALT(Qt::Key_E), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 18, 0x0065, QALT(Qt::Key_E), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 18, 0x0065, QALT(Qt::Key_E), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 18, 0x0065, QCTRL(QALT(Qt::Key_E)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 18, 0x0065, QCTRL(QALT(Qt::Key_E)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 18, 0x0065, QCTRL(QALT(Qt::Key_E)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 18, 0x0065, QCTRL(QALT(Qt::Key_E)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 19, 0x0072, Qt::Key_R, ModPlain, IsLetter, 0x0000 },
+ { 19, 0x0052, Qt::Key_R, ModShift, IsLetter, 0x0000 },
+ { 19, 0x0072, Qt::Key_R, ModAltGr, IsLetter, 0x0000 },
+ { 19, 0x0052, Qt::Key_R, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 19, 0x0072, QCTRL(Qt::Key_R), ModControl, IsLetter, 0x0000 },
+ { 19, 0x0072, QCTRL(Qt::Key_R), ModShift | ModControl, IsLetter, 0x0000 },
+ { 19, 0x0072, QCTRL(Qt::Key_R), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 19, 0x0072, QCTRL(Qt::Key_R), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 19, 0x0072, QALT(Qt::Key_R), ModAlt, IsLetter, 0x0000 },
+ { 19, 0x0072, QALT(Qt::Key_R), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 19, 0x0072, QALT(Qt::Key_R), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 19, 0x0072, QALT(Qt::Key_R), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 19, 0x0072, QCTRL(QALT(Qt::Key_R)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 19, 0x0072, QCTRL(QALT(Qt::Key_R)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 19, 0x0072, QCTRL(QALT(Qt::Key_R)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 19, 0x0072, QCTRL(QALT(Qt::Key_R)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 20, 0x0074, Qt::Key_T, ModPlain, IsLetter, 0x0000 },
+ { 20, 0x0054, Qt::Key_T, ModShift, IsLetter, 0x0000 },
+ { 20, 0x0074, Qt::Key_T, ModAltGr, IsLetter, 0x0000 },
+ { 20, 0x0054, Qt::Key_T, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 20, 0x0074, QCTRL(Qt::Key_T), ModControl, IsLetter, 0x0000 },
+ { 20, 0x0074, QCTRL(Qt::Key_T), ModShift | ModControl, IsLetter, 0x0000 },
+ { 20, 0x0074, QCTRL(Qt::Key_T), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 20, 0x0074, QCTRL(Qt::Key_T), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 20, 0x0074, QALT(Qt::Key_T), ModAlt, IsLetter, 0x0000 },
+ { 20, 0x0074, QALT(Qt::Key_T), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 20, 0x0074, QALT(Qt::Key_T), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 20, 0x0074, QALT(Qt::Key_T), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 20, 0x0074, QCTRL(QALT(Qt::Key_T)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 20, 0x0074, QCTRL(QALT(Qt::Key_T)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 20, 0x0074, QCTRL(QALT(Qt::Key_T)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 20, 0x0074, QCTRL(QALT(Qt::Key_T)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 21, 0x0079, Qt::Key_Y, ModPlain, IsLetter, 0x0000 },
+ { 21, 0x0059, Qt::Key_Y, ModShift, IsLetter, 0x0000 },
+ { 21, 0x0079, Qt::Key_Y, ModAltGr, IsLetter, 0x0000 },
+ { 21, 0x0059, Qt::Key_Y, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 21, 0x0079, QCTRL(Qt::Key_Y), ModControl, IsLetter, 0x0000 },
+ { 21, 0x0079, QCTRL(Qt::Key_Y), ModShift | ModControl, IsLetter, 0x0000 },
+ { 21, 0x0079, QCTRL(Qt::Key_Y), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 21, 0x0079, QCTRL(Qt::Key_Y), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 21, 0x0079, QALT(Qt::Key_Y), ModAlt, IsLetter, 0x0000 },
+ { 21, 0x0079, QALT(Qt::Key_Y), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 21, 0x0079, QALT(Qt::Key_Y), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 21, 0x0079, QALT(Qt::Key_Y), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 21, 0x0079, QCTRL(QALT(Qt::Key_Y)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 21, 0x0079, QCTRL(QALT(Qt::Key_Y)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 21, 0x0079, QCTRL(QALT(Qt::Key_Y)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 21, 0x0079, QCTRL(QALT(Qt::Key_Y)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 22, 0x0075, Qt::Key_U, ModPlain, IsLetter, 0x0000 },
+ { 22, 0x0055, Qt::Key_U, ModShift, IsLetter, 0x0000 },
+ { 22, 0x0075, Qt::Key_U, ModAltGr, IsLetter, 0x0000 },
+ { 22, 0x0055, Qt::Key_U, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 22, 0x0075, QCTRL(Qt::Key_U), ModControl, IsLetter, 0x0000 },
+ { 22, 0x0075, QCTRL(Qt::Key_U), ModShift | ModControl, IsLetter, 0x0000 },
+ { 22, 0x0075, QCTRL(Qt::Key_U), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 22, 0x0075, QCTRL(Qt::Key_U), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 22, 0x0075, QALT(Qt::Key_U), ModAlt, IsLetter, 0x0000 },
+ { 22, 0x0075, QALT(Qt::Key_U), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 22, 0x0075, QALT(Qt::Key_U), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 22, 0x0075, QALT(Qt::Key_U), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 22, 0x0075, QCTRL(QALT(Qt::Key_U)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 22, 0x0075, QCTRL(QALT(Qt::Key_U)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 22, 0x0075, QCTRL(QALT(Qt::Key_U)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 22, 0x0075, QCTRL(QALT(Qt::Key_U)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 23, 0x0069, Qt::Key_I, ModPlain, IsLetter, 0x0000 },
+ { 23, 0x0049, Qt::Key_I, ModShift, IsLetter, 0x0000 },
+ { 23, 0x0069, Qt::Key_I, ModAltGr, IsLetter, 0x0000 },
+ { 23, 0x0049, Qt::Key_I, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 23, 0x0069, QCTRL(Qt::Key_I), ModControl, IsLetter, 0x0000 },
+ { 23, 0x0069, QCTRL(Qt::Key_I), ModShift | ModControl, IsLetter, 0x0000 },
+ { 23, 0x0069, QCTRL(Qt::Key_I), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 23, 0x0069, QCTRL(Qt::Key_I), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 23, 0x0069, QALT(Qt::Key_I), ModAlt, IsLetter, 0x0000 },
+ { 23, 0x0069, QALT(Qt::Key_I), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 23, 0x0069, QALT(Qt::Key_I), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 23, 0x0069, QALT(Qt::Key_I), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 23, 0x0069, QCTRL(QALT(Qt::Key_I)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 23, 0x0069, QCTRL(QALT(Qt::Key_I)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 23, 0x0069, QCTRL(QALT(Qt::Key_I)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 23, 0x0069, QCTRL(QALT(Qt::Key_I)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 24, 0x006f, Qt::Key_O, ModPlain, IsLetter, 0x0000 },
+ { 24, 0x004f, Qt::Key_O, ModShift, IsLetter, 0x0000 },
+ { 24, 0x006f, Qt::Key_O, ModAltGr, IsLetter, 0x0000 },
+ { 24, 0x004f, Qt::Key_O, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 24, 0x006f, QCTRL(Qt::Key_O), ModControl, IsLetter, 0x0000 },
+ { 24, 0x006f, QCTRL(Qt::Key_O), ModShift | ModControl, IsLetter, 0x0000 },
+ { 24, 0x006f, QCTRL(Qt::Key_O), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 24, 0x006f, QCTRL(Qt::Key_O), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 24, 0x006f, QALT(Qt::Key_O), ModAlt, IsLetter, 0x0000 },
+ { 24, 0x006f, QALT(Qt::Key_O), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 24, 0x006f, QALT(Qt::Key_O), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 24, 0x006f, QALT(Qt::Key_O), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 24, 0x006f, QCTRL(QALT(Qt::Key_O)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 24, 0x006f, QCTRL(QALT(Qt::Key_O)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 24, 0x006f, QCTRL(QALT(Qt::Key_O)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 24, 0x006f, QCTRL(QALT(Qt::Key_O)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 25, 0x0070, Qt::Key_P, ModPlain, IsLetter, 0x0000 },
+ { 25, 0x0050, Qt::Key_P, ModShift, IsLetter, 0x0000 },
+ { 25, 0x0070, Qt::Key_P, ModAltGr, IsLetter, 0x0000 },
+ { 25, 0x0050, Qt::Key_P, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 25, 0x0070, QCTRL(Qt::Key_P), ModControl, IsLetter, 0x0000 },
+ { 25, 0x0070, QCTRL(Qt::Key_P), ModShift | ModControl, IsLetter, 0x0000 },
+ { 25, 0x0070, QCTRL(Qt::Key_P), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 25, 0x0070, QCTRL(Qt::Key_P), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 25, 0x0070, QALT(Qt::Key_P), ModAlt, IsLetter, 0x0000 },
+ { 25, 0x0070, QALT(Qt::Key_P), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 25, 0x0070, QALT(Qt::Key_P), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 25, 0x0070, QALT(Qt::Key_P), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 25, 0x0070, QCTRL(QALT(Qt::Key_P)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 25, 0x0070, QCTRL(QALT(Qt::Key_P)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 25, 0x0070, QCTRL(QALT(Qt::Key_P)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 25, 0x0070, QCTRL(QALT(Qt::Key_P)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 26, 0x005b, Qt::Key_BracketLeft, ModPlain, NoFlags, 0x0000 },
+ { 26, 0x007b, Qt::Key_BraceLeft, ModShift, NoFlags, 0x0000 },
+ { 26, 0xffff, Qt::Key_Escape, ModControl, NoFlags, 0x0000 },
+ { 27, 0x005d, Qt::Key_BracketRight, ModPlain, NoFlags, 0x0000 },
+ { 27, 0x007d, Qt::Key_BraceRight, ModShift, NoFlags, 0x0000 },
+ { 27, 0x007e, Qt::Key_AsciiTilde, ModAltGr, NoFlags, 0x0000 },
+ { 27, 0x005d, QCTRL(Qt::Key_BracketRight), ModControl, NoFlags, 0x0000 },
+ { 28, 0xffff, Qt::Key_Return, ModPlain, NoFlags, 0x0000 },
+ { 28, 0x006d, QCTRL(QALT(Qt::Key_M)), ModAlt, NoFlags, 0x0000 },
+ { 29, 0xffff, Qt::Key_Control, ModPlain, IsModifier, ModControl },
+ { 30, 0x0061, Qt::Key_A, ModPlain, IsLetter, 0x0000 },
+ { 30, 0x0041, Qt::Key_A, ModShift, IsLetter, 0x0000 },
+ { 30, 0x0061, Qt::Key_A, ModAltGr, IsLetter, 0x0000 },
+ { 30, 0x0041, Qt::Key_A, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 30, 0x0061, QCTRL(Qt::Key_A), ModControl, IsLetter, 0x0000 },
+ { 30, 0x0061, QCTRL(Qt::Key_A), ModShift | ModControl, IsLetter, 0x0000 },
+ { 30, 0x0061, QCTRL(Qt::Key_A), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 30, 0x0061, QCTRL(Qt::Key_A), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 30, 0x0061, QALT(Qt::Key_A), ModAlt, IsLetter, 0x0000 },
+ { 30, 0x0061, QALT(Qt::Key_A), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 30, 0x0061, QALT(Qt::Key_A), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 30, 0x0061, QALT(Qt::Key_A), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 30, 0x0061, QCTRL(QALT(Qt::Key_A)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 30, 0x0061, QCTRL(QALT(Qt::Key_A)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 30, 0x0061, QCTRL(QALT(Qt::Key_A)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 30, 0x0061, QCTRL(QALT(Qt::Key_A)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 31, 0x0073, Qt::Key_S, ModPlain, IsLetter, 0x0000 },
+ { 31, 0x0053, Qt::Key_S, ModShift, IsLetter, 0x0000 },
+ { 31, 0x0073, Qt::Key_S, ModAltGr, IsLetter, 0x0000 },
+ { 31, 0x0053, Qt::Key_S, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 31, 0x0073, QCTRL(Qt::Key_S), ModControl, IsLetter, 0x0000 },
+ { 31, 0x0073, QCTRL(Qt::Key_S), ModShift | ModControl, IsLetter, 0x0000 },
+ { 31, 0x0073, QCTRL(Qt::Key_S), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 31, 0x0073, QCTRL(Qt::Key_S), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 31, 0x0073, QALT(Qt::Key_S), ModAlt, IsLetter, 0x0000 },
+ { 31, 0x0073, QALT(Qt::Key_S), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 31, 0x0073, QALT(Qt::Key_S), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 31, 0x0073, QALT(Qt::Key_S), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 31, 0x0073, QCTRL(QALT(Qt::Key_S)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 31, 0x0073, QCTRL(QALT(Qt::Key_S)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 31, 0x0073, QCTRL(QALT(Qt::Key_S)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 31, 0x0073, QCTRL(QALT(Qt::Key_S)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 32, 0x0064, Qt::Key_D, ModPlain, IsLetter, 0x0000 },
+ { 32, 0x0044, Qt::Key_D, ModShift, IsLetter, 0x0000 },
+ { 32, 0x0064, Qt::Key_D, ModAltGr, IsLetter, 0x0000 },
+ { 32, 0x0044, Qt::Key_D, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 32, 0x0064, QCTRL(Qt::Key_D), ModControl, IsLetter, 0x0000 },
+ { 32, 0x0064, QCTRL(Qt::Key_D), ModShift | ModControl, IsLetter, 0x0000 },
+ { 32, 0x0064, QCTRL(Qt::Key_D), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 32, 0x0064, QCTRL(Qt::Key_D), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 32, 0x0064, QALT(Qt::Key_D), ModAlt, IsLetter, 0x0000 },
+ { 32, 0x0064, QALT(Qt::Key_D), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 32, 0x0064, QALT(Qt::Key_D), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 32, 0x0064, QALT(Qt::Key_D), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 32, 0x0064, QCTRL(QALT(Qt::Key_D)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 32, 0x0064, QCTRL(QALT(Qt::Key_D)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 32, 0x0064, QCTRL(QALT(Qt::Key_D)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 32, 0x0064, QCTRL(QALT(Qt::Key_D)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 33, 0x0066, Qt::Key_F, ModPlain, IsLetter, 0x0000 },
+ { 33, 0x0046, Qt::Key_F, ModShift, IsLetter, 0x0000 },
+ { 33, 0x0066, Qt::Key_F, ModAltGr, IsLetter, 0x0000 },
+ { 33, 0x0046, Qt::Key_F, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 33, 0x0066, QCTRL(Qt::Key_F), ModControl, IsLetter, 0x0000 },
+ { 33, 0x0066, QCTRL(Qt::Key_F), ModShift | ModControl, IsLetter, 0x0000 },
+ { 33, 0x0066, QCTRL(Qt::Key_F), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 33, 0x0066, QCTRL(Qt::Key_F), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 33, 0x0066, QALT(Qt::Key_F), ModAlt, IsLetter, 0x0000 },
+ { 33, 0x0066, QALT(Qt::Key_F), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 33, 0x0066, QALT(Qt::Key_F), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 33, 0x0066, QALT(Qt::Key_F), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 33, 0x0066, QCTRL(QALT(Qt::Key_F)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 33, 0x0066, QCTRL(QALT(Qt::Key_F)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 33, 0x0066, QCTRL(QALT(Qt::Key_F)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 33, 0x0066, QCTRL(QALT(Qt::Key_F)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 34, 0x0067, Qt::Key_G, ModPlain, IsLetter, 0x0000 },
+ { 34, 0x0047, Qt::Key_G, ModShift, IsLetter, 0x0000 },
+ { 34, 0x0067, Qt::Key_G, ModAltGr, IsLetter, 0x0000 },
+ { 34, 0x0047, Qt::Key_G, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 34, 0x0067, QCTRL(Qt::Key_G), ModControl, IsLetter, 0x0000 },
+ { 34, 0x0067, QCTRL(Qt::Key_G), ModShift | ModControl, IsLetter, 0x0000 },
+ { 34, 0x0067, QCTRL(Qt::Key_G), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 34, 0x0067, QCTRL(Qt::Key_G), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 34, 0x0067, QALT(Qt::Key_G), ModAlt, IsLetter, 0x0000 },
+ { 34, 0x0067, QALT(Qt::Key_G), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 34, 0x0067, QALT(Qt::Key_G), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 34, 0x0067, QALT(Qt::Key_G), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 34, 0x0067, QCTRL(QALT(Qt::Key_G)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 34, 0x0067, QCTRL(QALT(Qt::Key_G)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 34, 0x0067, QCTRL(QALT(Qt::Key_G)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 34, 0x0067, QCTRL(QALT(Qt::Key_G)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 35, 0x0068, Qt::Key_H, ModPlain, IsLetter, 0x0000 },
+ { 35, 0x0048, Qt::Key_H, ModShift, IsLetter, 0x0000 },
+ { 35, 0x0068, Qt::Key_H, ModAltGr, IsLetter, 0x0000 },
+ { 35, 0x0048, Qt::Key_H, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 35, 0x0068, QCTRL(Qt::Key_H), ModControl, IsLetter, 0x0000 },
+ { 35, 0x0068, QCTRL(Qt::Key_H), ModShift | ModControl, IsLetter, 0x0000 },
+ { 35, 0x0068, QCTRL(Qt::Key_H), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 35, 0x0068, QCTRL(Qt::Key_H), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 35, 0x0068, QALT(Qt::Key_H), ModAlt, IsLetter, 0x0000 },
+ { 35, 0x0068, QALT(Qt::Key_H), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 35, 0x0068, QALT(Qt::Key_H), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 35, 0x0068, QALT(Qt::Key_H), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 35, 0x0068, QCTRL(QALT(Qt::Key_H)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 35, 0x0068, QCTRL(QALT(Qt::Key_H)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 35, 0x0068, QCTRL(QALT(Qt::Key_H)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 35, 0x0068, QCTRL(QALT(Qt::Key_H)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 36, 0x006a, Qt::Key_J, ModPlain, IsLetter, 0x0000 },
+ { 36, 0x004a, Qt::Key_J, ModShift, IsLetter, 0x0000 },
+ { 36, 0x006a, Qt::Key_J, ModAltGr, IsLetter, 0x0000 },
+ { 36, 0x004a, Qt::Key_J, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 36, 0x006a, QCTRL(Qt::Key_J), ModControl, IsLetter, 0x0000 },
+ { 36, 0x006a, QCTRL(Qt::Key_J), ModShift | ModControl, IsLetter, 0x0000 },
+ { 36, 0x006a, QCTRL(Qt::Key_J), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 36, 0x006a, QCTRL(Qt::Key_J), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 36, 0x006a, QALT(Qt::Key_J), ModAlt, IsLetter, 0x0000 },
+ { 36, 0x006a, QALT(Qt::Key_J), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 36, 0x006a, QALT(Qt::Key_J), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 36, 0x006a, QALT(Qt::Key_J), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 36, 0x006a, QCTRL(QALT(Qt::Key_J)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 36, 0x006a, QCTRL(QALT(Qt::Key_J)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 36, 0x006a, QCTRL(QALT(Qt::Key_J)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 36, 0x006a, QCTRL(QALT(Qt::Key_J)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 37, 0x006b, Qt::Key_K, ModPlain, IsLetter, 0x0000 },
+ { 37, 0x004b, Qt::Key_K, ModShift, IsLetter, 0x0000 },
+ { 37, 0x006b, Qt::Key_K, ModAltGr, IsLetter, 0x0000 },
+ { 37, 0x004b, Qt::Key_K, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 37, 0x006b, QCTRL(Qt::Key_K), ModControl, IsLetter, 0x0000 },
+ { 37, 0x006b, QCTRL(Qt::Key_K), ModShift | ModControl, IsLetter, 0x0000 },
+ { 37, 0x006b, QCTRL(Qt::Key_K), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 37, 0x006b, QCTRL(Qt::Key_K), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 37, 0x006b, QALT(Qt::Key_K), ModAlt, IsLetter, 0x0000 },
+ { 37, 0x006b, QALT(Qt::Key_K), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 37, 0x006b, QALT(Qt::Key_K), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 37, 0x006b, QALT(Qt::Key_K), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 37, 0x006b, QCTRL(QALT(Qt::Key_K)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 37, 0x006b, QCTRL(QALT(Qt::Key_K)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 37, 0x006b, QCTRL(QALT(Qt::Key_K)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 37, 0x006b, QCTRL(QALT(Qt::Key_K)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 38, 0x006c, Qt::Key_L, ModPlain, IsLetter, 0x0000 },
+ { 38, 0x004c, Qt::Key_L, ModShift, IsLetter, 0x0000 },
+ { 38, 0x006c, Qt::Key_L, ModAltGr, IsLetter, 0x0000 },
+ { 38, 0x004c, Qt::Key_L, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 38, 0x006c, QCTRL(Qt::Key_L), ModControl, IsLetter, 0x0000 },
+ { 38, 0x006c, QCTRL(Qt::Key_L), ModShift | ModControl, IsLetter, 0x0000 },
+ { 38, 0x006c, QCTRL(Qt::Key_L), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 38, 0x006c, QCTRL(Qt::Key_L), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 38, 0x006c, QALT(Qt::Key_L), ModAlt, IsLetter, 0x0000 },
+ { 38, 0x006c, QALT(Qt::Key_L), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 38, 0x006c, QALT(Qt::Key_L), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 38, 0x006c, QALT(Qt::Key_L), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 38, 0x006c, QCTRL(QALT(Qt::Key_L)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 38, 0x006c, QCTRL(QALT(Qt::Key_L)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 38, 0x006c, QCTRL(QALT(Qt::Key_L)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 38, 0x006c, QCTRL(QALT(Qt::Key_L)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 39, 0x003b, Qt::Key_Semicolon, ModPlain, NoFlags, 0x0000 },
+ { 39, 0x003a, Qt::Key_Colon, ModShift, NoFlags, 0x0000 },
+ { 40, 0x0027, Qt::Key_Apostrophe, ModPlain, NoFlags, 0x0000 },
+ { 40, 0x0022, Qt::Key_QuoteDbl, ModShift, NoFlags, 0x0000 },
+ { 40, 0x0067, QCTRL(Qt::Key_G), ModControl, NoFlags, 0x0000 },
+ { 41, 0x0060, Qt::Key_QuoteLeft, ModPlain, NoFlags, 0x0000 },
+ { 41, 0x007e, Qt::Key_AsciiTilde, ModShift, NoFlags, 0x0000 },
+ { 42, 0xffff, Qt::Key_Shift, ModPlain, IsModifier, ModShift },
+ { 43, 0x005c, Qt::Key_Backslash, ModPlain, NoFlags, 0x0000 },
+ { 43, 0x007c, Qt::Key_Bar, ModShift, NoFlags, 0x0000 },
+ { 43, 0x005c, QCTRL(Qt::Key_Backslash), ModControl, NoFlags, 0x0000 },
+ { 44, 0x007a, Qt::Key_Z, ModPlain, IsLetter, 0x0000 },
+ { 44, 0x005a, Qt::Key_Z, ModShift, IsLetter, 0x0000 },
+ { 44, 0x007a, Qt::Key_Z, ModAltGr, IsLetter, 0x0000 },
+ { 44, 0x005a, Qt::Key_Z, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 44, 0x007a, QCTRL(Qt::Key_Z), ModControl, IsLetter, 0x0000 },
+ { 44, 0x007a, QCTRL(Qt::Key_Z), ModShift | ModControl, IsLetter, 0x0000 },
+ { 44, 0x007a, QCTRL(Qt::Key_Z), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 44, 0x007a, QCTRL(Qt::Key_Z), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 44, 0x007a, QALT(Qt::Key_Z), ModAlt, IsLetter, 0x0000 },
+ { 44, 0x007a, QALT(Qt::Key_Z), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 44, 0x007a, QALT(Qt::Key_Z), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 44, 0x007a, QALT(Qt::Key_Z), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 44, 0x007a, QCTRL(QALT(Qt::Key_Z)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 44, 0x007a, QCTRL(QALT(Qt::Key_Z)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 44, 0x007a, QCTRL(QALT(Qt::Key_Z)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 44, 0x007a, QCTRL(QALT(Qt::Key_Z)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 45, 0x0078, Qt::Key_X, ModPlain, IsLetter, 0x0000 },
+ { 45, 0x0058, Qt::Key_X, ModShift, IsLetter, 0x0000 },
+ { 45, 0x0078, Qt::Key_X, ModAltGr, IsLetter, 0x0000 },
+ { 45, 0x0058, Qt::Key_X, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 45, 0x0078, QCTRL(Qt::Key_X), ModControl, IsLetter, 0x0000 },
+ { 45, 0x0078, QCTRL(Qt::Key_X), ModShift | ModControl, IsLetter, 0x0000 },
+ { 45, 0x0078, QCTRL(Qt::Key_X), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 45, 0x0078, QCTRL(Qt::Key_X), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 45, 0x0078, QALT(Qt::Key_X), ModAlt, IsLetter, 0x0000 },
+ { 45, 0x0078, QALT(Qt::Key_X), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 45, 0x0078, QALT(Qt::Key_X), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 45, 0x0078, QALT(Qt::Key_X), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 45, 0x0078, QCTRL(QALT(Qt::Key_X)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 45, 0x0078, QCTRL(QALT(Qt::Key_X)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 45, 0x0078, QCTRL(QALT(Qt::Key_X)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 45, 0x0078, QCTRL(QALT(Qt::Key_X)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 46, 0x0063, Qt::Key_C, ModPlain, IsLetter, 0x0000 },
+ { 46, 0x0043, Qt::Key_C, ModShift, IsLetter, 0x0000 },
+ { 46, 0x0063, Qt::Key_C, ModAltGr, IsLetter, 0x0000 },
+ { 46, 0x0043, Qt::Key_C, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 46, 0x0063, QCTRL(Qt::Key_C), ModControl, IsLetter, 0x0000 },
+ { 46, 0x0063, QCTRL(Qt::Key_C), ModShift | ModControl, IsLetter, 0x0000 },
+ { 46, 0x0063, QCTRL(Qt::Key_C), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 46, 0x0063, QCTRL(Qt::Key_C), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 46, 0x0063, QALT(Qt::Key_C), ModAlt, IsLetter, 0x0000 },
+ { 46, 0x0063, QALT(Qt::Key_C), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 46, 0x0063, QALT(Qt::Key_C), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 46, 0x0063, QALT(Qt::Key_C), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 46, 0x0063, QCTRL(QALT(Qt::Key_C)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 46, 0x0063, QCTRL(QALT(Qt::Key_C)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 46, 0x0063, QCTRL(QALT(Qt::Key_C)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 46, 0x0063, QCTRL(QALT(Qt::Key_C)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 47, 0x0076, Qt::Key_V, ModPlain, IsLetter, 0x0000 },
+ { 47, 0x0056, Qt::Key_V, ModShift, IsLetter, 0x0000 },
+ { 47, 0x0076, Qt::Key_V, ModAltGr, IsLetter, 0x0000 },
+ { 47, 0x0056, Qt::Key_V, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 47, 0x0076, QCTRL(Qt::Key_V), ModControl, IsLetter, 0x0000 },
+ { 47, 0x0076, QCTRL(Qt::Key_V), ModShift | ModControl, IsLetter, 0x0000 },
+ { 47, 0x0076, QCTRL(Qt::Key_V), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 47, 0x0076, QCTRL(Qt::Key_V), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 47, 0x0076, QALT(Qt::Key_V), ModAlt, IsLetter, 0x0000 },
+ { 47, 0x0076, QALT(Qt::Key_V), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 47, 0x0076, QALT(Qt::Key_V), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 47, 0x0076, QALT(Qt::Key_V), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 47, 0x0076, QCTRL(QALT(Qt::Key_V)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 47, 0x0076, QCTRL(QALT(Qt::Key_V)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 47, 0x0076, QCTRL(QALT(Qt::Key_V)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 47, 0x0076, QCTRL(QALT(Qt::Key_V)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 48, 0x0062, Qt::Key_B, ModPlain, IsLetter, 0x0000 },
+ { 48, 0x0042, Qt::Key_B, ModShift, IsLetter, 0x0000 },
+ { 48, 0x0062, Qt::Key_B, ModAltGr, IsLetter, 0x0000 },
+ { 48, 0x0042, Qt::Key_B, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 48, 0x0062, QCTRL(Qt::Key_B), ModControl, IsLetter, 0x0000 },
+ { 48, 0x0062, QCTRL(Qt::Key_B), ModShift | ModControl, IsLetter, 0x0000 },
+ { 48, 0x0062, QCTRL(Qt::Key_B), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 48, 0x0062, QCTRL(Qt::Key_B), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 48, 0x0062, QALT(Qt::Key_B), ModAlt, IsLetter, 0x0000 },
+ { 48, 0x0062, QALT(Qt::Key_B), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 48, 0x0062, QALT(Qt::Key_B), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 48, 0x0062, QALT(Qt::Key_B), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 48, 0x0062, QCTRL(QALT(Qt::Key_B)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 48, 0x0062, QCTRL(QALT(Qt::Key_B)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 48, 0x0062, QCTRL(QALT(Qt::Key_B)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 48, 0x0062, QCTRL(QALT(Qt::Key_B)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 49, 0x006e, Qt::Key_N, ModPlain, IsLetter, 0x0000 },
+ { 49, 0x004e, Qt::Key_N, ModShift, IsLetter, 0x0000 },
+ { 49, 0x006e, Qt::Key_N, ModAltGr, IsLetter, 0x0000 },
+ { 49, 0x004e, Qt::Key_N, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 49, 0x006e, QCTRL(Qt::Key_N), ModControl, IsLetter, 0x0000 },
+ { 49, 0x006e, QCTRL(Qt::Key_N), ModShift | ModControl, IsLetter, 0x0000 },
+ { 49, 0x006e, QCTRL(Qt::Key_N), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 49, 0x006e, QCTRL(Qt::Key_N), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 49, 0x006e, QALT(Qt::Key_N), ModAlt, IsLetter, 0x0000 },
+ { 49, 0x006e, QALT(Qt::Key_N), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 49, 0x006e, QALT(Qt::Key_N), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 49, 0x006e, QALT(Qt::Key_N), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 49, 0x006e, QCTRL(QALT(Qt::Key_N)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 49, 0x006e, QCTRL(QALT(Qt::Key_N)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 49, 0x006e, QCTRL(QALT(Qt::Key_N)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 49, 0x006e, QCTRL(QALT(Qt::Key_N)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 50, 0x006d, Qt::Key_M, ModPlain, IsLetter, 0x0000 },
+ { 50, 0x004d, Qt::Key_M, ModShift, IsLetter, 0x0000 },
+ { 50, 0x006d, Qt::Key_M, ModAltGr, IsLetter, 0x0000 },
+ { 50, 0x004d, Qt::Key_M, ModShift | ModAltGr, IsLetter, 0x0000 },
+ { 50, 0x006d, QCTRL(Qt::Key_M), ModControl, IsLetter, 0x0000 },
+ { 50, 0x006d, QCTRL(Qt::Key_M), ModShift | ModControl, IsLetter, 0x0000 },
+ { 50, 0x006d, QCTRL(Qt::Key_M), ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 50, 0x006d, QCTRL(Qt::Key_M), ModShift | ModAltGr | ModControl, IsLetter, 0x0000 },
+ { 50, 0x006d, QALT(Qt::Key_M), ModAlt, IsLetter, 0x0000 },
+ { 50, 0x006d, QALT(Qt::Key_M), ModShift | ModAlt, IsLetter, 0x0000 },
+ { 50, 0x006d, QALT(Qt::Key_M), ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 50, 0x006d, QALT(Qt::Key_M), ModShift | ModAltGr | ModAlt, IsLetter, 0x0000 },
+ { 50, 0x006d, QCTRL(QALT(Qt::Key_M)), ModControl | ModAlt, IsLetter, 0x0000 },
+ { 50, 0x006d, QCTRL(QALT(Qt::Key_M)), ModShift | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 50, 0x006d, QCTRL(QALT(Qt::Key_M)), ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 50, 0x006d, QCTRL(QALT(Qt::Key_M)), ModShift | ModAltGr | ModControl | ModAlt, IsLetter, 0x0000 },
+ { 51, 0x002c, Qt::Key_Comma, ModPlain, NoFlags, 0x0000 },
+ { 51, 0x003c, Qt::Key_Less, ModShift, NoFlags, 0x0000 },
+ { 52, 0x002e, Qt::Key_Period, ModPlain, NoFlags, 0x0000 },
+ { 52, 0x003e, Qt::Key_Greater, ModShift, NoFlags, 0x0000 },
+ { 52, 0xffff, Qt::Key_Multi_key, ModAltGr, NoFlags, 0x0000 },
+ { 53, 0x002f, Qt::Key_Slash, ModPlain, NoFlags, 0x0000 },
+ { 53, 0x003f, Qt::Key_Question, ModShift, NoFlags, 0x0000 },
+ { 53, 0xffff, Qt::Key_Backspace, ModControl, NoFlags, 0x0000 },
+ { 54, 0xffff, Qt::Key_Shift, ModPlain, IsModifier, ModShift },
+ { 55, 0x002a, QKEYPAD(Qt::Key_Asterisk), ModPlain, NoFlags, 0x0000 },
+ { 56, 0xffff, Qt::Key_Alt, ModPlain, IsModifier, ModAlt },
+ { 57, 0x0020, Qt::Key_Space, ModPlain, NoFlags, 0x0000 },
+ { 58, 0xffff, Qt::Key_CapsLock, ModPlain, NoFlags, 0x0000 },
+ { 59, 0xffff, Qt::Key_F1, ModPlain, NoFlags, 0x0000 },
+ { 59, 0xffff, Qt::Key_F13, ModShift, NoFlags, 0x0000 },
+ { 59, 0xffff, Qt::Key_F25, ModControl, NoFlags, 0x0000 },
+ { 60, 0xffff, Qt::Key_F2, ModPlain, NoFlags, 0x0000 },
+ { 60, 0xffff, Qt::Key_F14, ModShift, NoFlags, 0x0000 },
+ { 60, 0xffff, Qt::Key_F26, ModControl, NoFlags, 0x0000 },
+ { 61, 0xffff, Qt::Key_F3, ModPlain, NoFlags, 0x0000 },
+ { 61, 0xffff, Qt::Key_F15, ModShift, NoFlags, 0x0000 },
+ { 61, 0xffff, Qt::Key_F27, ModControl, NoFlags, 0x0000 },
+ { 62, 0xffff, Qt::Key_F4, ModPlain, NoFlags, 0x0000 },
+ { 62, 0xffff, Qt::Key_F16, ModShift, NoFlags, 0x0000 },
+ { 62, 0xffff, Qt::Key_F28, ModControl, NoFlags, 0x0000 },
+ { 63, 0xffff, Qt::Key_F5, ModPlain, NoFlags, 0x0000 },
+ { 63, 0xffff, Qt::Key_F17, ModShift, NoFlags, 0x0000 },
+ { 63, 0xffff, Qt::Key_F29, ModControl, NoFlags, 0x0000 },
+ { 64, 0xffff, Qt::Key_F6, ModPlain, NoFlags, 0x0000 },
+ { 64, 0xffff, Qt::Key_F18, ModShift, NoFlags, 0x0000 },
+ { 64, 0xffff, Qt::Key_F30, ModControl, NoFlags, 0x0000 },
+ { 65, 0xffff, Qt::Key_F7, ModPlain, NoFlags, 0x0000 },
+ { 65, 0xffff, Qt::Key_F19, ModShift, NoFlags, 0x0000 },
+ { 65, 0xffff, Qt::Key_F31, ModControl, NoFlags, 0x0000 },
+ { 66, 0xffff, Qt::Key_F8, ModPlain, NoFlags, 0x0000 },
+ { 66, 0xffff, Qt::Key_F20, ModShift, NoFlags, 0x0000 },
+ { 66, 0xffff, Qt::Key_F32, ModControl, NoFlags, 0x0000 },
+ { 67, 0xffff, Qt::Key_F9, ModPlain, NoFlags, 0x0000 },
+ { 67, 0xffff, Qt::Key_F21, ModShift, NoFlags, 0x0000 },
+ { 67, 0xffff, Qt::Key_F33, ModControl, NoFlags, 0x0000 },
+ { 68, 0xffff, Qt::Key_F10, ModPlain, NoFlags, 0x0000 },
+ { 68, 0xffff, Qt::Key_F22, ModShift, NoFlags, 0x0000 },
+ { 68, 0xffff, Qt::Key_F34, ModControl, NoFlags, 0x0000 },
+ { 69, 0xffff, Qt::Key_NumLock, ModPlain, NoFlags, 0x0000 },
+ { 70, 0xffff, Qt::Key_ScrollLock, ModPlain, NoFlags, 0x0000 },
+ { 70, 0xffff, Qt::Key_ScrollLock, ModAlt, NoFlags, 0x0000 },
+ { 71, 0x0037, QKEYPAD(Qt::Key_7), ModPlain, NoFlags, 0x0000 },
+ { 72, 0x0038, QKEYPAD(Qt::Key_8), ModPlain, NoFlags, 0x0000 },
+ { 73, 0x0039, QKEYPAD(Qt::Key_9), ModPlain, NoFlags, 0x0000 },
+ { 74, 0x002d, QKEYPAD(Qt::Key_Minus), ModPlain, NoFlags, 0x0000 },
+ { 75, 0x0034, QKEYPAD(Qt::Key_4), ModPlain, NoFlags, 0x0000 },
+ { 76, 0x0035, QKEYPAD(Qt::Key_5), ModPlain, NoFlags, 0x0000 },
+ { 77, 0x0036, QKEYPAD(Qt::Key_6), ModPlain, NoFlags, 0x0000 },
+ { 78, 0x002b, QKEYPAD(Qt::Key_Plus), ModPlain, NoFlags, 0x0000 },
+ { 79, 0x0031, QKEYPAD(Qt::Key_1), ModPlain, NoFlags, 0x0000 },
+ { 80, 0x0032, QKEYPAD(Qt::Key_2), ModPlain, NoFlags, 0x0000 },
+ { 81, 0x0033, QKEYPAD(Qt::Key_3), ModPlain, NoFlags, 0x0000 },
+ { 82, 0x0030, QKEYPAD(Qt::Key_0), ModPlain, NoFlags, 0x0000 },
+ { 83, 0x002e, QKEYPAD(Qt::Key_Period), ModPlain, NoFlags, 0x0000 },
+ { 86, 0x003c, Qt::Key_Less, ModPlain, NoFlags, 0x0000 },
+ { 86, 0x003e, Qt::Key_Greater, ModShift, NoFlags, 0x0000 },
+ { 86, 0x007c, Qt::Key_Bar, ModAltGr, NoFlags, 0x0000 },
+ { 87, 0xffff, Qt::Key_F11, ModPlain, NoFlags, 0x0000 },
+ { 87, 0xffff, Qt::Key_F23, ModShift, NoFlags, 0x0000 },
+ { 87, 0xffff, Qt::Key_F35, ModControl, NoFlags, 0x0000 },
+ { 88, 0xffff, Qt::Key_F12, ModPlain, NoFlags, 0x0000 },
+ { 88, 0xffff, Qt::Key_F24, ModShift, NoFlags, 0x0000 },
+ { 89, 0xffff, QKEYPAD(Qt::Key_Enter), ModPlain, NoFlags, 0x0000 },
+ { 90, 0xffff, Qt::Key_Control, ModPlain, IsModifier, ModControl },
+ { 91, 0x002f, QKEYPAD(Qt::Key_Slash), ModPlain, NoFlags, 0x0000 },
+ { 92, 0x005c, QCTRL(Qt::Key_Backslash), ModPlain, NoFlags, 0x0000 },
+ { 93, 0xffff, Qt::Key_AltGr, ModPlain, IsModifier, ModAltGr },
+ { 94, 0xffff, Qt::Key_Home, ModPlain, NoFlags, 0x0000 },
+ { 95, 0xffff, Qt::Key_Up, ModPlain, NoFlags, 0x0000 },
+ { 96, 0xffff, Qt::Key_PageUp, ModPlain, NoFlags, 0x0000 },
+ { 97, 0xffff, Qt::Key_Left, ModPlain, NoFlags, 0x0000 },
+ { 98, 0xffff, Qt::Key_Right, ModPlain, NoFlags, 0x0000 },
+ { 99, 0xffff, Qt::Key_End, ModPlain, NoFlags, 0x0000 },
+ { 100, 0xffff, Qt::Key_Down, ModPlain, NoFlags, 0x0000 },
+ { 101, 0xffff, Qt::Key_PageDown, ModPlain, NoFlags, 0x0000 },
+ { 102, 0xffff, Qt::Key_Insert, ModPlain, NoFlags, 0x0000 },
+ { 103, 0xffff, Qt::Key_Delete, ModPlain, NoFlags, 0x0000 },
+};
+
+#endif // QBSDKEYBOARD_DEFAULTMAP_P_H
diff --git a/src/plugins/generic/bsdmouse/bsdmouse.json b/src/plugins/generic/bsdmouse/bsdmouse.json
new file mode 100644
index 0000000000..33974a62f2
--- /dev/null
+++ b/src/plugins/generic/bsdmouse/bsdmouse.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "BsdMouse" ]
+}
diff --git a/src/plugins/generic/bsdmouse/bsdmouse.pro b/src/plugins/generic/bsdmouse/bsdmouse.pro
new file mode 100644
index 0000000000..11949b95d5
--- /dev/null
+++ b/src/plugins/generic/bsdmouse/bsdmouse.pro
@@ -0,0 +1,16 @@
+TARGET = qbsdmouseplugin
+
+PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
+PLUGIN_CLASS_NAME = QBsdMousePlugin
+load(qt_plugin)
+
+QT += core-private gui-private
+
+HEADERS = qbsdmouse.h
+SOURCES = main.cpp \
+ qbsdmouse.cpp
+
+OTHER_FILES += \
+ qbsdmouse.json
+
diff --git a/src/plugins/generic/bsdmouse/main.cpp b/src/plugins/generic/bsdmouse/main.cpp
new file mode 100644
index 0000000000..4abc7609c1
--- /dev/null
+++ b/src/plugins/generic/bsdmouse/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qgenericplugin.h>
+#include "qbsdmouse.h"
+
+QT_BEGIN_NAMESPACE
+
+class QBsdMousePlugin : public QGenericPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "bsdmouse.json")
+
+public:
+ QObject *create(const QString &key, const QString &specification) override;
+};
+
+QObject *QBsdMousePlugin::create(const QString &key, const QString &specification)
+{
+ if (!key.compare(QLatin1String("BsdMouse"), Qt::CaseInsensitive))
+ return new QBsdMouseHandler(key, specification);
+
+ return nullptr;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/generic/bsdmouse/qbsdmouse.cpp b/src/plugins/generic/bsdmouse/qbsdmouse.cpp
new file mode 100644
index 0000000000..125d74470b
--- /dev/null
+++ b/src/plugins/generic/bsdmouse/qbsdmouse.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbsdmouse.h"
+
+#include <QSocketNotifier>
+#include <QStringList>
+#include <QPoint>
+#include <QGuiApplication>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <private/qcore_unix_p.h>
+#include <qdebug.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mouse.h>
+#include <unistd.h>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ PsmLevelBasic = 0,
+ PsmLevelExtended = 1,
+ PsmLevelNative = 2
+};
+
+QBsdMouseHandler::QBsdMouseHandler(const QString &key, const QString &specification)
+{
+ Q_UNUSED(key);
+
+ setObjectName(QLatin1String("BSD Sysmouse Handler"));
+
+ QByteArray device;
+ if (specification.startsWith("/dev/"))
+ device = QFile::encodeName(specification);
+
+ if (device.isEmpty())
+ device = QByteArrayLiteral("/dev/sysmouse");
+
+ m_devFd = QT_OPEN(device.constData(), O_RDONLY);
+ if (m_devFd < 0) {
+ qErrnoWarning(errno, "open(%s) failed", device.constData());
+ return;
+ }
+
+ int level = 0;
+ if (ioctl(m_devFd, MOUSE_GETLEVEL, &level)) {
+ qErrnoWarning(errno, "ioctl(%s, MOUSE_GETLEVEL) failed", device.constData());
+ close(m_devFd);
+ m_devFd = -1;
+ return;
+ }
+
+ switch (level) {
+ case PsmLevelBasic:
+ m_packetSize = 5;
+ break;
+ case PsmLevelExtended:
+ m_packetSize = 8;
+ break;
+ default:
+ qWarning("Unsupported mouse device operation level: %d", level);
+ close(m_devFd);
+ m_devFd = -1;
+ return;
+ }
+
+ if (fcntl(m_devFd, F_SETFL, O_NONBLOCK)) {
+ qErrnoWarning(errno, "fcntl(%s, F_SETFL, O_NONBLOCK) failed", device.constData());
+ close(m_devFd);
+ m_devFd = -1;
+ return;
+ }
+
+ m_notifier.reset(new QSocketNotifier(m_devFd, QSocketNotifier::Read, this));
+ connect(m_notifier.data(), &QSocketNotifier::activated, this, &QBsdMouseHandler::readMouseData);
+}
+
+QBsdMouseHandler::~QBsdMouseHandler()
+{
+ if (m_devFd != -1)
+ close(m_devFd);
+}
+
+void QBsdMouseHandler::readMouseData()
+{
+ if (m_devFd < 0)
+ return;
+
+ if (m_packetSize == 0)
+ return;
+
+ // packet format described in mouse(4)
+ qint8 packet[MOUSE_SYS_PACKETSIZE];
+ quint8 status = 0;
+ while (read(m_devFd, packet, m_packetSize) == m_packetSize) {
+ const qint16 relx = packet[1] + packet[3];
+ const qint16 rely = -(packet[2] + packet[4]);
+
+ m_x += relx;
+ m_y += rely;
+
+ status = packet[0] & MOUSE_SYS_STDBUTTONS;
+ }
+
+ // clamp to screen geometry
+ const QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ if (m_x + m_xOffset < g.left())
+ m_x = g.left() - m_xOffset;
+ else if (m_x + m_xOffset > g.right())
+ m_x = g.right() - m_xOffset;
+
+ if (m_y + m_yOffset < g.top())
+ m_y = g.top() - m_yOffset;
+ else if (m_y + m_yOffset > g.bottom())
+ m_y = g.bottom() - m_yOffset;
+
+ const QPoint pos(m_x + m_xOffset, m_y + m_yOffset);
+ m_buttons = Qt::NoButton;
+ if (!(status & MOUSE_SYS_BUTTON1UP))
+ m_buttons |= Qt::LeftButton;
+ if (!(status & MOUSE_SYS_BUTTON2UP))
+ m_buttons |= Qt::MiddleButton;
+ if (!(status & MOUSE_SYS_BUTTON3UP))
+ m_buttons |= Qt::RightButton;
+
+ QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/generic/bsdmouse/qbsdmouse.h b/src/plugins/generic/bsdmouse/qbsdmouse.h
new file mode 100644
index 0000000000..9a4cb8dd82
--- /dev/null
+++ b/src/plugins/generic/bsdmouse/qbsdmouse.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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.
+**
+** 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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBSDMOUSE_H
+#define QBSDMOUSE_H
+
+#include <QString>
+#include <QScopedPointer>
+#include <QSocketNotifier>
+
+#include <qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSocketNotifier;
+
+class QBsdMouseHandler : public QObject
+{
+ Q_OBJECT
+public:
+ QBsdMouseHandler(const QString &key, const QString &specification);
+ ~QBsdMouseHandler() override;
+
+private:
+ void readMouseData();
+
+private:
+ QScopedPointer<QSocketNotifier> m_notifier;
+ int m_devFd = -1;
+ int m_packetSize = 0;
+ int m_x = 0;
+ int m_y = 0;
+ int m_xOffset = 0;
+ int m_yOffset = 0;
+ Qt::MouseButtons m_buttons = Qt::NoButton;
+};
+
+QT_END_NAMESPACE
+
+#endif // QBSDMOUSE_H
diff --git a/src/plugins/generic/generic.pro b/src/plugins/generic/generic.pro
index 0c1943b7dd..182a60fdb5 100644
--- a/src/plugins/generic/generic.pro
+++ b/src/plugins/generic/generic.pro
@@ -17,3 +17,7 @@ contains(QT_CONFIG, tslib) {
contains(QT_CONFIG, libinput) {
SUBDIRS += libinput
}
+
+freebsd {
+ SUBDIRS += bsdkeyboard bsdmouse
+}