diff --git a/repos/os/src/server/event_filter/README b/repos/os/src/server/event_filter/README index 0add22e18e..43261612d9 100644 --- a/repos/os/src/server/event_filter/README +++ b/repos/os/src/server/event_filter/README @@ -35,6 +35,13 @@ one of the following filters: content into the '' node. The included ROM must have a '' top-level node. +:: + + Logs debug information about key presses and releases to the component's 'Log' + session. An optional 'prefix' attribute can be provided in order to + distinguish multiple '' filters. The given prefix is placed at the + beginning of each log message. + :: Merges the results of any number of filters that appear as child nodes. diff --git a/repos/os/src/server/event_filter/log_source.h b/repos/os/src/server/event_filter/log_source.h new file mode 100644 index 0000000000..52d5b2261d --- /dev/null +++ b/repos/os/src/server/event_filter/log_source.h @@ -0,0 +1,84 @@ +/* + * \brief Input-event source that logs key events from another source + * \author Johannes Schlatow + * \date 2021-04-26 + */ + +/* + * Copyright (C) 2021 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _EVENT_FILTER__LOG_SOURCE_H_ +#define _EVENT_FILTER__LOG_SOURCE_H_ + +/* Genode includes */ +#include + +/* local includes */ +#include +#include +#include + +namespace Event_filter { class Log_source; } + + +class Event_filter::Log_source : public Source, Source::Filter +{ + private: + + typedef String<32> Prefix; + + Prefix _prefix = ""; + + Owner _owner; + + Source &_source; + + unsigned _event_cnt = 0; + int _key_cnt = 0; + + /** + * Filter interface + */ + void filter_event(Source::Sink &destination, Input::Event const &event) override + { + /* only log presses and releases */ + if (event.press() || event.release()) { + if (event.press()) ++_key_cnt; + if (event.release()) --_key_cnt; + + log(_prefix, "event #", _event_cnt++, "\t", event, "\tkey count: ", _key_cnt); + } + + /* forward event */ + destination.submit(event); + } + + void _apply_config(Xml_node const config) + { + _prefix = config.attribute_value("prefix", _prefix); + } + + public: + + static char const *name() { return "log"; } + + Log_source(Owner &owner, Xml_node config, Source::Factory &factory) + : + Source(owner), + _owner(factory), + _source(factory.create_source(_owner, input_sub_node(config))) + { + _apply_config(config); + } + + void generate(Source::Sink &destination) override + { + Source::Filter::apply(destination, *this, _source); + } +}; + +#endif /* _EVENT_FILTER__LOG_SOURCE_H_ */ diff --git a/repos/os/src/server/event_filter/main.cc b/repos/os/src/server/event_filter/main.cc index 7cb90dc98f..56c07fa1e6 100644 --- a/repos/os/src/server/event_filter/main.cc +++ b/repos/os/src/server/event_filter/main.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace Event_filter { struct Main; } @@ -246,6 +247,9 @@ struct Event_filter::Main : Source::Factory, Source::Trigger if (node.type() == Accelerate_source::name()) return *new (_heap) Accelerate_source(owner, node, *this); + if (node.type() == Log_source::name()) + return *new (_heap) Log_source(owner, node, *this); + warning("unknown <", node.type(), "> input-source node type"); throw Source::Invalid_config(); } diff --git a/repos/os/src/server/event_filter/source.h b/repos/os/src/server/event_filter/source.h index 84a38b333b..d45176bddc 100644 --- a/repos/os/src/server/event_filter/source.h +++ b/repos/os/src/server/event_filter/source.h @@ -46,7 +46,8 @@ class Event_filter::Source || node.type() == "chargen" || node.type() == "merge" || node.type() == "button-scroll" - || node.type() == "accelerate"; + || node.type() == "accelerate" + || node.type() == "log"; return false; }