From e446fd5f7cf8764e0711da6da30757f8b71d3e10 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Thu, 23 Feb 2017 17:58:21 +0100 Subject: [PATCH] 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 --- repos/libports/ports/qt5.hash | 2 +- repos/libports/run/qt5_common.inc | 2 +- repos/libports/run/qt5_drivers.inc | 52 ++++++++++++-- .../src/lib/qt5/patches/qt5_qpa.patch | 20 ++++-- .../nitpicker/qnitpickerplatformwindow.cpp | 71 ++++++++++++------- .../nitpicker/qnitpickerplatformwindow.h | 4 +- 6 files changed, 112 insertions(+), 39 deletions(-) diff --git a/repos/libports/ports/qt5.hash b/repos/libports/ports/qt5.hash index 980fe66064..2cface7d80 100644 --- a/repos/libports/ports/qt5.hash +++ b/repos/libports/ports/qt5.hash @@ -1 +1 @@ -0e36d5ca8b3f7e7e0100248b0f99b55c30a520cd +6932514d67f1ce1ff00421d7b4ee9a1de0b7d6bc diff --git a/repos/libports/run/qt5_common.inc b/repos/libports/run/qt5_common.inc index 145dddd720..9c52113ec3 100644 --- a/repos/libports/run/qt5_common.inc +++ b/repos/libports/run/qt5_common.inc @@ -63,7 +63,7 @@ proc qt5_start_nodes { feature_arg } { } append start_nodes { - + diff --git a/repos/libports/run/qt5_drivers.inc b/repos/libports/run/qt5_drivers.inc index 7d07f747ce..50782bc548 100644 --- a/repos/libports/run/qt5_drivers.inc +++ b/repos/libports/run/qt5_drivers.inc @@ -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 } { " - 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 { - + } @@ -188,13 +198,40 @@ proc drivers_start_nodes { feature_arg } { append_if [use_fb_sdl feature] start_nodes { } append start_nodes { + + + } + append_if [use_ps2_drv feature] start_nodes { + } + append_if [use_usb_drv feature] start_nodes { + } + append_if [use_fb_sdl feature] start_nodes { + } + append start_nodes { + + + + + + + + + + + } + append start_nodes " + " + append start_nodes { + + - } + + } append_if [use_ps2_drv feature] start_nodes { } 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 diff --git a/repos/libports/src/lib/qt5/patches/qt5_qpa.patch b/repos/libports/src/lib/qt5/patches/qt5_qpa.patch index 62c2a64b22..4067a500ec 100644 --- a/repos/libports/src/lib/qt5/patches/qt5_qpa.patch +++ b/repos/libports/src/lib/qt5/patches/qt5_qpa.patch @@ -5,10 +5,10 @@ From: Christian Prochaska --- .../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 diff --git a/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerplatformwindow.cpp b/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerplatformwindow.cpp index dd7cc54538..39093c4e2f 100644 --- a/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerplatformwindow.cpp +++ b/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerplatformwindow.cpp @@ -85,20 +85,20 @@ void QNitpickerPlatformWindow::_process_touch_events(QList 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 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); diff --git a/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerplatformwindow.h b/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerplatformwindow.h index 2fdfb1dade..768a884ce6 100644 --- a/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerplatformwindow.h +++ b/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerplatformwindow.h @@ -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 const &events); Nitpicker::Session::View_handle _create_view();