From 455bd9396e0bc98e399d8e3ac8b020ec738a0041 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 13 Feb 2017 13:11:12 +0100 Subject: [PATCH] gems/terminal: support 'CHARACTER' events This patch adds the handling of 'CHARACTER' events as emitted by the input-filter's character generator (). To avoid interpreting press/release events twice (at the input filter and by the terminal's built-in scancode tracker), the terminal's scancode tracker can be explicitly disabled via . In the future, the terminal's built-in scancode tracker will be removed. The use of the terminal with the input filter is illustrated by the 'terminal_echo.run' script. Issue #2264 --- repos/gems/run/terminal_echo.run | 50 ++++++++++++++++++-- repos/gems/src/server/terminal/main.cc | 38 ++++++++++++--- repos/os/include/terminal/scancode_tracker.h | 2 +- 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/repos/gems/run/terminal_echo.run b/repos/gems/run/terminal_echo.run index 7eba3354d2..81705aae22 100644 --- a/repos/gems/run/terminal_echo.run +++ b/repos/gems/run/terminal_echo.run @@ -1,6 +1,6 @@ set build_components { core init drivers/timer - server/terminal test/terminal_echo + server/input_filter server/terminal test/terminal_echo drivers/framebuffer drivers/input } @@ -11,6 +11,9 @@ build $build_components create_boot_directory +exec cp -f [genode_dir]/repos/os/src/server/input_filter/en_us.chargen bin/ +exec cp -f [genode_dir]/repos/os/src/server/input_filter/de.chargen bin/ + append config { @@ -36,7 +39,9 @@ append_if [have_spec sdl] config { - } + + + } append_platform_drv_config @@ -44,27 +49,63 @@ append_if [have_spec framebuffer] config { + } append_if [have_spec ps2] config { - } + + } append config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -79,7 +120,8 @@ install_config $config # generic modules set boot_modules { - core ld.lib.so init timer terminal test-terminal_echo + core ld.lib.so init timer input_filter terminal test-terminal_echo + en_us.chargen de.chargen } # platform-specific modules diff --git a/repos/gems/src/server/terminal/main.cc b/repos/gems/src/server/terminal/main.cc index 3a184ccf40..6dbdd34ef9 100644 --- a/repos/gems/src/server/terminal/main.cc +++ b/repos/gems/src/server/terminal/main.cc @@ -544,7 +544,7 @@ struct Terminal::Main /* create root interface for service */ Terminal::Root_component _root; - Terminal::Scancode_tracker _scancode_tracker; + Constructible _scancode_tracker; /* state needed for key-repeat handling */ unsigned const _repeat_delay = 250; @@ -608,27 +608,45 @@ struct Terminal::Main font_family), _scancode_tracker(keymap, shift, altgr, Terminal::control) { + /* + * Construct scancode tracker only if a key map is defined. Otherwise, + * the terminal responds solely by 'CHARACTER' input events. + */ + if (keymap) + _scancode_tracker.construct(keymap, shift, altgr, Terminal::control); + _input.sigh(_input_handler); /* announce service at our parent */ _env.parent().announce(_env.ep().manage(_root)); } - }; void Terminal::Main::_handle_input() { _input.for_each_event([&] (Input::Event const &event) { + + if (event.type() == Input::Event::CHARACTER) { + Input::Event::Utf8 const utf8 = event.utf8(); + _read_buffer.add(utf8.b0); + if (utf8.b1) _read_buffer.add(utf8.b1); + if (utf8.b2) _read_buffer.add(utf8.b2); + if (utf8.b3) _read_buffer.add(utf8.b3); + } + + if (!_scancode_tracker.constructed()) + return; + bool press = (event.type() == Input::Event::PRESS ? true : false); bool release = (event.type() == Input::Event::RELEASE ? true : false); int keycode = event.code(); if (press || release) - _scancode_tracker.submit(keycode, press); + _scancode_tracker->submit(keycode, press); if (press) { - _scancode_tracker.emit_current_character(_read_buffer); + _scancode_tracker->emit_current_character(_read_buffer); /* setup first key repeat */ _repeat_next = _repeat_delay; @@ -648,7 +666,7 @@ void Terminal::Main::_handle_key_repeat(Time_source::Microseconds) if (_repeat_next) { /* repeat current character or sequence */ - _scancode_tracker.emit_current_character(_read_buffer); + _scancode_tracker->emit_current_character(_read_buffer); _repeat_next = _repeat_rate; } @@ -723,12 +741,20 @@ void Component::construct(Genode::Env &env) try { if (config.xml().sub_node("keyboard") .attribute("layout").has_value("de")) { - keymap = Terminal::german_keymap; shift = Terminal::german_shift; altgr = Terminal::german_altgr; } } catch (...) { } + try { + if (config.xml().sub_node("keyboard") + .attribute("layout").has_value("none")) { + keymap = nullptr; + shift = nullptr; + altgr = nullptr; + } + } catch (...) { } + static Terminal::Main main(env, font_family, keymap, shift, altgr, Terminal::control); } diff --git a/repos/os/include/terminal/scancode_tracker.h b/repos/os/include/terminal/scancode_tracker.h index 2cf47ba8c5..425fae30c2 100644 --- a/repos/os/include/terminal/scancode_tracker.h +++ b/repos/os/include/terminal/scancode_tracker.h @@ -113,7 +113,7 @@ class Terminal::Scancode_tracker _mod_altgr(false), _last_character(0), _last_sequence(0) - { }; + { } /** * Submit key event to state machine