Qt5: keyboard layout support

To select a different keyboard layout than the default 'en_us', override the
'language_chargen' function in your run script (after including
qt5_common.inc):

  proc language_chargen { } { return "de" }

where "de" refers to the character map file

  'repos/os/src/server/input_filter/de.chargen'

Issue #2264
This commit is contained in:
Christian Prochaska 2017-02-23 17:58:21 +01:00 committed by Christian Helmuth
parent 1f447c1460
commit e446fd5f7c
6 changed files with 112 additions and 39 deletions

View File

@ -1 +1 @@
0e36d5ca8b3f7e7e0100248b0f99b55c30a520cd
6932514d67f1ce1ff00421d7b4ee9a1de0b7d6bc

View File

@ -63,7 +63,7 @@ proc qt5_start_nodes { feature_arg } {
<service name="Framebuffer"> <child name="fb_drv" /> </service>
}
append start_nodes {
<service name="Input"> <child name="input_merger"/> </service>
<service name="Input"> <child name="input_filter"/> </service>
<service name="Report"> <child name="report_rom"/> </service>
<any-service> <parent /> <any-child /> </any-service>
</route>

View File

@ -33,7 +33,7 @@ proc use_gpio_drv { feature_arg } {
[have_spec gpio]}]
}
proc use_input_merger { feature_arg } {
proc use_input_filter { feature_arg } {
upvar $feature_arg feature
return [info exists feature(Input)]
}
@ -59,7 +59,9 @@ proc use_timer { feature_arg } {
proc use_usb_input { feature_arg } {
upvar $feature_arg feature
return [expr {[info exists feature(Input)] && [need_usb_hid]}]
return [expr {[info exists feature(Input)] &&
([need_usb_hid] ||
([have_spec x86] && ![have_spec linux]))}]
}
proc use_usb_nic { feature_arg } {
@ -75,6 +77,11 @@ proc use_usb_drv { feature_arg } {
return [expr {[use_usb_input feature] || [use_usb_nic feature]}]
}
#
# Keyboard layout - this function can be overridden in a run script
#
proc language_chargen { } { return "en_us" }
#
# Build
#
@ -93,7 +100,7 @@ proc drivers_build_components { feature_arg } {
lappend_if [use_fb_drv feature] build_components drivers/framebuffer
lappend_if [use_fb_sdl feature] build_components drivers/framebuffer/spec/sdl
lappend_if [use_gpio_drv feature] build_components drivers/gpio
lappend_if [use_input_merger feature] build_components server/input_merger
lappend_if [use_input_filter feature] build_components server/input_filter
lappend_if [use_nic_drv feature] build_components drivers/nic
lappend_if [use_ps2_drv feature] build_components drivers/input/spec/ps2
lappend_if [use_timer feature] build_components drivers/timer
@ -175,9 +182,12 @@ proc drivers_start_nodes { feature_arg } {
<config/>
</start>"
if { [use_input_merger feature] } {
if { [use_input_filter feature] } {
exec cp -f [genode_dir]/repos/os/src/server/input_filter/[language_chargen].chargen bin/
append start_nodes {
<start name="input_merger">
<start name="input_filter">
<resource name="RAM" quantum="1M" />
<provides> <service name="Input" /> </provides>
<config>}
@ -188,13 +198,40 @@ proc drivers_start_nodes { feature_arg } {
append_if [use_fb_sdl feature] start_nodes {
<input label="sdl"/>}
append start_nodes {
<output>
<chargen>
<merge>}
append_if [use_ps2_drv feature] start_nodes {
<input name="ps2"/>}
append_if [use_usb_drv feature] start_nodes {
<input name="usb"/>}
append_if [use_fb_sdl feature] start_nodes {
<input name="sdl"/>}
append start_nodes {
</merge>
<mod1>
<key name="KEY_LEFTSHIFT"/> <key name="KEY_RIGHTSHIFT"/>
</mod1>
<mod2>
<key name="KEY_LEFTCTRL"/> <key name="KEY_RIGHTCTRL"/>
</mod2>
<mod3>
<key name="KEY_RIGHTALT"/> <!-- AltGr -->
</mod3>
<repeat delay_ms="500" rate_ms="50"/>}
append start_nodes "
<include rom=\"[language_chargen].chargen\"/>"
append start_nodes {
</chargen>
</output>
</config>
<route>
<service name="LOG"> <parent/> </service>
<service name="RAM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>}
<service name="PD"> <parent/> </service>
<service name="Timer"> <child name="timer"/> </service>}
append_if [use_ps2_drv feature] start_nodes {
<service name="Input" label="ps2"> <child name="ps2_drv" /> </service>}
append_if [use_usb_drv feature] start_nodes {
@ -271,7 +308,8 @@ proc drivers_boot_modules { feature_arg } {
lappend_if [use_fb_drv feature] boot_modules fb_drv
lappend_if [use_fb_sdl feature] boot_modules fb_sdl
lappend_if [use_gpio_drv feature] boot_modules [gpio_drv]
lappend_if [use_input_merger feature] boot_modules input_merger
lappend_if [use_input_filter feature] boot_modules input_filter
lappend_if [use_input_filter feature] boot_modules [language_chargen].chargen
lappend_if [use_nic_drv feature] boot_modules nic_drv
lappend_if [use_ps2_drv feature] boot_modules ps2_drv
lappend_if [use_timer feature] boot_modules timer

View File

@ -5,10 +5,10 @@ From: Christian Prochaska <christian.prochaska@genode-labs.com>
---
.../fontdatabases/basic/qbasicfontdatabase.cpp | 9 +++++++++
.../input/evdevkeyboard/qevdevkeyboardhandler.cpp | 9 ++++++---
.../input/evdevkeyboard/qevdevkeyboardhandler.cpp | 18 +++++++++++++++---
.../input/evdevkeyboard/qevdevkeyboardhandler_p.h | 2 ++
qtbase/src/widgets/kernel/qwidget_qpa.cpp | 2 +-
4 files changed, 18 insertions(+), 4 deletions(-)
4 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 9b87418..aa25c6b 100644
@ -32,7 +32,7 @@ index 9b87418..aa25c6b 100644
}
diff --git a/qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
index 26dc116..3d0e3e2 100644
index 26dc116..f0c104d 100644
--- a/qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
+++ b/qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp
@@ -49,7 +49,9 @@
@ -68,7 +68,7 @@ index 26dc116..3d0e3e2 100644
QEvdevKeyboardHandler *QEvdevKeyboardHandler::create(const QString &device, const QString &specification)
{
#ifdef QT_QPA_KEYMAP_DEBUG
@@ -218,7 +221,7 @@ void QEvdevKeyboardHandler::readKeycode()
@@ -218,10 +221,19 @@ void QEvdevKeyboardHandler::readKeycode()
}
}
}
@ -77,6 +77,18 @@ index 26dc116..3d0e3e2 100644
void QEvdevKeyboardHandler::processKeyEvent(int nativecode, int unicode, int qtcode,
Qt::KeyboardModifiers modifiers, bool isPress, bool autoRepeat)
{
+#ifdef Q_OS_GENODE
+ /* characters are handled separately by the QPA plugin */
+ unicode = 0xffff;
+
+ /* Ctrl-A .. Ctrl-Z is handled separately by the QPA plugin */
+ if ((modifiers & Qt::ControlModifier) &&
+ ((qtcode >= Qt::Key_A) && (qtcode <= Qt::Key_Z)))
+ return;
+#endif
QWindowSystemInterface::handleExtendedKeyEvent(0, (isPress ? QEvent::KeyPress : QEvent::KeyRelease),
qtcode, modifiers, nativecode + 8, 0, int(modifiers),
QString(unicode), autoRepeat);
diff --git a/qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h b/qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h
index 1065b05..b395d46 100644
--- a/qtbase/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h

View File

@ -85,20 +85,20 @@ void QNitpickerPlatformWindow::_process_touch_events(QList<Input::Event> const &
QWindowSystemInterface::handleTouchEvent(0, _touch_device, touch_points);
}
void QNitpickerPlatformWindow::_process_mouse_event(Input::Event *ev)
void QNitpickerPlatformWindow::_process_mouse_event(Input::Event const &ev)
{
QPoint global_position(ev->ax(), ev->ay());
QPoint global_position(ev.ax(), ev.ay());
QPoint local_position(global_position.x() - geometry().x(),
global_position.y() - geometry().y());
switch (ev->type()) {
switch (ev.type()) {
case Input::Event::PRESS:
/* make this window the focused window */
requestActivateWindow();
switch (ev->code()) {
switch (ev.code()) {
case Input::BTN_LEFT:
_mouse_button_state |= Qt::LeftButton;
break;
@ -119,7 +119,7 @@ void QNitpickerPlatformWindow::_process_mouse_event(Input::Event *ev)
case Input::Event::RELEASE:
switch (ev->code()) {
switch (ev.code()) {
case Input::BTN_LEFT:
_mouse_button_state &= ~Qt::LeftButton;
break;
@ -143,7 +143,7 @@ void QNitpickerPlatformWindow::_process_mouse_event(Input::Event *ev)
QWindowSystemInterface::handleWheelEvent(window(),
local_position,
local_position,
ev->ry() * 120,
ev.ry() * 120,
Qt::Vertical);
return;
@ -158,10 +158,10 @@ void QNitpickerPlatformWindow::_process_mouse_event(Input::Event *ev)
}
void QNitpickerPlatformWindow::_process_key_event(Input::Event *ev)
void QNitpickerPlatformWindow::_process_key_event(Input::Event const &ev)
{
const bool pressed = (ev->type() == Input::Event::PRESS);
const int keycode = ev->code();
const bool pressed = (ev.type() == Input::Event::PRESS);
const int keycode = ev.code();
if (pressed) {
_last_keycode = keycode;
@ -183,34 +183,57 @@ void QNitpickerPlatformWindow::_key_repeat()
void QNitpickerPlatformWindow::_handle_input(unsigned int)
{
QList<Input::Event> touch_events;
for (int i = 0, num_ev = _input_session.flush(); i < num_ev; i++) {
Input::Event *ev = &_ev_buf[i];
_input_session.for_each_event([&] (Input::Event const &event) {
bool const is_key_event = ev->type() == Input::Event::PRESS ||
ev->type() == Input::Event::RELEASE;
bool const is_key_event = event.type() == Input::Event::PRESS ||
event.type() == Input::Event::RELEASE;
bool const is_mouse_button_event =
is_key_event && (ev->code() == Input::BTN_LEFT ||
ev->code() == Input::BTN_MIDDLE ||
ev->code() == Input::BTN_RIGHT);
is_key_event && (event.code() == Input::BTN_LEFT ||
event.code() == Input::BTN_MIDDLE ||
event.code() == Input::BTN_RIGHT);
if (ev->type() == Input::Event::MOTION ||
ev->type() == Input::Event::WHEEL ||
if (event.type() == Input::Event::MOTION ||
event.type() == Input::Event::WHEEL ||
is_mouse_button_event) {
_process_mouse_event(ev);
_process_mouse_event(event);
} else if (ev->type() == Input::Event::TOUCH) {
} else if (event.type() == Input::Event::TOUCH) {
touch_events.push_back(*ev);
touch_events.push_back(event);
} else if (is_key_event && (ev->code() < 128)) {
} else if (event.type() == Input::Event::CHARACTER) {
_process_key_event(ev);
Input::Event::Utf8 const utf8 = event.utf8();
if ((utf8.b0 >= 1) && (utf8.b0 <= 26)) {
/* Ctrl-A .. Ctrl-Z */
QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyPress,
Qt::Key_A + (utf8.b0 - 1),
Qt::ControlModifier);
QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyRelease,
Qt::Key_A + (utf8.b0 - 1),
Qt::ControlModifier);
} else {
char const utf8_string[] = { utf8.b0, utf8.b1, utf8.b2, utf8.b3, '\0' };
QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyPress, 0, 0,
QString::fromUtf8(utf8_string));
QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyRelease, 0, 0,
QString::fromUtf8(utf8_string));
}
} else if (is_key_event && (event.code() < 128)) {
_process_key_event(event);
}
}
});
/* process all gathered touch events */
_process_touch_events(touch_events);

View File

@ -70,8 +70,8 @@ class QNitpickerPlatformWindow : public QObject, public QPlatformWindow
QTouchDevice *_touch_device;
QTouchDevice * _init_touch_device();
void _process_mouse_event(Input::Event *ev);
void _process_key_event(Input::Event *ev);
void _process_mouse_event(Input::Event const &ev);
void _process_key_event(Input::Event const &ev);
void _process_touch_events(QList<Input::Event> const &events);
Nitpicker::Session::View_handle _create_view();