Ability to switch language under platform eglfs/linuxfb

I need to change keymap under platforms eglfs and linuxfb (without wayland).
I use the function QEglFSFunctions::loadKeymap(const QString&), but there's
no way to switch between english and another language than to press AltGr as
a modifier. I added the function that allows to change the language. And also
added the ability to switch the keymap and language for the platform linuxfb

and also added the ability to switch the keymap and language for the platform linuxfb

Task-number: QTBUG-72452
Change-Id: I37432cf60d375555bea2bf668ec1387322b4964f
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Elena Zaretskaya 2019-01-11 10:11:03 -05:00
parent c4e7f3ab65
commit c9b9a0ea2f
14 changed files with 267 additions and 7 deletions

View File

@ -49,7 +49,9 @@ class QEglFSFunctions
{
public:
typedef void (*LoadKeymapType)(const QString &filename);
typedef void (*SwitchLangType)();
static QByteArray loadKeymapTypeIdentifier() { return QByteArrayLiteral("EglFSLoadKeymap"); }
static QByteArray switchLangTypeIdentifier() { return QByteArrayLiteral("EglFSSwitchLang"); }
static void loadKeymap(const QString &filename)
{
@ -58,6 +60,13 @@ public:
func(filename);
}
static void switchLang()
{
SwitchLangType func = reinterpret_cast<SwitchLangType>(QGuiApplication::platformFunction(switchLangTypeIdentifier()));
if (func)
func();
}
typedef int (*Vsp2AddLayerType)(const QScreen *screen, int dmabufFd, const QSize &size, const QPoint &position, uint drmPixelFormat, uint bytesPerLine);
static QByteArray vsp2AddLayerTypeIdentifier() { return QByteArrayLiteral("EglFSVsp2AddLayer"); }

View File

@ -66,6 +66,21 @@
support, this function will have no effect.
*/
/*!
\fn void QEglFSFunctions::switchLang()
Switches between English and other language when the keymap is loaded.
Usually the keymap contains two languages: English and national. When
you load the keymap, English is selected by default. This function allows
to switch between these languages.
\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.
*/
/*!
\fn int QEglFSFunctions::vsp2AddLayer(const QScreen *screen, int dmabufFd, const QSize &size, const QPoint &position, uint drmPixelFormat, uint bytesPerLine)
\internal

View File

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

View File

@ -0,0 +1,74 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QLINUXFBFUNCTIONS_H
#define QLINUXFBFUNCTIONS_H
#include <QtCore/QByteArray>
#include <QtGui/QGuiApplication>
QT_BEGIN_NAMESPACE
class QLinuxFbFunctions
{
public:
typedef void (*LoadKeymapType)(const QString &filename);
typedef void (*SwitchLangType)();
static QByteArray loadKeymapTypeIdentifier() { return QByteArrayLiteral("LinuxFbLoadKeymap"); }
static QByteArray switchLangTypeIdentifier() { return QByteArrayLiteral("LinuxFbSwitchLang"); }
static void loadKeymap(const QString &filename)
{
LoadKeymapType func = reinterpret_cast<LoadKeymapType>(QGuiApplication::platformFunction(loadKeymapTypeIdentifier()));
if (func)
func(filename);
}
static void switchLang()
{
SwitchLangType func = reinterpret_cast<SwitchLangType>(QGuiApplication::platformFunction(switchLangTypeIdentifier()));
if (func)
func();
}
};
QT_END_NAMESPACE
#endif // QLINUXFBFUNCTIONS_H

View File

@ -0,0 +1,82 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/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: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\class QLinuxFbFunctions
\inmodule QtPlatformHeaders
\brief The QLinuxFbFunctions class is an inline class containing
platform-specific functionality for the linuxfb platform plugin that is
typically used on systems running Embedded Linux or Android.
\note There is no binary compatibility guarantee for this class,
meaning that an application using it is only guaranteed to work with the Qt
version it was developed against.
*/
/*!
\typedef QLinuxFbFunctions::LoadKeymapType
Function type for loadKeymap.
*/
/*!
\fn QByteArray QLinuxFbFunctions::loadKeymapTypeIdentifier()
\return the identifier that can be passed to
QGuiApplication::platformFunction() to query the entry point for the
loadKeymap function implementation.
*/
/*!
\fn void QLinuxFbFunctions::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_FB_DISABLE_INPUT} is set or when building Qt without evdev
support, this function will have no effect.
*/
/*!
\fn void QLinuxFbFunctions::switchLang()
Switches between English and other language when the keymap is loaded.
Usually the keymap contains two languages: English and national. When
you load the keymap, English is selected by default. This function allows
to switch between these languages.
\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_FB_DISABLE_INPUT} is set or when building Qt without evdev
support, this function will have no effect.
*/

View File

@ -10,6 +10,7 @@ include(windowsfunctions/windowsfunctions.pri)
include(helper/helper.pri)
include(cocoafunctions/cocoafunctions.pri)
include(waylandfunctions/waylandfunctions.pri)
include(linuxfbfunctions/linuxfbfunctions.pri)
QMAKE_DOCS = $$PWD/doc/qtplatformheaders.qdocconf

View File

@ -76,7 +76,7 @@ void QFdContainer::reset() Q_DECL_NOTHROW
QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, QFdContainer &fd, bool disableZap, bool enableCompose, const QString &keymapFile)
: m_device(device), m_fd(fd.release()), m_notify(nullptr),
m_modifiers(0), m_composing(0), m_dead_unicode(0xffff),
m_no_zap(disableZap), m_do_compose(enableCompose),
m_langLock(0), m_no_zap(disableZap), m_do_compose(enableCompose),
m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0)
{
qCDebug(qLcEvdevKey) << "Create keyboard handler with for device" << device;
@ -253,6 +253,8 @@ QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint
quint8 testmods = m_modifiers;
if (m_locks[0] /*CapsLock*/ && (m->flags & QEvdevKeyboardMap::IsLetter))
testmods ^= QEvdevKeyboardMap::ModShift;
if (m_langLock)
testmods ^= QEvdevKeyboardMap::ModAltGr;
if (m->modifiers == testmods)
map_withmod = m;
}
@ -509,6 +511,8 @@ void QEvdevKeyboardHandler::unloadKeymap()
m_locks[2] = 1;
qCDebug(qLcEvdevKey, "numlock=%d , capslock=%d, scrolllock=%d", m_locks[1], m_locks[0], m_locks[2]);
}
m_langLock = 0;
}
bool QEvdevKeyboardHandler::loadKeymap(const QString &file)
@ -570,4 +574,9 @@ bool QEvdevKeyboardHandler::loadKeymap(const QString &file)
return true;
}
void QEvdevKeyboardHandler::switchLang()
{
m_langLock ^= 1;
}
QT_END_NAMESPACE

View File

@ -192,6 +192,8 @@ public:
void readKeycode();
KeycodeAction processKeycode(quint16 keycode, bool pressed, bool autorepeat);
void switchLang();
private:
void processKeyEvent(int nativecode, int unicode, int qtcode,
Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat);
@ -206,6 +208,7 @@ private:
quint8 m_locks[3];
int m_composing;
quint16 m_dead_unicode;
quint8 m_langLock;
bool m_no_zap;
bool m_do_compose;

View File

@ -153,4 +153,10 @@ void QEvdevKeyboardManager::loadKeymap(const QString &file)
}
}
void QEvdevKeyboardManager::switchLang()
{
foreach (QEvdevKeyboardHandler *handler, m_keyboards)
handler->switchLang();
}
QT_END_NAMESPACE

View File

@ -68,6 +68,7 @@ public:
~QEvdevKeyboardManager();
void loadKeymap(const QString &file);
void switchLang();
void addKeyboard(const QString &deviceNode = QString());
void removeKeyboard(const QString &deviceNode);

View File

@ -429,6 +429,8 @@ QFunctionPointer QEglFSIntegration::platformFunction(const QByteArray &function)
#if QT_CONFIG(evdev)
if (function == QEglFSFunctions::loadKeymapTypeIdentifier())
return QFunctionPointer(loadKeymapStatic);
else if (function == QEglFSFunctions::switchLangTypeIdentifier())
return QFunctionPointer(switchLangStatic);
#endif
return qt_egl_device_integration()->platformFunction(function);
@ -447,6 +449,17 @@ void QEglFSIntegration::loadKeymapStatic(const QString &filename)
#endif
}
void QEglFSIntegration::switchLangStatic()
{
#if QT_CONFIG(evdev)
QEglFSIntegration *self = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
if (self->m_kbdMgr)
self->m_kbdMgr->switchLang();
else
qWarning("QEglFSIntegration: Cannot switch language, no keyboard handler found");
#endif
}
void QEglFSIntegration::createInputHandlers()
{
#if QT_CONFIG(libinput)

View File

@ -110,6 +110,7 @@ private:
EGLNativeDisplayType nativeDisplay() const;
void createInputHandlers();
static void loadKeymapStatic(const QString &filename);
static void switchLangStatic();
EGLDisplay m_display;
QPlatformInputContext *m_inputContext;

View File

@ -69,12 +69,15 @@
#include <QtInputSupport/private/qtslib_p.h>
#endif
#include <QtPlatformHeaders/qlinuxfbfunctions.h>
QT_BEGIN_NAMESPACE
QLinuxFbIntegration::QLinuxFbIntegration(const QStringList &paramList)
: m_primaryScreen(nullptr),
m_fontDb(new QGenericUnixFontDatabase),
m_services(new QGenericUnixServices)
m_services(new QGenericUnixServices),
m_kbdMgr(0)
{
#if QT_CONFIG(kms)
if (qEnvironmentVariableIntValue("QT_QPA_FB_DRM") != 0)
@ -98,8 +101,6 @@ void QLinuxFbIntegration::initialize()
m_inputContext = QPlatformInputContextFactory::create();
m_nativeInterface.reset(new QPlatformNativeInterface);
m_vtHandler.reset(new QFbVtHandler);
if (!qEnvironmentVariableIntValue("QT_QPA_FB_DISABLE_INPUT"))
@ -163,7 +164,7 @@ void QLinuxFbIntegration::createInputHandlers()
#endif
#if QT_CONFIG(evdev)
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this);
m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this);
#if QT_CONFIG(tslib)
if (!useTslib)
@ -174,7 +175,45 @@ void QLinuxFbIntegration::createInputHandlers()
QPlatformNativeInterface *QLinuxFbIntegration::nativeInterface() const
{
return m_nativeInterface.data();
return const_cast<QLinuxFbIntegration *>(this);
}
QFunctionPointer QLinuxFbIntegration::platformFunction(const QByteArray &function) const
{
#if QT_CONFIG(evdev)
if (function == QLinuxFbFunctions::loadKeymapTypeIdentifier())
return QFunctionPointer(loadKeymapStatic);
else if (function == QLinuxFbFunctions::switchLangTypeIdentifier())
return QFunctionPointer(switchLangStatic);
#else
Q_UNUSED(function)
#endif
return 0;
}
void QLinuxFbIntegration::loadKeymapStatic(const QString &filename)
{
#if QT_CONFIG(evdev)
QLinuxFbIntegration *self = static_cast<QLinuxFbIntegration *>(QGuiApplicationPrivate::platformIntegration());
if (self->m_kbdMgr)
self->m_kbdMgr->loadKeymap(filename);
else
qWarning("QLinuxFbIntegration: Cannot load keymap, no keyboard handler found");
#else
Q_UNUSED(filename);
#endif
}
void QLinuxFbIntegration::switchLangStatic()
{
#if QT_CONFIG(evdev)
QLinuxFbIntegration *self = static_cast<QLinuxFbIntegration *>(QGuiApplicationPrivate::platformIntegration());
if (self->m_kbdMgr)
self->m_kbdMgr->switchLang();
else
qWarning("QLinuxFbIntegration: Cannot switch language, no keyboard handler found");
#endif
}
QT_END_NAMESPACE

View File

@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
class QFbScreen;
class QFbVtHandler;
class QEvdevKeyboardManager;
class QLinuxFbIntegration : public QPlatformIntegration, public QPlatformNativeInterface
{
@ -71,15 +72,20 @@ public:
QList<QPlatformScreen *> screens() const;
QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
private:
void createInputHandlers();
static void loadKeymapStatic(const QString &filename);
static void switchLangStatic();
QFbScreen *m_primaryScreen;
QPlatformInputContext *m_inputContext;
QScopedPointer<QPlatformFontDatabase> m_fontDb;
QScopedPointer<QPlatformServices> m_services;
QScopedPointer<QFbVtHandler> m_vtHandler;
QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
QEvdevKeyboardManager *m_kbdMgr;
};
QT_END_NAMESPACE