mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 00:24:51 +00:00
event_filter: add touch-click filter
This filter bridges the gap between a touchscreen driver, which generates raw touch events and traditional GUI applications that expect a pointer (absolute motion, press/release of the left mouse button). Fixes #4332
This commit is contained in:
parent
09d020508c
commit
133d21ad38
@ -79,6 +79,13 @@ one of the following filters:
|
||||
"0" corresponds to a linear function whereas the maximum value "255" applies
|
||||
a curved function. The default value is "127".
|
||||
|
||||
:<touch-click>:
|
||||
|
||||
Augments touch events with artificial absolute motion and mouse click/clack
|
||||
events as understood by regular GUI applications that are not aware of
|
||||
touch input. The original touch events are preserved, enabling touch-aware
|
||||
applications to interpet touch gestures.
|
||||
|
||||
|
||||
Character generator rules
|
||||
-------------------------
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <button_scroll_source.h>
|
||||
#include <accelerate_source.h>
|
||||
#include <log_source.h>
|
||||
#include <touch_click_source.h>
|
||||
#include <event_session.h>
|
||||
|
||||
namespace Event_filter { struct Main; }
|
||||
@ -250,6 +251,9 @@ struct Event_filter::Main : Source::Factory, Source::Trigger
|
||||
if (node.type() == Log_source::name())
|
||||
return *new (_heap) Log_source(owner, node, *this);
|
||||
|
||||
if (node.type() == Touch_click_source::name())
|
||||
return *new (_heap) Touch_click_source(owner, node, *this);
|
||||
|
||||
warning("unknown <", node.type(), "> input-source node type");
|
||||
throw Source::Invalid_config();
|
||||
}
|
||||
|
@ -47,7 +47,8 @@ class Event_filter::Source
|
||||
|| node.type() == "merge"
|
||||
|| node.type() == "button-scroll"
|
||||
|| node.type() == "accelerate"
|
||||
|| node.type() == "log";
|
||||
|| node.type() == "log"
|
||||
|| node.type() == "touch-click";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
96
repos/os/src/server/event_filter/touch_click_source.h
Normal file
96
repos/os/src/server/event_filter/touch_click_source.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* \brief Input-event source that augments touch events with pointer events
|
||||
* \author Norman Feske
|
||||
* \date 2021-11-22
|
||||
*
|
||||
* This filter supplements touch events with absolute motion events and
|
||||
* artificial mouse click/release events as understood by regular GUI
|
||||
* applications. The original touch events are preserved, which enables
|
||||
* touch-aware applications to interpret them.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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__TOUCH_CLICK_SOURCE_H_
|
||||
#define _EVENT_FILTER__TOUCH_CLICK_SOURCE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <input/keycodes.h>
|
||||
|
||||
/* local includes */
|
||||
#include <source.h>
|
||||
|
||||
namespace Event_filter { class Touch_click_source; }
|
||||
|
||||
|
||||
class Event_filter::Touch_click_source : public Source, Source::Filter
|
||||
{
|
||||
private:
|
||||
|
||||
Owner _owner;
|
||||
|
||||
Source &_source;
|
||||
|
||||
bool _pressed = false;
|
||||
|
||||
/**
|
||||
* Filter interface
|
||||
*/
|
||||
void filter_event(Sink &destination, Input::Event const &event) override
|
||||
{
|
||||
Input::Event ev = event;
|
||||
|
||||
/* forward original event */
|
||||
destination.submit(ev);
|
||||
|
||||
/* supplement mouse click and absolute motion */
|
||||
ev.handle_touch([&] (Input::Touch_id id, float x, float y) {
|
||||
|
||||
/* respond to first finger only */
|
||||
if (id.value != 0)
|
||||
return;
|
||||
|
||||
destination.submit(Input::Absolute_motion{ int(x), int(y) });
|
||||
|
||||
if (!_pressed) {
|
||||
destination.submit(Input::Press { Input::BTN_LEFT });
|
||||
_pressed = true;
|
||||
}
|
||||
});
|
||||
|
||||
/* supplement mouse clack */
|
||||
ev.handle_touch_release([&] (Input::Touch_id id) {
|
||||
|
||||
if (id.value != 0)
|
||||
return;
|
||||
|
||||
if (_pressed) {
|
||||
destination.submit(Input::Release { Input::BTN_LEFT });
|
||||
_pressed = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static char const *name() { return "touch-click"; }
|
||||
|
||||
Touch_click_source(Owner &owner, Xml_node config, Source::Factory &factory)
|
||||
:
|
||||
Source(owner),
|
||||
_owner(factory),
|
||||
_source(factory.create_source(_owner, input_sub_node(config)))
|
||||
{ }
|
||||
|
||||
void generate(Sink &destination) override
|
||||
{
|
||||
Source::Filter::apply(destination, *this, _source);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _EVENT_FILTER__TOUCH_CLICK_SOURCE_H_*/
|
Loading…
x
Reference in New Issue
Block a user