summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client/client.pro2
-rw-r--r--src/client/qwaylandinputdevice.cpp158
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor.cpp53
-rw-r--r--src/compositor/wayland_wrapper/qwlcompositor_p.h2
-rw-r--r--src/compositor/wayland_wrapper/qwlkeyboard.cpp21
-rw-r--r--src/compositor/wayland_wrapper/qwlkeyboard_p.h10
-rw-r--r--src/compositor/wayland_wrapper/wayland_wrapper.pri2
-rw-r--r--src/shared/qwaylandxkb.cpp202
-rw-r--r--src/shared/qwaylandxkb.h56
9 files changed, 341 insertions, 165 deletions
diff --git a/src/client/client.pro b/src/client/client.pro
index 29016c9c8..ba17b21c5 100644
--- a/src/client/client.pro
+++ b/src/client/client.pro
@@ -75,6 +75,7 @@ SOURCES += qwaylandintegration.cpp \
qwaylandtouch.cpp \
qwaylandqtkey.cpp \
../shared/qwaylandmimehelper.cpp \
+ ../shared/qwaylandxkb.cpp \
qwaylandabstractdecoration.cpp \
qwaylanddecorationfactory.cpp \
qwaylanddecorationplugin.cpp \
@@ -107,6 +108,7 @@ HEADERS += qwaylandintegration_p.h \
qwaylandtouch_p.h \
qwaylandqtkey_p.h \
../shared/qwaylandmimehelper.h \
+ ../shared/qwaylandxkb.h \
qwaylandabstractdecoration_p.h \
qwaylanddecorationfactory_p.h \
qwaylanddecorationplugin_p.h \
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
index 009ef670e..9ac678c93 100644
--- a/src/client/qwaylandinputdevice.cpp
+++ b/src/client/qwaylandinputdevice.cpp
@@ -42,6 +42,7 @@
#include "qwaylandscreen_p.h"
#include "qwaylandcursor_p.h"
#include "qwaylanddisplay_p.h"
+#include "../shared/qwaylandxkb.h"
#include <QtGui/private/qpixmap_raster_p.h>
#include <qpa/qplatformwindow.h>
@@ -302,16 +303,7 @@ Qt::KeyboardModifiers QWaylandInputDevice::Keyboard::modifiers() const
if (!mXkbState)
return ret;
- xkb_state_component cstate = static_cast<xkb_state_component>(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED);
-
- if (xkb_state_mod_name_is_active(mXkbState, XKB_MOD_NAME_SHIFT, cstate))
- ret |= Qt::ShiftModifier;
- if (xkb_state_mod_name_is_active(mXkbState, XKB_MOD_NAME_CTRL, cstate))
- ret |= Qt::ControlModifier;
- if (xkb_state_mod_name_is_active(mXkbState, XKB_MOD_NAME_ALT, cstate))
- ret |= Qt::AltModifier;
- if (xkb_state_mod_name_is_active(mXkbState, XKB_MOD_NAME_LOGO, cstate))
- ret |= Qt::MetaModifier;
+ ret = QWaylandXkb::modifiers(mXkbState);
#endif
return ret;
@@ -530,150 +522,6 @@ void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, in
window->handleMouse(mParent, e);
}
-#ifndef QT_NO_WAYLAND_XKB
-
-static const uint32_t KeyTbl[] = {
- XKB_KEY_Escape, Qt::Key_Escape,
- XKB_KEY_Tab, Qt::Key_Tab,
- XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab,
- XKB_KEY_BackSpace, Qt::Key_Backspace,
- XKB_KEY_Return, Qt::Key_Return,
- XKB_KEY_Insert, Qt::Key_Insert,
- XKB_KEY_Delete, Qt::Key_Delete,
- XKB_KEY_Clear, Qt::Key_Delete,
- XKB_KEY_Pause, Qt::Key_Pause,
- XKB_KEY_Print, Qt::Key_Print,
-
- XKB_KEY_Home, Qt::Key_Home,
- XKB_KEY_End, Qt::Key_End,
- XKB_KEY_Left, Qt::Key_Left,
- XKB_KEY_Up, Qt::Key_Up,
- XKB_KEY_Right, Qt::Key_Right,
- XKB_KEY_Down, Qt::Key_Down,
- XKB_KEY_Prior, Qt::Key_PageUp,
- XKB_KEY_Next, Qt::Key_PageDown,
-
- XKB_KEY_Shift_L, Qt::Key_Shift,
- XKB_KEY_Shift_R, Qt::Key_Shift,
- XKB_KEY_Shift_Lock, Qt::Key_Shift,
- XKB_KEY_Control_L, Qt::Key_Control,
- XKB_KEY_Control_R, Qt::Key_Control,
- XKB_KEY_Meta_L, Qt::Key_Meta,
- XKB_KEY_Meta_R, Qt::Key_Meta,
- XKB_KEY_Alt_L, Qt::Key_Alt,
- XKB_KEY_Alt_R, Qt::Key_Alt,
- XKB_KEY_Caps_Lock, Qt::Key_CapsLock,
- XKB_KEY_Num_Lock, Qt::Key_NumLock,
- XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock,
- XKB_KEY_Super_L, Qt::Key_Super_L,
- XKB_KEY_Super_R, Qt::Key_Super_R,
- XKB_KEY_Menu, Qt::Key_Menu,
- XKB_KEY_Hyper_L, Qt::Key_Hyper_L,
- XKB_KEY_Hyper_R, Qt::Key_Hyper_R,
- XKB_KEY_Help, Qt::Key_Help,
-
- XKB_KEY_KP_Space, Qt::Key_Space,
- XKB_KEY_KP_Tab, Qt::Key_Tab,
- XKB_KEY_KP_Enter, Qt::Key_Enter,
- XKB_KEY_KP_Home, Qt::Key_Home,
- XKB_KEY_KP_Left, Qt::Key_Left,
- XKB_KEY_KP_Up, Qt::Key_Up,
- XKB_KEY_KP_Right, Qt::Key_Right,
- XKB_KEY_KP_Down, Qt::Key_Down,
- XKB_KEY_KP_Prior, Qt::Key_PageUp,
- XKB_KEY_KP_Next, Qt::Key_PageDown,
- XKB_KEY_KP_End, Qt::Key_End,
- XKB_KEY_KP_Begin, Qt::Key_Clear,
- XKB_KEY_KP_Insert, Qt::Key_Insert,
- XKB_KEY_KP_Delete, Qt::Key_Delete,
- XKB_KEY_KP_Equal, Qt::Key_Equal,
- XKB_KEY_KP_Multiply, Qt::Key_Asterisk,
- XKB_KEY_KP_Add, Qt::Key_Plus,
- XKB_KEY_KP_Separator, Qt::Key_Comma,
- XKB_KEY_KP_Subtract, Qt::Key_Minus,
- XKB_KEY_KP_Decimal, Qt::Key_Period,
- XKB_KEY_KP_Divide, Qt::Key_Slash,
-
- XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr,
- XKB_KEY_Multi_key, Qt::Key_Multi_key,
- XKB_KEY_Codeinput, Qt::Key_Codeinput,
- XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate,
- XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate,
- XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate,
-
- XKB_KEY_Mode_switch, Qt::Key_Mode_switch,
- XKB_KEY_script_switch, Qt::Key_Mode_switch,
-
- XKB_KEY_XF86Back, Qt::Key_Back,
- XKB_KEY_XF86Forward, Qt::Key_Forward,
-
- XKB_KEY_XF86AudioPlay, Qt::Key_MediaTogglePlayPause, //there isn't a PlayPause keysym, however just play keys are not common
- XKB_KEY_XF86AudioPause, Qt::Key_MediaPause,
- XKB_KEY_XF86AudioStop, Qt::Key_MediaStop,
- XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious,
- XKB_KEY_XF86AudioNext, Qt::Key_MediaNext,
- XKB_KEY_XF86AudioRewind, Qt::Key_MediaPrevious,
- XKB_KEY_XF86AudioForward, Qt::Key_MediaNext,
- XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord,
-
- XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute,
- XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown,
- XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp,
-
- XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay,
- XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat,
-
- XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn,
- XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut,
-
- XKB_KEY_XF86Eject, Qt::Key_Eject,
-
- 0, 0
-};
-
-static int keysymToQtKey(xkb_keysym_t key)
-{
- int code = 0;
- int i = 0;
- while (KeyTbl[i]) {
- if (key == KeyTbl[i]) {
- code = (int)KeyTbl[i+1];
- break;
- }
- i += 2;
- }
-
- return code;
-}
-
-static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text)
-{
- int code = 0;
-
- if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
- code = Qt::Key_F1 + (int(keysym) - XKB_KEY_F1);
- } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) {
- if (keysym >= XKB_KEY_KP_0) {
- // numeric keypad keys
- code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0);
- } else {
- code = keysymToQtKey(keysym);
- }
- modifiers |= Qt::KeypadModifier;
- } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f
- && text.unicode()->unicode() != 0x7f
- && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_currency)) {
- code = text.unicode()->toUpper().unicode();
- } else {
- // any other keys
- code = keysymToQtKey(keysym);
- }
-
- return code;
-}
-
-#endif // QT_NO_WAYLAND_XKB
-
void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size)
{
#ifndef QT_NO_WAYLAND_XKB
@@ -795,7 +643,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time,
if (utf32)
text = QString::fromUcs4(&utf32, 1);
- qtkey = keysymToQtKey(sym, modifiers, text);
+ qtkey = QWaylandXkb::keysymToQtKey(sym, modifiers, text);
QWindowSystemInterface::handleExtendedKeyEvent(window->window(),
time, type, qtkey,
diff --git a/src/compositor/wayland_wrapper/qwlcompositor.cpp b/src/compositor/wayland_wrapper/qwlcompositor.cpp
index 303b9601a..f8c8bdc1f 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor.cpp
+++ b/src/compositor/wayland_wrapper/qwlcompositor.cpp
@@ -63,6 +63,7 @@
#include "qwaylandsurfaceview.h"
#include "qwaylandshmformathelper.h"
#include "qwaylandoutput.h"
+#include "qwlkeyboard_p.h"
#include <QWindow>
#include <QSocketNotifier>
@@ -98,12 +99,61 @@
#include "hardware_integration/qwlclientbufferintegrationfactory_p.h"
#include "hardware_integration/qwlserverbufferintegrationfactory_p.h"
+#include "../shared/qwaylandxkb.h"
+
QT_BEGIN_NAMESPACE
namespace QtWayland {
static Compositor *compositor;
+class WindowSystemEventHandler : public QWindowSystemEventHandler
+{
+public:
+ WindowSystemEventHandler(Compositor *c) : compositor(c) {}
+ bool sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) Q_DECL_OVERRIDE
+ {
+ if (e->type == QWindowSystemInterfacePrivate::Key) {
+ QWindowSystemInterfacePrivate::KeyEvent *ke = static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e);
+ Keyboard *keyb = compositor->defaultInputDevice()->keyboardDevice();
+
+ uint32_t code = ke->nativeScanCode;
+ bool isDown = ke->keyType == QEvent::KeyPress;
+
+#ifndef QT_NO_WAYLAND_XKB
+ QString text;
+ Qt::KeyboardModifiers modifiers = QWaylandXkb::modifiers(keyb->xkbState());
+
+ const xkb_keysym_t sym = xkb_state_key_get_one_sym(keyb->xkbState(), code);
+ uint utf32 = xkb_keysym_to_utf32(sym);
+ if (utf32)
+ text = QString::fromUcs4(&utf32, 1);
+ int qtkey = QWaylandXkb::keysymToQtKey(sym, modifiers, text);
+
+ ke->key = qtkey;
+ ke->modifiers = modifiers;
+ ke->nativeVirtualKey = sym;
+ ke->nativeModifiers = keyb->xkbModsMask();
+ ke->unicode = text;
+#endif
+ if (!ke->repeat)
+ keyb->keyEvent(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
+
+ QWindowSystemEventHandler::sendEvent(e);
+
+ if (!ke->repeat) {
+ keyb->updateKeymap();
+ keyb->updateModifierState(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
+ }
+ } else {
+ QWindowSystemEventHandler::sendEvent(e);
+ }
+ return true;
+ }
+
+ Compositor *compositor;
+};
+
Compositor *Compositor::instance()
{
return compositor;
@@ -128,10 +178,13 @@ Compositor::Compositor(QWaylandCompositor *qt_compositor, QWaylandCompositor::Ex
, m_qtkeyExtension(0)
, m_textInputManager()
, m_inputPanel()
+ , m_eventHandler(new WindowSystemEventHandler(this))
, m_retainSelection(false)
{
m_timer.start();
compositor = this;
+
+ QWindowSystemInterfacePrivate::installWindowSystemEventHandler(m_eventHandler.data());
}
void Compositor::init()
diff --git a/src/compositor/wayland_wrapper/qwlcompositor_p.h b/src/compositor/wayland_wrapper/qwlcompositor_p.h
index 04a9e317c..7360e7dca 100644
--- a/src/compositor/wayland_wrapper/qwlcompositor_p.h
+++ b/src/compositor/wayland_wrapper/qwlcompositor_p.h
@@ -66,6 +66,7 @@ class WindowManagerServerIntegration;
class QMimeData;
class QPlatformScreenBuffer;
class QWaylandSurface;
+class QWindowSystemEventHandler;
namespace QtWayland {
@@ -220,6 +221,7 @@ protected:
QScopedPointer<TextInputManager> m_textInputManager;
QScopedPointer<InputPanel> m_inputPanel;
QList<QWaylandGlobalInterface *> m_globals;
+ QScopedPointer<QWindowSystemEventHandler> m_eventHandler;
static void bind_func(struct wl_client *client, void *data,
uint32_t version, uint32_t id);
diff --git a/src/compositor/wayland_wrapper/qwlkeyboard.cpp b/src/compositor/wayland_wrapper/qwlkeyboard.cpp
index 5af3e8c29..bcee40fb4 100644
--- a/src/compositor/wayland_wrapper/qwlkeyboard.cpp
+++ b/src/compositor/wayland_wrapper/qwlkeyboard.cpp
@@ -223,12 +223,9 @@ void Keyboard::key(uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
}
}
-void Keyboard::sendKeyEvent(uint code, uint32_t state)
+void Keyboard::keyEvent(uint code, uint32_t state)
{
- uint32_t time = m_compositor->currentTimeMsecs();
- uint32_t serial = wl_display_next_serial(m_compositor->wl_display());
uint key = code - 8;
- m_grab->key(serial, time, key, state);
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
m_keys << key;
} else {
@@ -238,11 +235,14 @@ void Keyboard::sendKeyEvent(uint code, uint32_t state)
}
}
}
- updateModifierState(code, state);
+}
- // If keys are no longer pressed, update the keymap
- if (m_pendingKeymap && m_keys.isEmpty())
- updateKeymap();
+void Keyboard::sendKeyEvent(uint code, uint32_t state)
+{
+ uint32_t time = m_compositor->currentTimeMsecs();
+ uint32_t serial = wl_display_next_serial(m_compositor->wl_display());
+ uint key = code - 8;
+ m_grab->key(serial, time, key, state);
}
void Keyboard::modifiers(uint32_t serial, uint32_t mods_depressed,
@@ -286,6 +286,11 @@ void Keyboard::updateModifierState(uint code, uint32_t state)
void Keyboard::updateKeymap()
{
+ // There must be no keys pressed when changing the keymap,
+ // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html
+ if (!m_pendingKeymap || !m_keys.isEmpty())
+ return;
+
m_pendingKeymap = false;
#ifndef QT_NO_WAYLAND_XKB
if (!m_context)
diff --git a/src/compositor/wayland_wrapper/qwlkeyboard_p.h b/src/compositor/wayland_wrapper/qwlkeyboard_p.h
index 44503114e..d394aad1b 100644
--- a/src/compositor/wayland_wrapper/qwlkeyboard_p.h
+++ b/src/compositor/wayland_wrapper/qwlkeyboard_p.h
@@ -99,10 +99,18 @@ public:
void modifiers(uint32_t serial, uint32_t mods_depressed,
uint32_t mods_latched, uint32_t mods_locked, uint32_t group);
+ void keyEvent(uint code, uint32_t state);
+ void updateModifierState(uint code, uint32_t state);
+ void updateKeymap();
+
void startGrab(KeyboardGrabber *grab);
void endGrab();
KeyboardGrabber *currentGrab() const;
+#ifndef QT_NO_WAYLAND_XKB
+ struct xkb_state *xkbState() const { return m_state; }
+ uint32_t xkbModsMask() const { return m_modsDepressed | m_modsLatched | m_modsLocked; }
+#endif
Q_SIGNALS:
void focusChanged(Surface *surface);
@@ -114,8 +122,6 @@ protected:
private:
void sendKeyEvent(uint code, uint32_t state);
- void updateModifierState(uint code, uint32_t state);
- void updateKeymap();
void focusDestroyed(void *data);
#ifndef QT_NO_WAYLAND_XKB
diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri
index d70facd5c..eb66f6949 100644
--- a/src/compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri
@@ -36,6 +36,7 @@ HEADERS += \
wayland_wrapper/qwltextinputmanager_p.h \
wayland_wrapper/qwltouch_p.h \
wayland_wrapper/qwllistener_p.h \
+ ../shared/qwaylandxkb.h \
SOURCES += \
wayland_wrapper/qwlcompositor.cpp \
@@ -64,6 +65,7 @@ SOURCES += \
wayland_wrapper/qwltextinputmanager.cpp \
wayland_wrapper/qwltouch.cpp \
wayland_wrapper/qwllistener.cpp \
+ ../shared/qwaylandxkb.cpp \
INCLUDEPATH += wayland_wrapper
diff --git a/src/shared/qwaylandxkb.cpp b/src/shared/qwaylandxkb.cpp
new file mode 100644
index 000000000..c947902bd
--- /dev/null
+++ b/src/shared/qwaylandxkb.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Jolla Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins 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 "qwaylandxkb.h"
+
+#include <QString>
+
+#ifndef QT_NO_WAYLAND_XKB
+
+#include <xkbcommon/xkbcommon-keysyms.h>
+
+QT_BEGIN_NAMESPACE
+
+static const uint32_t KeyTbl[] = {
+ XKB_KEY_Escape, Qt::Key_Escape,
+ XKB_KEY_Tab, Qt::Key_Tab,
+ XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab,
+ XKB_KEY_BackSpace, Qt::Key_Backspace,
+ XKB_KEY_Return, Qt::Key_Return,
+ XKB_KEY_Insert, Qt::Key_Insert,
+ XKB_KEY_Delete, Qt::Key_Delete,
+ XKB_KEY_Clear, Qt::Key_Delete,
+ XKB_KEY_Pause, Qt::Key_Pause,
+ XKB_KEY_Print, Qt::Key_Print,
+
+ XKB_KEY_Home, Qt::Key_Home,
+ XKB_KEY_End, Qt::Key_End,
+ XKB_KEY_Left, Qt::Key_Left,
+ XKB_KEY_Up, Qt::Key_Up,
+ XKB_KEY_Right, Qt::Key_Right,
+ XKB_KEY_Down, Qt::Key_Down,
+ XKB_KEY_Prior, Qt::Key_PageUp,
+ XKB_KEY_Next, Qt::Key_PageDown,
+
+ XKB_KEY_Shift_L, Qt::Key_Shift,
+ XKB_KEY_Shift_R, Qt::Key_Shift,
+ XKB_KEY_Shift_Lock, Qt::Key_Shift,
+ XKB_KEY_Control_L, Qt::Key_Control,
+ XKB_KEY_Control_R, Qt::Key_Control,
+ XKB_KEY_Meta_L, Qt::Key_Meta,
+ XKB_KEY_Meta_R, Qt::Key_Meta,
+ XKB_KEY_Alt_L, Qt::Key_Alt,
+ XKB_KEY_Alt_R, Qt::Key_Alt,
+ XKB_KEY_Caps_Lock, Qt::Key_CapsLock,
+ XKB_KEY_Num_Lock, Qt::Key_NumLock,
+ XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock,
+ XKB_KEY_Super_L, Qt::Key_Super_L,
+ XKB_KEY_Super_R, Qt::Key_Super_R,
+ XKB_KEY_Menu, Qt::Key_Menu,
+ XKB_KEY_Hyper_L, Qt::Key_Hyper_L,
+ XKB_KEY_Hyper_R, Qt::Key_Hyper_R,
+ XKB_KEY_Help, Qt::Key_Help,
+
+ XKB_KEY_KP_Space, Qt::Key_Space,
+ XKB_KEY_KP_Tab, Qt::Key_Tab,
+ XKB_KEY_KP_Enter, Qt::Key_Enter,
+ XKB_KEY_KP_Home, Qt::Key_Home,
+ XKB_KEY_KP_Left, Qt::Key_Left,
+ XKB_KEY_KP_Up, Qt::Key_Up,
+ XKB_KEY_KP_Right, Qt::Key_Right,
+ XKB_KEY_KP_Down, Qt::Key_Down,
+ XKB_KEY_KP_Prior, Qt::Key_PageUp,
+ XKB_KEY_KP_Next, Qt::Key_PageDown,
+ XKB_KEY_KP_End, Qt::Key_End,
+ XKB_KEY_KP_Begin, Qt::Key_Clear,
+ XKB_KEY_KP_Insert, Qt::Key_Insert,
+ XKB_KEY_KP_Delete, Qt::Key_Delete,
+ XKB_KEY_KP_Equal, Qt::Key_Equal,
+ XKB_KEY_KP_Multiply, Qt::Key_Asterisk,
+ XKB_KEY_KP_Add, Qt::Key_Plus,
+ XKB_KEY_KP_Separator, Qt::Key_Comma,
+ XKB_KEY_KP_Subtract, Qt::Key_Minus,
+ XKB_KEY_KP_Decimal, Qt::Key_Period,
+ XKB_KEY_KP_Divide, Qt::Key_Slash,
+
+ XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr,
+ XKB_KEY_Multi_key, Qt::Key_Multi_key,
+ XKB_KEY_Codeinput, Qt::Key_Codeinput,
+ XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate,
+ XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate,
+ XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate,
+
+ XKB_KEY_Mode_switch, Qt::Key_Mode_switch,
+ XKB_KEY_script_switch, Qt::Key_Mode_switch,
+
+ XKB_KEY_XF86AudioPlay, Qt::Key_MediaTogglePlayPause, //there isn't a PlayPause keysym, however just play keys are not common
+ XKB_KEY_XF86AudioPause, Qt::Key_MediaPause,
+ XKB_KEY_XF86AudioStop, Qt::Key_MediaStop,
+ XKB_KEY_XF86AudioPrev, Qt::Key_MediaPrevious,
+ XKB_KEY_XF86AudioNext, Qt::Key_MediaNext,
+ XKB_KEY_XF86AudioRewind, Qt::Key_MediaPrevious,
+ XKB_KEY_XF86AudioForward, Qt::Key_MediaNext,
+ XKB_KEY_XF86AudioRecord, Qt::Key_MediaRecord,
+
+ XKB_KEY_XF86AudioMute, Qt::Key_VolumeMute,
+ XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown,
+ XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp,
+
+ XKB_KEY_XF86AudioRandomPlay, Qt::Key_AudioRandomPlay,
+ XKB_KEY_XF86AudioRepeat, Qt::Key_AudioRepeat,
+
+ XKB_KEY_XF86ZoomIn, Qt::Key_ZoomIn,
+ XKB_KEY_XF86ZoomOut, Qt::Key_ZoomOut,
+
+ XKB_KEY_XF86Eject, Qt::Key_Eject,
+
+ 0, 0
+};
+
+static int lookupKeysym(xkb_keysym_t key)
+{
+ int code = 0;
+ int i = 0;
+ while (KeyTbl[i]) {
+ if (key == KeyTbl[i]) {
+ code = (int)KeyTbl[i+1];
+ break;
+ }
+ i += 2;
+ }
+
+ return code;
+}
+
+int QWaylandXkb::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text)
+{
+ int code = 0;
+
+ if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) {
+ code = Qt::Key_F1 + (int(keysym) - XKB_KEY_F1);
+ } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) {
+ if (keysym >= XKB_KEY_KP_0) {
+ // numeric keypad keys
+ code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0);
+ } else {
+ code = lookupKeysym(keysym);
+ }
+ modifiers |= Qt::KeypadModifier;
+ } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f
+ && text.unicode()->unicode() != 0x7f
+ && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_currency)) {
+ code = text.unicode()->toUpper().unicode();
+ } else {
+ // any other keys
+ code = lookupKeysym(keysym);
+ }
+
+ return code;
+}
+
+Qt::KeyboardModifiers QWaylandXkb::modifiers(struct xkb_state *state)
+{
+ Qt::KeyboardModifiers modifiers = Qt::NoModifier;
+
+ xkb_state_component cstate = static_cast<xkb_state_component>(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED);
+
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, cstate))
+ modifiers |= Qt::ShiftModifier;
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, cstate))
+ modifiers |= Qt::ControlModifier;
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, cstate))
+ modifiers |= Qt::AltModifier;
+ if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_LOGO, cstate))
+ modifiers |= Qt::MetaModifier;
+
+ return modifiers;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_WAYLAND_XKB
diff --git a/src/shared/qwaylandxkb.h b/src/shared/qwaylandxkb.h
new file mode 100644
index 000000000..91e69ab03
--- /dev/null
+++ b/src/shared/qwaylandxkb.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2015 Jolla Ltd
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins 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 QWAYLANDXKB_H
+#define QWAYLANDXKB_H
+
+#ifndef QT_NO_WAYLAND_XKB
+
+#include <Qt>
+#include <xkbcommon/xkbcommon.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandXkb
+{
+public:
+ static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, const QString &text);
+ static Qt::KeyboardModifiers modifiers(struct xkb_state *state);
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_WAYLAND_XKB
+
+#endif