Add a way to access loadKeymap on eglfs

[ChangeLog][QtGui] Keymaps are now changeable at runtime when using eglfs

Task-number: QTBUG-39583
Change-Id: I93480da72c1d1d1db1914298fe624cae02b0b2d0
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Reviewed-by: Will Wagner <willw@carallon.com>
This commit is contained in:
Laszlo Agocs 2014-06-17 12:28:15 +02:00
parent 27dc07fa05
commit 186354ee51
10 changed files with 205 additions and 8 deletions

View File

@ -0,0 +1 @@
HEADERS += $$PWD/qeglfsfunctions.h

View File

@ -0,0 +1,67 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QEGLFSFUNCTIONS_H
#define QEGLFSFUNCTIONS_H
#include <QtCore/QByteArray>
#include <QtGui/QGuiApplication>
QT_BEGIN_NAMESPACE
class QEglFSFunctions
{
public:
typedef void (*LoadKeymapType)(const QString &filename);
static QByteArray loadKeymapTypeIdentifier() { return QByteArrayLiteral("EglFSLoadKeymap"); }
static void loadKeymap(const QString &filename)
{
LoadKeymapType func = reinterpret_cast<LoadKeymapType>(QGuiApplication::platformFunction(loadKeymapTypeIdentifier()));
if (func)
func(filename);
}
};
QT_END_NAMESPACE
#endif // QEGLFSFUNCTIONS_H

View File

@ -0,0 +1,63 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\class QEglFSFunctions
\inmodule QtPlatformHeaders
\brief The QEglFSFunctions class is an inline class containing
platform-specific functionality for the eglfs platform plugin that is
typically used on systems running Embedded Linux or Android.
*/
/*!
\typedef QEglFSFunctions::LoadKeymapType
Function type for loadKeymap.
*/
/*!
\fn QByteArray QEglFSFunctions::loadKeymapTypeIdentifier()
\return the identifier that can be passed to
QGuiApplication::platformFunction() to query the entry point for the
loadKeymap function implementation.
*/
/*!
\fn void QEglFSFunctions::loadKeymap(const QString &filename)
Loads and switches to the keymap from \a filename. When \a filename is
empty, the default keymap, which is either the built-on one or the keymap
given in the plugin specification, is restored.
\note This is functional only when the evdev keyboard support code is
compiled in to the platform plugin. When using external generic plugins via
the \c{-plugin} argument, or when the environment variable
\c{QT_QPA_EGLFS_DISABLE_INPUT} is set or when building Qt without evdev
support, this function will have no effect.
*/

View File

@ -5,6 +5,7 @@ MODULE_INCNAME = QtPlatformHeaders
include(nativecontexts/nativecontexts.pri) include(nativecontexts/nativecontexts.pri)
include(xcbfunctions/xcbfunctions.pri) include(xcbfunctions/xcbfunctions.pri)
include(eglfsfunctions/eglfsfunctions.pri)
QMAKE_DOCS = $$PWD/doc/qtplatformheaders.qdocconf QMAKE_DOCS = $$PWD/doc/qtplatformheaders.qdocconf

View File

@ -43,6 +43,7 @@
#include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLContext>
#include <QtGui/QOffscreenSurface> #include <QtGui/QOffscreenSurface>
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatforminputcontextfactory_p.h> #include <qpa/qplatforminputcontextfactory_p.h>
@ -57,6 +58,8 @@
#include <QtPlatformSupport/private/qevdevtouch_p.h> #include <QtPlatformSupport/private/qevdevtouch_p.h>
#endif #endif
#include <QtPlatformHeaders/qeglfsfunctions.h>
#include "qeglplatformintegration_p.h" #include "qeglplatformintegration_p.h"
#include "qeglplatformcontext_p.h" #include "qeglplatformcontext_p.h"
#include "qeglplatformwindow_p.h" #include "qeglplatformwindow_p.h"
@ -93,7 +96,8 @@ QEGLPlatformIntegration::QEGLPlatformIntegration()
m_display(EGL_NO_DISPLAY), m_display(EGL_NO_DISPLAY),
m_inputContext(0), m_inputContext(0),
m_fontDb(new QGenericUnixFontDatabase), m_fontDb(new QGenericUnixFontDatabase),
m_services(new QGenericUnixServices) m_services(new QGenericUnixServices),
m_kbdMgr(0)
{ {
} }
@ -314,10 +318,33 @@ QPlatformNativeInterface::NativeResourceForContextFunction QEGLPlatformIntegrati
return 0; return 0;
} }
QFunctionPointer QEGLPlatformIntegration::platformFunction(const QByteArray &function) const
{
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
if (function == QEglFSFunctions::loadKeymapTypeIdentifier())
return QFunctionPointer(loadKeymapStatic);
#endif
return 0;
}
void QEGLPlatformIntegration::loadKeymapStatic(const QString &filename)
{
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
QEGLPlatformIntegration *self = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration());
if (self->m_kbdMgr)
self->m_kbdMgr->loadKeymap(filename);
else
qWarning("QEGLPlatformIntegration: Cannot load keymap, no keyboard handler found");
#else
Q_UNUSED(filename);
#endif
}
void QEGLPlatformIntegration::createInputHandlers() void QEGLPlatformIntegration::createInputHandlers()
{ {
#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)) #if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this); m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
QEvdevMouseManager *mouseMgr = new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this); QEvdevMouseManager *mouseMgr = new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
Q_FOREACH (QScreen *screen, QGuiApplication::screens()) { Q_FOREACH (QScreen *screen, QGuiApplication::screens()) {
QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(screen->handle()->cursor()); QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(screen->handle()->cursor());

View File

@ -53,6 +53,7 @@ class QEGLPlatformScreen;
class QEGLPlatformWindow; class QEGLPlatformWindow;
class QEGLPlatformContext; class QEGLPlatformContext;
class QFbVtHandler; class QFbVtHandler;
class QEvdevKeyboardManager;
class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface
{ {
@ -85,6 +86,8 @@ public:
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE; void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE; NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
protected: protected:
virtual QEGLPlatformScreen *createScreen() const = 0; virtual QEGLPlatformScreen *createScreen() const = 0;
virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0; virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0;
@ -101,12 +104,15 @@ protected:
void createInputHandlers(); void createInputHandlers();
private: private:
static void loadKeymapStatic(const QString &filename);
QEGLPlatformScreen *m_screen; QEGLPlatformScreen *m_screen;
EGLDisplay m_display; EGLDisplay m_display;
QPlatformInputContext *m_inputContext; QPlatformInputContext *m_inputContext;
QScopedPointer<QPlatformFontDatabase> m_fontDb; QScopedPointer<QPlatformFontDatabase> m_fontDb;
QScopedPointer<QPlatformServices> m_services; QScopedPointer<QPlatformServices> m_services;
QScopedPointer<QFbVtHandler> m_vtHandler; QScopedPointer<QFbVtHandler> m_vtHandler;
QEvdevKeyboardManager *m_kbdMgr;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -93,13 +93,15 @@ QEvdevKeyboardHandler::~QEvdevKeyboardHandler()
qt_safe_close(m_fd); qt_safe_close(m_fd);
} }
QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, const QString &specification) QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device,
const QString &specification,
const QString &defaultKeymapFile)
{ {
#ifdef QT_QPA_KEYMAP_DEBUG #ifdef QT_QPA_KEYMAP_DEBUG
qWarning() << "Try to create keyboard handler for" << device << specification; qWarning() << "Try to create keyboard handler for" << device << specification;
#endif #endif
QString keymapFile; QString keymapFile = defaultKeymapFile;
int repeatDelay = 400; int repeatDelay = 400;
int repeatRate = 80; int repeatRate = 80;
bool disableZap = false; bool disableZap = false;

View File

@ -145,7 +145,9 @@ public:
SwitchConsoleMask = 0x0000007f SwitchConsoleMask = 0x0000007f
}; };
static QEvdevKeyboardHandler *create(const QString &device, const QString &specification); static QEvdevKeyboardHandler *create(const QString &device,
const QString &specification,
const QString &defaultKeymapFile = QString());
static Qt::KeyboardModifiers toQtModifiers(quint8 mod) static Qt::KeyboardModifiers toQtModifiers(quint8 mod)
{ {
@ -161,13 +163,14 @@ public:
return qtmod; return qtmod;
} }
bool loadKeymap(const QString &file);
void unloadKeymap();
private slots: private slots:
void readKeycode(); void readKeycode();
KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat); KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat);
private: private:
void unloadKeymap();
bool loadKeymap(const QString &file);
void processKeyEvent(int nativecode, int unicode, int qtcode, void processKeyEvent(int nativecode, int unicode, int qtcode,
Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat); Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat);
void switchLed(int, bool); void switchLed(int, bool);

View File

@ -113,7 +113,7 @@ void QEvdevKeyboardManager::addKeyboard(const QString &deviceNode)
#endif #endif
QEvdevKeyboardHandler *keyboard; QEvdevKeyboardHandler *keyboard;
keyboard = QEvdevKeyboardHandler::create(deviceNode, m_spec); keyboard = QEvdevKeyboardHandler::create(deviceNode, m_spec, m_defaultKeymapFile);
if (keyboard) if (keyboard)
m_keyboards.insert(deviceNode, keyboard); m_keyboards.insert(deviceNode, keyboard);
else else
@ -132,4 +132,28 @@ void QEvdevKeyboardManager::removeKeyboard(const QString &deviceNode)
} }
} }
void QEvdevKeyboardManager::loadKeymap(const QString &file)
{
m_defaultKeymapFile = file;
if (file.isEmpty()) {
// Restore the default, which is either the built-in keymap or
// the one given in the plugin spec.
QString keymapFromSpec;
foreach (const QString &arg, m_spec.split(QLatin1Char(':'))) {
if (arg.startsWith(QLatin1String("keymap=")))
keymapFromSpec = arg.mid(7);
}
foreach (QEvdevKeyboardHandler *handler, m_keyboards) {
if (keymapFromSpec.isEmpty())
handler->unloadKeymap();
else
handler->loadKeymap(keymapFromSpec);
}
} else {
foreach (QEvdevKeyboardHandler *handler, m_keyboards)
handler->loadKeymap(file);
}
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -59,6 +59,8 @@ public:
QEvdevKeyboardManager(const QString &key, const QString &specification, QObject *parent = 0); QEvdevKeyboardManager(const QString &key, const QString &specification, QObject *parent = 0);
~QEvdevKeyboardManager(); ~QEvdevKeyboardManager();
void loadKeymap(const QString &file);
private slots: private slots:
void addKeyboard(const QString &deviceNode = QString()); void addKeyboard(const QString &deviceNode = QString());
void removeKeyboard(const QString &deviceNode); void removeKeyboard(const QString &deviceNode);
@ -67,6 +69,7 @@ private:
QString m_spec; QString m_spec;
QHash<QString,QEvdevKeyboardHandler*> m_keyboards; QHash<QString,QEvdevKeyboardHandler*> m_keyboards;
QDeviceDiscovery *m_deviceDiscovery; QDeviceDiscovery *m_deviceDiscovery;
QString m_defaultKeymapFile;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE