Replace input filter with event filter

This commit applies the transition from the "Input" session to the "Event"
session to the event-filtering mechansim. The functionality of the
input_filter is now provided by the event_filter. The event filter
requests only one "Event" session as destination for the filter result,
which is usually routed to the nitpicker GUI server. It provides an
"Event" service to which any number of event sources can connect.

The configuration of the filter chain remains almost the same. Only the
declaration of the <input> nodes is no longer needed. Instead, the
configuration must specify <policy> nodes, which define the mapping of
"Event" clients (event sources) to the inputs used in the filter chain.

The patch adjusts all uses of the nitpicker GUI server accordingly such
that the event filter reports events to nitpicker's event service
instead of having nitpicker request an "Input" session. This dissolves
the dependency of nitpicker from input drivers.

Issue #3827
This commit is contained in:
Norman Feske 2020-07-16 11:28:18 +02:00
parent bc5b161260
commit 9662d89cfb
92 changed files with 1072 additions and 836 deletions

View File

@ -1,4 +1,5 @@
_/src/imx8_fb_drv
_/src/usb_host_drv
_/src/usb_hid_drv
_/src/input_event_client
_/raw/drivers_interactive-imx8q_evk

View File

@ -1,4 +1,5 @@
_/src/platform_drv
_/src/usb_drv
_/src/rpi_fb_drv
_/src/input_event_client
_/raw/drivers_interactive-rpi

View File

@ -10,13 +10,11 @@
<service name="LOG"/>
<service name="Timer"/>
<service name="Capture"/>
<service name="Event"/>
</parent-provides>
<default caps="60"/>
<service name="Input">
<default-policy> <child name="usb_hid_drv"/> </default-policy> </service>
<start name="report_rom">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
@ -68,4 +66,14 @@
<service name="Capture"> <parent/> </service>
</route>
</start>
<start name="input_event_client" caps="90">
<resource name="RAM" quantum="1M"/>
<config/>
<route>
<service name="Event"> <parent/> </service>
<service name="Input"> <child name="usb_hid_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
</config>

View File

@ -10,13 +10,11 @@
<service name="LOG"/>
<service name="Timer"/>
<service name="Capture"/>
<service name="Event"/>
</parent-provides>
<default caps="60"/>
<service name="Input">
<default-policy> <child name="input_drv"/> </default-policy> </service>
<start name="platform_drv" caps="200">
<binary name="rpi_platform_drv"/>
<resource name="RAM" quantum="3M"/>
@ -67,4 +65,14 @@
<service name="Timer"> <parent/> </service>
</route>
</start>
<start name="input_event_client" caps="90">
<resource name="RAM" quantum="1M"/>
<config/>
<route>
<service name="Event"> <parent/> </service>
<service name="Input"> <child name="input_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
</config>

View File

@ -8,9 +8,10 @@ _/src/intel_fb_drv
_/src/boot_fb_drv
_/src/ahci_drv
_/src/report_rom
_/src/input_filter
_/src/event_filter
_/src/init
_/src/driver_manager
_/src/rom_filter
_/src/rom_reporter
_/src/input_event_client
_/raw/drivers_managed-pc

View File

@ -1,11 +1,11 @@
content: drivers.config fb_drv.config input_filter.config en_us.chargen \
content: drivers.config fb_drv.config event_filter.config en_us.chargen \
special.chargen numlock_remap.config
drivers.config numlock_remap.config:
cp $(REP_DIR)/recipes/raw/drivers_managed-pc/$@ $@
fb_drv.config input_filter.config:
fb_drv.config event_filter.config:
cp $(GENODE_DIR)/repos/os/recipes/raw/drivers_interactive-pc/$@ $@
en_us.chargen special.chargen:
cp $(GENODE_DIR)/repos/os/src/server/input_filter/$@ $@
cp $(GENODE_DIR)/repos/os/src/server/event_filter/$@ $@

View File

@ -12,6 +12,7 @@
<service name="Timer"/>
<service name="Report"/>
<service name="Capture"/>
<service name="Event"/>
</parent-provides>
<default-route>
@ -29,9 +30,6 @@
<service name="Platform">
<default-policy> <child name="platform_drv"/> </default-policy> </service>
<service name="Input">
<default-policy> <child name="input_filter"/> </default-policy> </service>
<start name="report_rom">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Report"/> <service name="ROM"/> </provides>
@ -170,20 +168,41 @@
</route>
</start>
<start name="input_filter" caps="90" priority="-1">
<start name="event_filter" caps="90" priority="-1">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Input"/> </provides>
<provides> <service name="Event"/> </provides>
<route>
<service name="ROM" label="config"> <parent label="input_filter.config"/> </service>
<service name="ROM" label="config"> <parent label="event_filter.config"/> </service>
<service name="ROM" label="numlock.remap"> <child name="numlock_remap_rom"/> </service>
<service name="ROM" label="capslock"> <parent label="capslock"/> </service>
<service name="Input" label="ps2"> <child name="ps2_drv"/> </service>
<service name="Input" label="usb"> <child name="usb_drv"/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service>
<service name="Event"> <parent/> </service>
</route>
</start>
<start name="ps2" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="ps2"/> </service>
<service name="Input"> <child name="ps2_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="usb" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="usb"/> </service>
<service name="Input"> <child name="usb_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>

View File

@ -1,6 +1,4 @@
<config>
<input label="ps2"/>
<input label="usb"/>
<output>
<chargen>
<remap>
@ -37,4 +35,6 @@
<include rom="special.chargen"/>
</chargen>
</output>
<policy label="ps2" input="ps2"/>
<policy label="usb" input="usb"/>
</config>

View File

@ -39,16 +39,18 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="pointer" layer="1" label="no" content="client" origin="pointer" />
<domain name="default" layer="2" label="no" content="client" hover="always" />

View File

@ -41,9 +41,9 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="report_rom">
@ -57,9 +57,11 @@ install_config {
<start name="nitpicker">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<report pointer="yes" />
<domain name="default" layer="2" content="client" label="no"/>
<default-policy domain="default"/>

View File

@ -43,16 +43,18 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker" caps="200">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="" layer="2" content="client" label="no" />
<default-policy domain=""/>
<report pointer="yes" />

View File

@ -52,16 +52,18 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<background color="#123456"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="3" content="client" label="no" hover="always" />

View File

@ -50,8 +50,8 @@ install_config {
<resource name="RAM" quantum="64M" constrain_phys="yes"/>
<binary name="init"/>
<route>
<service name="ROM" label_last="managed/input_filter">
<parent label="input_filter.config"/> </service>
<service name="ROM" label_last="managed/event_filter">
<parent label="event_filter.config"/> </service>
<service name="ROM" label_last="numlock_remap">
<parent label="numlock_remap.config"/> </service>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
@ -61,13 +61,11 @@ install_config {
<service name="ROM" label="usb_policy"><child name="dynamic_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<service name="Report"> <child name="report_rom"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides>
<service name="Input"/>
<service name="Block"/>
</provides>
<provides> <service name="Block"/> </provides>
</start>
<start name="dynamic_rom">
@ -99,9 +97,11 @@ install_config {
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/>
<capture/> <event/>
<report displays="yes"/>
</config>
<route>
@ -115,7 +115,6 @@ install_config {
<config>
<check_ahci_block_device label="ahci-1" block_count="65536" block_size="512"
model="QEMU HARDDISK"/>
<check_input/>
<check_displays/>
</config>
<route>

View File

@ -38,16 +38,18 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="3" content="client" label="no" focus="click" hover="always" />

View File

@ -72,9 +72,9 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="report_rom">
@ -92,9 +92,11 @@ install_config {
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<report hover="yes" displays="yes"/>
<background color="#000000"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -42,16 +42,18 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<background color="#123456"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -33,9 +33,9 @@ append config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="timer">
@ -45,9 +45,11 @@ append config {
<start name="nitpicker">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="default" layer="2" content="client" label="no"/>
<domain name="nano3d" layer="1" content="client" label="no" origin="pointer"/>

View File

@ -99,10 +99,10 @@ install_config {
<rom name="wifi" label="wifi.config"/>
<rom name="installation"/>
<rom name="runtime" label="empty_runtime.config"/>
<rom name="input_filter" label="input_filter.config"/>
<rom name="event_filter" label="event_filter.config"/>
<inline name="depot_query"><query/></inline>
</dir>
<rom name="input_filter" label="input_filter.config"/>
<rom name="event_filter" label="event_filter.config"/>
<rom name="fb_drv" label="fb_drv.config"/>
<rom name="nitpicker" label="nitpicker.config"/>
<rom name="numlock_remap" label="numlock_remap.config"/>
@ -243,9 +243,9 @@ install_config {
<service name="ROM" label="config">
<child name="config_fs_rom" label="drivers"/> </service>
<service name="ROM" label_last="capslock"> <child name="report_rom"/> </service>
<service name="ROM" label_last="input_filter.config">
<child name="config_fs_rom" label="managed/input_filter"/> </service>
<service name="ROM" label_prefix="input_filter" label_suffix=".chargen">
<service name="ROM" label_last="event_filter.config">
<child name="config_fs_rom" label="managed/event_filter"/> </service>
<service name="ROM" label_prefix="event_filter" label_suffix=".chargen">
<child name="config_fs_rom"/> </service>
<service name="ROM" label_last="fb_drv.config">
<child name="config_fs_rom" label="managed/fb_drv"/> </service>
@ -256,11 +256,11 @@ install_config {
<service name="ROM" label_last="numlock"> <child name="report_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<service name="Report"> <child name="fs_report"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides>
<service name="Input"/>
<service name="Block"/>
<service name="Usb"/>
<service name="Platform"/>
@ -269,7 +269,9 @@ install_config {
<start name="nitpicker" caps="1000">
<resource name="RAM" quantum="6M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<route>
<service name="ROM" label="config">
<child name="config_fs_rom" label="nitpicker"/> </service>
@ -278,7 +280,6 @@ install_config {
<service name="Report" label="keystate">
<child name="report_logger"/> </service>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Input"> <child name="drivers"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
@ -516,11 +517,11 @@ file copy -force [genode_dir]/repos/gems/recipes/raw/drivers_managed-pc/drivers.
[run_dir]/genode/drivers.config
foreach file { en_us.chargen de_ch.chargen de_de.chargen fr_ch.chargen fr_fr.chargen special.chargen } {
file copy -force [genode_dir]/repos/os/src/server/input_filter/$file \
file copy -force [genode_dir]/repos/os/src/server/event_filter/$file \
[run_dir]/genode/$file }
file copy -force [genode_dir]/repos/gems/recipes/raw/drivers_managed-pc/input_filter.config \
[run_dir]/genode/input_filter.config
file copy -force [genode_dir]/repos/gems/recipes/raw/drivers_managed-pc/event_filter.config \
[run_dir]/genode/event_filter.config
file copy -force [genode_dir]/repos/gems/recipes/raw/depot_download/depot_download.config \
[run_dir]/genode/depot_download.config

View File

@ -221,8 +221,8 @@
<child name="config_fs_report" label="managed -> nic_router"/> </service>
<service name="Report" label="fb_drv_config">
<child name="config_fs_report" label="managed -> fb_drv"/> </service>
<service name="Report" label="input_filter_config">
<child name="config_fs_report" label="managed -> input_filter"/> </service>
<service name="Report" label="event_filter_config">
<child name="config_fs_report" label="managed -> event_filter"/> </service>
<service name="Report" label="installation_config">
<child name="config_fs_report" label="managed -> installation"/> </service>
<service name="Report" label="depot_query">

View File

@ -1,5 +1,5 @@
<config focus="rom" request_framebuffer="no">
<capture/>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<report hover="yes" focus="yes" clicked="yes" keystate="no" displays="yes"/>
<background color="#000000"/>

View File

@ -3,6 +3,8 @@ create_boot_directory
import_from_depot [depot_user]/src/[base_src] \
[depot_user]/pkg/[drivers_interactive_pkg] \
[depot_user]/pkg/terminal \
[depot_user]/src/nitpicker \
[depot_user]/src/gui_fb \
[depot_user]/src/init
install_config {
@ -35,11 +37,32 @@ install_config {
<route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides>
<service name="Input"/> <service name="Framebuffer"/>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="default" layer="2" content="client" label="no" hover="always"/>
<default-policy domain="default"/>
</config>
</start>
<start name="gui_fb">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Framebuffer"/> <service name="Input"/> </provides>
<config/>
<route>
<service name="Gui"> <child name="nitpicker" label="terminal"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="terminal" caps="110">
@ -57,6 +80,10 @@ install_config {
</config>
}
set fd [open [run_dir]/genode/focus w]
puts $fd "<focus label=\"terminal\" domain=\"default\"/>"
close $fd
build { server/terminal test/terminal_echo }
build_boot_image { terminal test-terminal_echo }

View File

@ -42,25 +42,24 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" content="client" label="no" focus="click" hover="always" />
<policy label_prefix="pointer" domain="pointer"/>
<default-policy domain="default"/>
</config>
<route>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
<route> <any-service> <parent/> <any-child/> </any-service> </route>
</start>
<start name="pointer">

View File

@ -42,9 +42,9 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="report_rom">
@ -58,9 +58,11 @@ install_config {
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<report hover="yes"/>
<background color="#123456"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -40,24 +40,23 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="default" layer="2" content="client" label="no"
hover="always" width="1024" height="768"/>
<default-policy domain="default"/>
</config>
<route>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
<route> <any-service> <parent/> <any-child/> </any-service> </route>
</start>
<start name="gui_fb">

View File

@ -45,16 +45,18 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" content="client" label="no" hover="always"/>

View File

@ -106,12 +106,12 @@ struct Sculpt::Main : Input_event_handler,
_handle_gui_mode();
}
Managed_config<Main> _input_filter_config {
_env, "config", "input_filter", *this, &Main::_handle_input_filter_config };
Managed_config<Main> _event_filter_config {
_env, "config", "event_filter", *this, &Main::_handle_event_filter_config };
void _handle_input_filter_config(Xml_node)
void _handle_event_filter_config(Xml_node)
{
_input_filter_config.try_generate_manually_managed();
_event_filter_config.try_generate_manually_managed();
}
Attached_rom_dataspace _gui_hover { _env, "nitpicker_hover" };

View File

@ -129,11 +129,6 @@ struct Test::Main
Main(Env &env) : _env(env)
{
if (_config.xml().has_sub_node("check_input")) {
log("connect to input driver");
Input::Connection input(_env);
}
_block_devices.sigh(_block_devices_update_handler);
_check_conditions();
}

View File

@ -14,10 +14,11 @@ set build_components {
drivers/input
server/acpi_input
server/dynamic_rom
server/input_filter
server/event_filter
server/report_rom
server/event_dump
app/acpica
test/input
app/input_event_client
}
set use_acpica_as_acpi_drv 0
@ -130,22 +131,21 @@ append config {
</start>}
append config {
<start name="input_filter">
<start name="event_filter">
<resource name="RAM" quantum="1M" />
<provides> <service name="Input" /> </provides>
<provides> <service name="Event" /> </provides>
<config>
<input label="ps2" />
<input label="acpi" />
<output>
<merge>
<input name="ps2"/>
<input name="acpi"/>
</merge>
</output>
<policy label="ps2" input="ps2"/>
<policy label="acpi" input="acpi"/>
</config>
<route>
<service name="Input" label="ps2"> <child name="ps2_drv" /> </service>
<service name="Input" label="acpi"> <child name="acpi_input" /> </service>
<service name="Event"> <child name="event_dump" /> </service>
<any-service> <parent/> </any-service>
</route>
</start>}
@ -162,16 +162,38 @@ append config {
</route>
</start>
<start name="test-input">
<start name="ps2" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="ps2"/> </service>
<service name="Input"> <child name="ps2_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="event_dump">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Event"/> </provides>
<route>
<service name="Input"> <child name="input_filter"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>}
append config {
<start name="acpi" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="acpi"/> </service>
<service name="Input"> <child name="acpi_input"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="acpi_input">
<resource name="RAM" quantum="1M"/>
<provides><service name="Input"/></provides>
@ -211,12 +233,13 @@ set boot_modules {
ld.lib.so
timer
ps2_drv
input_filter
event_filter
report_rom
dynamic_rom
acpica
acpi_input
test-input
event_dump
input_event_client
}
append_platform_drv_boot_modules

View File

@ -55,16 +55,18 @@ set config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker" caps="200">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" content="client" label="no" focus="click" hover="always" />
<policy label_prefix="pointer" domain="pointer"/>

View File

@ -41,16 +41,18 @@ set config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
<domain name="default" layer="2" content="client" label="no" hover="always"/>

View File

@ -70,30 +70,23 @@ proc qt5_parent_provides { } {
#
proc language_chargen { } { return "en_us" }
exec cp -f [genode_dir]/repos/os/src/server/input_filter/[language_chargen].chargen bin/
exec cp -f [genode_dir]/repos/os/src/server/input_filter/special.chargen bin/
exec cp -f [genode_dir]/repos/os/src/server/event_filter/[language_chargen].chargen bin/
exec cp -f [genode_dir]/repos/os/src/server/event_filter/special.chargen bin/
set qt5_input_filter_config {
<config>}
append_if [have_spec ps2] qt5_input_filter_config {
<input label="ps2"/>}
append_if [have_spec usb] qt5_input_filter_config {
<input label="usb"/>}
append_if [have_spec linux] qt5_input_filter_config {
<input label="sdl"/>}
append qt5_input_filter_config {
set qt5_event_filter_config {
<config>
<output>
<chargen>
<remap>
<include rom="numlock.remap"/>
<merge>}
append_if [have_spec ps2] qt5_input_filter_config {
append_if [have_spec ps2] qt5_event_filter_config {
<input name="ps2"/>}
append_if [have_spec usb] qt5_input_filter_config {
append_if [have_spec usb] qt5_event_filter_config {
<input name="usb"/>}
append_if [have_spec linux] qt5_input_filter_config {
append_if [have_spec linux] qt5_event_filter_config {
<input name="sdl"/>}
append qt5_input_filter_config {
append qt5_event_filter_config {
</merge>
</remap>
<mod1>
@ -109,17 +102,23 @@ append qt5_input_filter_config {
<rom name="capslock"/>
</mod4>
<repeat delay_ms="500" rate_ms="50"/>}
append qt5_input_filter_config "
append qt5_event_filter_config "
<include rom=\"[language_chargen].chargen\"/>"
append qt5_input_filter_config {
append qt5_event_filter_config {
<include rom="special.chargen"/>
</chargen>
</output>
</config>
}
</output>}
append_if [have_spec ps2] qt5_event_filter_config {
<policy label="ps2" input="ps2"/>}
append_if [have_spec usb] qt5_event_filter_config {
<policy label="usb" input="usb"/>}
append_if [have_spec linux] qt5_event_filter_config {
<policy label="sdl" input="sdl"/>}
append qt5_event_filter_config {
</config>}
set fd [open bin/qt5_input_filter.config w]
puts $fd $qt5_input_filter_config
set fd [open bin/qt5_event_filter.config w]
puts $fd $qt5_event_filter_config
close $fd
@ -169,30 +168,32 @@ proc qt5_start_nodes { } {
</route>
</start>
<start name="drivers" caps="1000">
<start name="drivers" caps="1500">
<resource name="RAM" quantum="64M" constrain_phys="yes"/>
<binary name="init"/>
<route>
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="ROM" label="input_filter.config"> <parent label="qt5_input_filter.config"/> </service>
<service name="ROM" label="input_filter -> capslock"> <child name="wm_report_rom"/> </service>
<service name="ROM" label="input_filter -> numlock.remap"> <child name="numlock_remap_rom"/> </service>
<service name="ROM" label="event_filter.config"> <parent label="qt5_event_filter.config"/> </service>
<service name="ROM" label="event_filter -> capslock"> <child name="wm_report_rom"/> </service>
<service name="ROM" label="event_filter -> numlock.remap"> <child name="numlock_remap_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker" caps="200">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<route>
<service name="Report"> <child name="wm_report_rom"/> </service>
<any-service> <parent /> <any-child /> </any-service>
</route>
<config request_framebuffer="no">
<capture/>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<report focus="yes" hover="yes" xray="yes"/>
@ -240,7 +241,7 @@ proc qt5_start_nodes { } {
<policy label="clipboard -> focus" report="nitpicker -> focus"/>
<policy label="pointer -> hover" report="nitpicker -> hover"/>
<policy label="pointer -> xray" report="nitpicker -> xray"/>
<policy label="drivers -> input_filter -> capslock" report="global_keys_handler -> capslock"/>
<policy label="drivers -> event_filter -> capslock" report="global_keys_handler -> capslock"/>
<policy label="numlock_remap_rom -> numlock" report="global_keys_handler -> numlock"/>
<policy label="ps2_drv -> capslock" report="global_keys_handler -> capslock"/>
<policy label="ps2_drv -> numlock" report="global_keys_handler -> numlock"/>
@ -331,5 +332,5 @@ proc qt5_boot_modules { } {
lappend boot_modules [language_chargen].chargen
lappend boot_modules special.chargen
lappend boot_modules qt5_input_filter.config
lappend boot_modules qt5_event_filter.config
}

View File

@ -1,4 +1,3 @@
_/src/fb_sdl
_/src/input_filter
_/src/input_event_bridge
_/src/event_filter
_/raw/drivers_interactive-linux

View File

@ -2,5 +2,6 @@ _/src/platform_drv
_/src/ps2_drv
_/src/usb_drv
_/src/vesa_drv
_/src/input_filter
_/src/event_filter
_/src/input_event_client
_/raw/drivers_interactive-muen

View File

@ -1,4 +1,5 @@
_/src/pbxa9_drivers
_/src/platform_drv
_/src/input_filter
_/src/event_filter
_/src/input_event_client
_/raw/drivers_interactive-pbxa9

View File

@ -4,5 +4,6 @@ _/src/ps2_drv
_/src/usb_drv
_/src/vesa_drv
_/src/report_rom
_/src/input_filter
_/src/event_filter
_/src/input_event_client
_/raw/drivers_interactive-pc

View File

@ -15,9 +15,6 @@
<default caps="60"/>
<service name="Input">
<default-policy> <child name="dummy_input_drv"/> </default-policy> </service>
<start name="platform_drv" caps="200">
<binary name="imx53_platform_drv"/>
<resource name="RAM" quantum="3M" constrain_phys="yes"/>
@ -71,14 +68,4 @@
</route>
</start>
<start name="dummy_input_drv" caps="100">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Input"/> </provides>
<route>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
</route>
</start>
</config>

View File

@ -1,7 +1,7 @@
content: drivers.config input_filter.config en_us.chargen special.chargen
content: drivers.config event_filter.config en_us.chargen special.chargen
drivers.config input_filter.config:
drivers.config event_filter.config:
cp $(REP_DIR)/recipes/raw/drivers_interactive-linux/$@ $@
en_us.chargen special.chargen:
cp $(REP_DIR)/src/server/input_filter/$@ $@
cp $(REP_DIR)/src/server/event_filter/$@ $@

View File

@ -6,37 +6,28 @@
<service name="LOG"/>
<service name="Timer"/>
<service name="Capture"/>
<service name="Event"/>
</parent-provides>
<service name="Input">
<default-policy> <child name="input_filter"/> </default-policy> </service>
<start name="input_event_bridge" caps="100">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Input"/> <service name="Event"/> </provides>
<route> <any-service> <parent/> </any-service> </route>
<config/>
</start>
<start name="fb_sdl" caps="100" ld="no">
<resource name="RAM" quantum="10M"/>
<route>
<service name="Event"> <child name="input_event_bridge"/> </service>
<service name="Event"> <child name="event_filter" label="sdl"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="input_filter" caps="80">
<start name="event_filter" caps="80">
<resource name="RAM" quantum="1280K"/>
<provides> <service name="Input"/> </provides>
<provides> <service name="Event"/> </provides>
<route>
<service name="ROM" label="config"> <parent label="input_filter.config"/> </service>
<service name="Input" label="sdl"> <child name="input_event_bridge"/> </service>
<service name="ROM" label="config"> <parent label="event_filter.config"/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service>
<service name="Event"> <parent/> </service>
</route>
</start>
</config>

View File

@ -1,5 +1,4 @@
<config>
<input label="sdl"/>
<output>
<chargen>
<accelerate max="50" sensitivity_percent="1000" curve="127">
@ -23,4 +22,5 @@
<include rom="special.chargen"/>
</chargen>
</output>
<default-policy input="sdl"/>
</config>

View File

@ -1,7 +1,7 @@
content: drivers.config fb_drv.config input_filter.config en_us.chargen special.chargen
content: drivers.config fb_drv.config event_filter.config en_us.chargen special.chargen
drivers.config fb_drv.config input_filter.config:
drivers.config fb_drv.config event_filter.config:
cp $(REP_DIR)/recipes/raw/drivers_interactive-muen/$@ $@
en_us.chargen special.chargen:
cp $(REP_DIR)/src/server/input_filter/$@ $@
cp $(REP_DIR)/src/server/event_filter/$@ $@

View File

@ -11,13 +11,11 @@
<service name="LOG"/>
<service name="Timer"/>
<service name="Capture"/>
<service name="Event"/>
</parent-provides>
<default caps="60"/>
<service name="Input">
<default-policy> <child name="input_filter"/> </default-policy> </service>
<start name="platform_drv" caps="200">
<resource name="RAM" quantum="3M" constrain_phys="yes"/>
<provides>
@ -85,13 +83,12 @@
</route>
</start>
<start name="input_filter" caps="90">
<start name="event_filter" caps="90">
<resource name="RAM" quantum="1280K"/>
<provides> <service name="Input"/> </provides>
<provides> <service name="Event"/> </provides>
<route>
<service name="ROM" label="config"> <parent label="input_filter.config"/> </service>
<service name="Input" label="ps2"> <child name="ps2_drv"/> </service>
<service name="Input" label="usb"> <child name="usb_drv"/> </service>
<service name="ROM" label="config"> <parent label="event_filter.config"/> </service>
<service name="Event"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
@ -100,4 +97,26 @@
</route>
</start>
<start name="ps2" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="ps2"/> </service>
<service name="Input"> <child name="ps2_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="usb" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="usb"/> </service>
<service name="Input"> <child name="usb_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
</config>

View File

@ -1,6 +1,4 @@
<config>
<input label="ps2"/>
<input label="usb"/>
<output>
<chargen>
<merge>
@ -27,4 +25,6 @@
<include rom="special.chargen"/>
</chargen>
</output>
<policy label_prefix="ps2_drv" input="ps2"/>
<policy label_prefix="usb_drv" input="usb"/>
</config>

View File

@ -1,7 +1,7 @@
content: drivers.config input_filter.config en_us.chargen special.chargen
content: drivers.config event_filter.config en_us.chargen special.chargen
drivers.config input_filter.config:
drivers.config event_filter.config:
cp $(REP_DIR)/recipes/raw/drivers_interactive-pbxa9/$@ $@
en_us.chargen special.chargen:
cp $(REP_DIR)/src/server/input_filter/$@ $@
cp $(REP_DIR)/src/server/event_filter/$@ $@

View File

@ -8,13 +8,11 @@
<service name="LOG"/>
<service name="Timer"/>
<service name="Capture"/>
<service name="Event"/>
</parent-provides>
<default caps="100"/>
<service name="Input">
<default-policy> <child name="input_filter"/> </default-policy> </service>
<start name="platform_drv">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Platform"/> </provides>
@ -91,21 +89,30 @@
</route>
</start>
<start name="input_filter" caps="80">
<start name="event_filter" caps="90">
<resource name="RAM" quantum="1280K"/>
<provides> <service name="Input"/> </provides>
<provides> <service name="Event"/> </provides>
<route>
<service name="ROM" label="config">
<parent label="input_filter.config"/>
</service>
<service name="Input" label="ps2">
<child name="ps2_drv"/>
<parent label="event_filter.config"/>
</service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <parent/> </service>
<service name="Event"> <parent/> </service>
</route>
</start>
<start name="ps2" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="ps2"/> </service>
<service name="Input"> <child name="ps2_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
</config>

View File

@ -1,5 +1,4 @@
<config>
<input label="ps2"/>
<output>
<chargen>
<accelerate max="50" sensitivity_percent="1000" curve="127">
@ -23,4 +22,5 @@
<include rom="special.chargen"/>
</chargen>
</output>
<policy label="ps2" input="ps2"/>
</config>

View File

@ -1,7 +1,7 @@
content: drivers.config fb_drv.config input_filter.config en_us.chargen special.chargen
content: drivers.config fb_drv.config event_filter.config en_us.chargen special.chargen
drivers.config fb_drv.config input_filter.config:
drivers.config fb_drv.config event_filter.config:
cp $(REP_DIR)/recipes/raw/drivers_interactive-pc/$@ $@
en_us.chargen special.chargen:
cp $(REP_DIR)/src/server/input_filter/$@ $@
cp $(REP_DIR)/src/server/event_filter/$@ $@

View File

@ -11,13 +11,11 @@
<service name="LOG"/>
<service name="Timer"/>
<service name="Capture"/>
<service name="Event"/>
</parent-provides>
<default caps="60"/>
<service name="Input">
<default-policy> <child name="input_filter"/> </default-policy> </service>
<start name="acpi_drv" caps="250">
<resource name="RAM" quantum="4M"/>
<route>
@ -118,13 +116,12 @@
</route>
</start>
<start name="input_filter" caps="90">
<start name="event_filter" caps="90">
<resource name="RAM" quantum="1280K"/>
<provides> <service name="Input"/> </provides>
<provides> <service name="Event"/> </provides>
<route>
<service name="ROM" label="config"> <parent label="input_filter.config"/> </service>
<service name="Input" label="ps2"> <child name="ps2_drv"/> </service>
<service name="Input" label="usb"> <child name="usb_drv"/> </service>
<service name="ROM" label="config"> <parent label="event_filter.config"/> </service>
<service name="Event"> <parent/> </service>
<service name="ROM"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="CPU"> <parent/> </service>
@ -133,4 +130,26 @@
</route>
</start>
<start name="ps2" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="ps2"/> </service>
<service name="Input"> <child name="ps2_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="usb" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="usb"/> </service>
<service name="Input"> <child name="usb_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
</config>

View File

@ -1,6 +1,4 @@
<config>
<input label="ps2"/>
<input label="usb"/>
<output>
<chargen>
<merge>
@ -27,4 +25,6 @@
<include rom="special.chargen"/>
</chargen>
</output>
<policy label="ps2" input="ps2"/>
<policy label="usb" input="usb"/>
</config>

View File

@ -1,2 +1,2 @@
SRC_DIR = src/server/input_filter
SRC_DIR = src/server/event_filter
include $(GENODE_DIR)/repos/base/recipes/src/content.inc

View File

@ -0,0 +1 @@
2020-07-16 b70ed9b9578b7d5713d61bbe4fff8d418d7f9304

View File

@ -1,4 +1,4 @@
base
os
input_session
event_session
timer_session

View File

@ -7,9 +7,8 @@ include/gpio:
cp -r $(REP_DIR)/include/gpio $@
src/drivers:
mkdir -p $@/framebuffer/spec $@/input $@/gpio/spec
mkdir -p $@/framebuffer/spec $@/gpio/spec
cp -r $(REP_DIR)/src/drivers/gpio/spec/imx $@/gpio/spec/
cp -r $(REP_DIR)/src/drivers/gpio/spec/imx53 $@/gpio/spec/
cp -r $(REP_DIR)/src/drivers/framebuffer/spec/imx53 $@/framebuffer/spec/
cp -r $(REP_DIR)/include/spec/imx53/imx_framebuffer_session $@/framebuffer/spec/imx53/
cp -r $(REP_DIR)/src/drivers/input/dummy $@/input/

View File

@ -1 +0,0 @@
2020-07-12 a498492b515f8bb5ebf76b61de13b8aeea6bf012

View File

@ -48,9 +48,9 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="report_rom">
@ -75,11 +75,12 @@ install_config {
<output node="config">
<attribute name="request_framebuffer" value="no"/>
<attribute name="request_input" value="no"/>
<attribute name="focus" value="rom"/>
<inline>
<report focus="yes" xray="yes" hover="yes" keystate="yes"
clicked="yes"/>
<capture/>
<capture/> <event/>
<domain name="pointer" layer="1" origin="pointer"
content="client" label="no"/>
<domain name="panel" layer="2"
@ -150,7 +151,9 @@ install_config {
<start name="nitpicker" caps="120">
<resource name="RAM" quantum="1216K"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<route>
<service name="ROM" label="config">
<child name="nitpicker_config"/> </service>

View File

@ -17,7 +17,7 @@ proc test_char_repeat { } {
set build_components {
core init timer
server/report_rom server/input_filter test/input_filter
server/report_rom server/event_filter test/event_filter
}
build $build_components
@ -55,47 +55,50 @@ append config {
<resource name="RAM" quantum="2M"/>
<provides> <service name="ROM"/> <service name="Report"/> </provides>
<config>
<policy label_prefix="input_filter -> config"
report="test-input_filter -> input_filter.config"/>
<policy label_prefix="input_filter -> chargen_include"
report="test-input_filter -> chargen_include"/>
<policy label_prefix="input_filter -> remap_include"
report="test-input_filter -> remap_include"/>
<policy label_prefix="input_filter -> capslock"
report="test-input_filter -> capslock"/>
<policy label_prefix="event_filter -> config"
report="test-event_filter -> event_filter.config"/>
<policy label_prefix="event_filter -> chargen_include"
report="test-event_filter -> chargen_include"/>
<policy label_prefix="event_filter -> remap_include"
report="test-event_filter -> remap_include"/>
<policy label_prefix="event_filter -> capslock"
report="test-event_filter -> capslock"/>
</config>
</start>
<start name="input_filter" priority="-1">
<start name="event_filter" priority="-1">
<resource name="RAM" quantum="2M"/>
<provides> <service name="Input"/> </provides>
<provides> <service name="Event"/> </provides>
<route>
<service name="ROM" label="config"> <child name="report_rom"/> </service>
<service name="ROM" label="chargen_include"> <child name="report_rom"/> </service>
<service name="ROM" label="remap_include"> <child name="report_rom"/> </service>
<service name="ROM" label="capslock"> <child name="report_rom"/> </service>
<service name="Input"> <child name="test-input_filter"/> </service>
<service name="Event"> <child name="test-event_filter"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="test-input_filter" priority="-1">
<start name="test-event_filter" priority="-1">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Input"/> </provides>
<provides> <service name="Event"/> </provides>
<config>
<driver name="usb"/>
<driver name="ps2"/>
<message string="test merging of two input sources"/>
<filter_config>
<input label="ps2"/>
<input label="usb"/>
<output>
<merge>
<input name="ps2"/>
<input name="usb"/>
</merge>
</output>
<policy label_suffix="ps2" input="ps2"/>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="250"/>
@ -111,8 +114,6 @@ append config {
<message string="test key remapping"/>
<filter_config>
<input label="ps2"/>
<input label="usb"/>
<output>
<remap>
<merge>
@ -125,6 +126,8 @@ append config {
<key name="KEY_A" to="KEY_B"/>
</remap>
</output>
<policy label_suffix="ps2" input="ps2"/>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="250"/>
@ -144,8 +147,8 @@ append config {
<expect_press code="KEY_B"/>
<filter_config>
<input label="usb"/>
<output> <input name="usb"/> </output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="250"/>
@ -153,7 +156,6 @@ append config {
<usb> <release code="KEY_A"/> </usb>
<expect_release code="KEY_B"/>
<!-- input_filter now requests a new input session from us -->
<sleep ms="100"/>
<!-- now the default configuration is expected to take effect -->
@ -161,11 +163,12 @@ append config {
<expect_press code="KEY_A"/>
<expect_release code="KEY_A"/>
<!-- disconnect ps2 to avoid warnings by the event filter -->
<driver name="ps2" connected="no"/>
<message string="test emission of characters"/>
<filter_config>
<input label="usb"/>
<output>
<chargen>
<input name="usb"/>
@ -176,6 +179,7 @@ append config {
<map mod1="yes"> <key name="KEY_A" char="A"/> </map>
</chargen>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="250"/>
<usb>
@ -203,7 +207,6 @@ append_if [test_char_repeat] config {
<message string="test character repeat"/>
<filter_config>
<input label="usb"/>
<output>
<chargen>
<input name="usb"/>
@ -211,6 +214,7 @@ append_if [test_char_repeat] config {
<map> <key name="KEY_A" char="a"/> </map>
</chargen>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="500"/>
<usb> <press code="KEY_A"/> </usb>
@ -234,7 +238,6 @@ append config {
<message string="capslock handling"/>
<filter_config>
<input label="usb"/>
<output>
<chargen>
<remap>
@ -245,12 +248,13 @@ append config {
<map mod4="yes"> <key name="KEY_A" char="A"/> </map>
</chargen>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<!--
Leave the 'capslock' ROM initially undefined, which prompts
the input filter to complain about the modifier state being
the event filter to complain about the modifier state being
unavailable. However, as soon as 'capslock' becomes defined,
the input filter is expected to re-processes its configuration.
the event filter is expected to re-processes its configuration.
-->
<sleep ms="250"/>
<capslock enabled="no"/>
@ -270,7 +274,6 @@ append config {
<message string="sequence handling"/>
<filter_config>
<input label="usb"/>
<output>
<chargen>
<remap>
@ -286,6 +289,7 @@ append config {
<sequence first="0x0300" second="0x0065" code="0x00e8"/> <!-- LATIN SMALL LETTER E WITH GRAVE -->
</chargen>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="250"/>
<usb>
@ -320,7 +324,6 @@ append config {
<message string="button-scroll feature"/>
<filter_config>
<input label="usb"/>
<output>
<button-scroll>
<input name="usb"/>
@ -328,6 +331,7 @@ append config {
<horizontal button="KEY_LEFTSHIFT" speed_percent="50"/>
</button-scroll>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="100"/>
<usb>
@ -359,12 +363,12 @@ append config {
<!-- linear acceleration -->
<filter_config>
<input label="usb"/>
<output>
<accelerate max="100" curve="0" sensitivity_percent="200">
<input name="usb"/>
</accelerate>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="100"/>
<usb>
@ -380,12 +384,12 @@ append config {
<!-- non-linear acceleration -->
<filter_config>
<input label="usb"/>
<output>
<accelerate max="100" curve="127" sensitivity_percent="200">
<input name="usb"/>
</accelerate>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="100"/>
<usb>
@ -411,13 +415,13 @@ append config {
<remap_include> </remap_include>
<chargen_include> </chargen_include>
<filter_config>
<input label="usb"/>
<output>
<chargen>
<input name="usb"/>
<include rom="nonexisting_include"/>
</chargen>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="100"/>
@ -425,13 +429,13 @@ append config {
<message string="detect top-level node mismatch in included ROM"/>
<filter_config>
<input label="usb"/>
<output>
<chargen>
<input name="usb"/>
<include rom="remap_include"/>
</chargen>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="100"/>
@ -440,13 +444,13 @@ append config {
<chargen_include> <include rom="chargen_include"/> </chargen_include>
<filter_config>
<input label="usb"/>
<output>
<chargen>
<input name="usb"/>
<include rom="chargen_include"/>
</chargen>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="100"/>
@ -457,13 +461,13 @@ append config {
<map> <key name="KEY_A" char="a"/> </map>
</chargen_include>
<filter_config>
<input label="usb"/>
<output>
<chargen>
<input name="usb"/>
<include rom="chargen_include"/>
</chargen>
</output>
<policy label_suffix="usb" input="usb"/>
</filter_config>
<sleep ms="100"/>
<usb> <press code="KEY_A"/> <release code="KEY_A"/> </usb>
@ -481,7 +485,7 @@ append config {
</config>
<route>
<service name="Input"> <child name="input_filter"/> </service>
<service name="Event"> <child name="event_filter"/> </service>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<any-service> <parent/> </any-service>
@ -497,11 +501,11 @@ install_config $config
#
set boot_modules { core ld.lib.so init timer report_rom
input_filter test-input_filter }
event_filter test-event_filter }
build_boot_image $boot_modules
append qemu_args " -nographic "
run_genode_until {.*child "test-input_filter" exited with exit value 0.*} 60
run_genode_until {.*child "test-event_filter" exited with exit value 0.*} 60

View File

@ -49,23 +49,22 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="default" layer="1" width="1024" height="768"/>
<default-policy domain="default"/>
</config>
<route>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
<route> <any-service> <parent/> <any-child/> </any-service> </route>
</start>
<start name="gui_fb">

View File

@ -3,7 +3,7 @@ import_from_depot [depot_user]/src/[base_src] \
[depot_user]/pkg/[drivers_interactive_pkg] \
[depot_user]/src/init
build { test/framebuffer }
build { server/event_dump test/framebuffer }
install_config {
<config>
@ -34,9 +34,15 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="test-framebuffer"/> </service>
<service name="Event"> <child name="event_dump"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="event_dump">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Event"/> </provides>
<config/>
</start>
<start name="test-framebuffer">
@ -44,7 +50,9 @@ install_config {
<provides> <service name="Capture"/> </provides>
<config/>
</start>
</config>}
build_boot_image { test-framebuffer }
build_boot_image { event_dump test-framebuffer }
run_genode_until forever

View File

@ -38,16 +38,18 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="" layer="2" /> <default-policy domain=""/>
</config>
</start>

View File

@ -12,7 +12,6 @@ set build_components {
server/report_rom
server/dynamic_rom
server/nitpicker
server/input_event_bridge
app/pointer
test/pointer
test/nitpicker
@ -50,17 +49,7 @@ set config {
<service name="LOG"> <parent/> </service>
</route>
</start>
<start name="input_event_bridge">
<resource name="RAM" quantum="1M"/>
<provides>
<service name="Event"/>
<service name="Input"/>
</provides>
<config/>
<route>
<any-service> <parent/> </any-service>
</route>
</start>
<start name="fb_sdl" ld="no">
<resource name="RAM" quantum="6M"/>
<config buffered="yes" width="1280" height="720" depth="16"/>
@ -71,11 +60,9 @@ set config {
<service name="LOG"> <parent/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="input_event_bridge"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
</route>
</start>
<alias name="input_drv" child="input_event_bridge"/>
<alias name="fb_drv" child="fb_sdl"/>
<start name="report_rom_nitpicker">
<binary name="report_rom"/>
@ -93,28 +80,30 @@ set config {
<service name="LOG"> <parent/> </service>
</route>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<report focus="yes" hover="yes" xray="yes"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer"/>
<domain name="default" layer="3" content="client" label="yes" hover="always" focus="click"/>
<policy label_prefix="pointer" domain="pointer"/>
<default-policy domain="default"/>
<policy label_prefix="pointer" domain="pointer"/>
<default-policy domain="default"/>
<background color="#00426f"/> <!-- indigo -->
</config>
<route>
<service name="ROM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Input"> <child name="input_drv"/> </service>
<service name="Report"> <child name="report_rom_nitpicker"/> </service>
<service name="ROM"> <parent/> </service>
<service name="CPU"> <parent/> </service>
<service name="PD"> <parent/> </service>
<service name="LOG"> <parent/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Report"> <child name="report_rom_nitpicker"/> </service>
</route>
</start>
@ -132,6 +121,7 @@ set config {
</service>
</route>
</start>
<start name="shape-blade">
<binary name="test-pointer"/>
<resource name="RAM" quantum="2M"/>
@ -146,6 +136,7 @@ set config {
</service>
</route>
</start>
<start name="shape-bladex">
<binary name="test-pointer"/>
<resource name="RAM" quantum="2M"/>
@ -160,6 +151,7 @@ set config {
</service>
</route>
</start>
<start name="shape-smiley-config">
<binary name="dynamic_rom"/>
<resource name="RAM" quantum="1M"/>
@ -184,6 +176,7 @@ set config {
<service name="Timer"> <child name="timer"/> </service>
</route>
</start>
<start name="shape-smiley">
<binary name="test-pointer"/>
<resource name="RAM" quantum="2M"/>
@ -227,6 +220,7 @@ set config {
<service name="Gui"> <child name="nitpicker"/> </service>
</route>
</start>
<start name="test-label-smiley">
<binary name="testnit"/>
<resource name="RAM" quantum="2M"/>
@ -239,6 +233,7 @@ set config {
<service name="Gui"> <child name="nitpicker"/> </service>
</route>
</start>
<start name="test-label-arrow">
<binary name="testnit"/>
<resource name="RAM" quantum="2M"/>
@ -251,6 +246,7 @@ set config {
<service name="Gui"> <child name="nitpicker"/> </service>
</route>
</start>
<start name="test-label-blade">
<binary name="testnit"/>
<resource name="RAM" quantum="2M"/>
@ -263,6 +259,7 @@ set config {
<service name="Gui"> <child name="nitpicker"/> </service>
</route>
</start>
<start name="test-label-bladex">
<binary name="testnit"/>
<resource name="RAM" quantum="2M"/>
@ -292,7 +289,6 @@ set boot_modules {
pointer
test-pointer
testnit
input_event_bridge
}
# "lsort -unique" removes duplicates but core must be first

View File

@ -4,7 +4,7 @@ This component transforms input events originating from multiple sources.
Configuration
-------------
An input-filter configuration consists of two parts, a declaration of
An event-filter configuration consists of two parts, a declaration of
input sources ("Input" connections) that the component should request,
and the definition of a filter chain. Each input source is defined via
an '<input>' node with the name of the input source as 'name' attribute and
@ -120,7 +120,7 @@ sub nodes:
generated instantly on key press but only after the sequence is
completed. If an unfinished sequence can't be completed due to an
unmatched character, the sequence is aborted and no character is
generated. input_filter supports sequences of up to four characters.
generated. Sequences of up to four characters are supported.
For example, the French AZERTY keyboard layout [1] has a dead key
for Circumflex Accent "^" right of the P key (which is bracket left
@ -165,11 +165,11 @@ sub nodes:
Additional features
-------------------
The input filter is able to respond to configuration updates as well as updates
The event filter is able to respond to configuration updates as well as updates
of included ROM modules. However, a new configuration is applied only if the
input sources are in their idle state - that is, no key is pressed. This
ensures the consistency of the generated key events (for each press event there
must be a corresponding release event), on which clients of the input filter
must be a corresponding release event), on which clients of the event filter
may depend. However, this deferred reconfiguration can be overridden by setting
the 'force' attribute of the '<config>' node to 'yes'. If forced, the new
configuration is applied immediately.
@ -178,7 +178,7 @@ configuration is applied immediately.
Examples
--------
An automated test that exercises various corner cases of the input filter
can be found at _os/run/input_filter.run_. For a practical example of how
to use the input filter with the terminal, please refer to the
An automated test that exercises various corner cases of the event filter
can be found at _os/run/event_filter.run_. For a practical example of how
to use the event filter with the terminal, please refer to the
_gems/run/terminal_echo.run_ script.

View File

@ -11,8 +11,8 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__ACCELERATE_SOURCE_H_
#define _INPUT_FILTER__ACCELERATE_SOURCE_H_
#ifndef _EVENT_FILTER__ACCELERATE_SOURCE_H_
#define _EVENT_FILTER__ACCELERATE_SOURCE_H_
/* Genode includes */
#include <util/bezier.h>
@ -22,10 +22,10 @@
#include <source.h>
#include <key_code_by_name.h>
namespace Input_filter { class Accelerate_source; }
namespace Event_filter { class Accelerate_source; }
class Input_filter::Accelerate_source : public Source, Source::Filter
class Event_filter::Accelerate_source : public Source, Source::Filter
{
private:
@ -86,14 +86,12 @@ class Input_filter::Accelerate_source : public Source, Source::Filter
*/
void filter_event(Sink &destination, Input::Event const &event) override
{
using namespace Input;
Event ev = event;
Input::Event ev = event;
ev.handle_relative_motion([&] (int x, int y) {
ev = Relative_motion{_apply_acceleration(x),
_apply_acceleration(y)}; });
destination.submit_event(ev);
ev = Input::Relative_motion{_apply_acceleration(x),
_apply_acceleration(y)}; });
destination.submit(ev);
}
public:
@ -116,4 +114,4 @@ class Input_filter::Accelerate_source : public Source, Source::Filter
}
};
#endif /* _INPUT_FILTER__ACCELERATE_SOURCE_H_ */
#endif /* _EVENT_FILTER__ACCELERATE_SOURCE_H_ */

View File

@ -11,8 +11,8 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__BUTTON_SCROLL_SOURCE_H_
#define _INPUT_FILTER__BUTTON_SCROLL_SOURCE_H_
#ifndef _EVENT_FILTER__BUTTON_SCROLL_SOURCE_H_
#define _EVENT_FILTER__BUTTON_SCROLL_SOURCE_H_
/* Genode includes */
#include <input/keycodes.h>
@ -21,10 +21,10 @@
#include <source.h>
#include <key_code_by_name.h>
namespace Input_filter { class Button_scroll_source; }
namespace Event_filter { class Button_scroll_source; }
class Input_filter::Button_scroll_source : public Source, Source::Filter
class Event_filter::Button_scroll_source : public Source, Source::Filter
{
private:
@ -167,7 +167,7 @@ class Input_filter::Button_scroll_source : public Source, Source::Filter
wheel_y = _vertical_wheel .pending_motion();
if (wheel_x || wheel_y)
destination.submit_event(Input::Wheel{wheel_x, wheel_y});
destination.submit(Input::Wheel{wheel_x, wheel_y});
/*
* Submit both press event and release event of magic button at
@ -185,8 +185,8 @@ class Input_filter::Button_scroll_source : public Source, Source::Filter
if (_vertical_wheel .handle_deactivation(event)
| _horizontal_wheel.handle_deactivation(event)) {
destination.submit_event(Input::Press{key});
destination.submit_event(Input::Release{key});
destination.submit(Input::Press{key});
destination.submit(Input::Release{key});
}
});
return;
@ -196,7 +196,7 @@ class Input_filter::Button_scroll_source : public Source, Source::Filter
if (_vertical_wheel .suppressed(event)) return;
if (_horizontal_wheel.suppressed(event)) return;
destination.submit_event(event);
destination.submit(event);
}
static Xml_node _sub_node(Xml_node node, char const *type)
@ -224,4 +224,4 @@ class Input_filter::Button_scroll_source : public Source, Source::Filter
}
};
#endif /* _INPUT_FILTER__BUTTON_SCROLL_SOURCE_H_ */
#endif /* _EVENT_FILTER__BUTTON_SCROLL_SOURCE_H_ */

View File

@ -11,8 +11,8 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__CHARGEN_SOURCE_H_
#define _INPUT_FILTER__CHARGEN_SOURCE_H_
#ifndef _EVENT_FILTER__CHARGEN_SOURCE_H_
#define _EVENT_FILTER__CHARGEN_SOURCE_H_
/* Genode includes */
#include <input/keycodes.h>
@ -22,10 +22,10 @@
#include <timer_accessor.h>
#include <include_accessor.h>
namespace Input_filter { class Chargen_source; }
namespace Event_filter { class Chargen_source; }
class Input_filter::Chargen_source : public Source, Source::Filter
class Event_filter::Chargen_source : public Source, Source::Filter
{
private:
@ -544,9 +544,9 @@ class Input_filter::Chargen_source : public Source, Source::Filter
void emit_events(Source::Sink &destination)
{
for (unsigned i = 0; i < _pending_event_count; i++) {
destination.submit_event(Input::Press_char{Input::KEY_UNKNOWN,
_curr_character});
destination.submit_event(Input::Release{Input::KEY_UNKNOWN});
destination.submit(Input::Press_char{Input::KEY_UNKNOWN,
_curr_character});
destination.submit(Input::Release{Input::KEY_UNKNOWN});
}
_pending_event_count = 0;
@ -619,7 +619,7 @@ class Input_filter::Chargen_source : public Source, Source::Filter
});
/* forward filtered event */
destination.submit_event(ev);
destination.submit(ev);
}
Source &_source;
@ -761,4 +761,4 @@ class Input_filter::Chargen_source : public Source, Source::Filter
}
};
#endif /* _INPUT_FILTER__CHARGEN_SOURCE_H_ */
#endif /* _EVENT_FILTER__CHARGEN_SOURCE_H_ */

View File

@ -0,0 +1,218 @@
/*
* \brief Event service
* \author Norman Feske
* \date 2020-07-16
*/
/*
* Copyright (C) 2020 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__EVENT_SESSION_H_
#define _EVENT_FILTER__EVENT_SESSION_H_
/* Genode includes */
#include <event_session/event_session.h>
#include <root/component.h>
#include <base/session_object.h>
#include <base/attached_ram_dataspace.h>
#include <base/attached_rom_dataspace.h>
#include <os/session_policy.h>
/* local includes */
#include <source.h>
namespace Event_filter {
typedef String<Session_label::capacity()> Input_name;
class Event_session;
class Event_root;
}
class Event_filter::Event_session : public Session_object<Event::Session, Event_session>
{
private:
Input_name _input_name { }; /* may change on reconfiguration */
Source::Trigger &_trigger;
Constrained_ram_allocator _ram;
Attached_ram_dataspace _ds;
unsigned _pending_count = 0;
unsigned _key_cnt = 0;
template <typename FN>
void _for_each_pending_event(FN const &fn) const
{
Input::Event const * const events = _ds.local_addr<Input::Event const>();
for (unsigned i = 0; i < _pending_count; i++)
fn(events[i]);
}
public:
Event_session(Env &env,
Resources const &resources,
Label const &label,
Diag const &diag,
Source::Trigger &trigger)
:
Session_object(env.ep(), resources, label, diag),
_trigger(trigger),
_ram(env.ram(), _ram_quota_guard(), _cap_quota_guard()),
_ds(_ram, env.rm(), 4096)
{ }
/**
* Collect pending input from event client
*
* \param input_name name of queried input
*
* This method is called during processing of 'Main::trigger_generate'.
*/
template <typename FN>
void for_each_pending_event(Input_name const &input_name, FN const &fn) const
{
if (input_name == _input_name)
_for_each_pending_event(fn);
}
bool idle() const { return (_key_cnt == 0); }
/**
* (Re-)assign input name to session according to session policy
*/
void assign_input_name(Xml_node config)
{
_input_name = Input_name();
try {
Session_policy policy(_label, config);
_input_name = policy.attribute_value("input", Input_name());
} catch (Service_denied) { }
}
/*****************************
** Event session interface **
*****************************/
Dataspace_capability dataspace() { return _ds.cap(); }
void submit_batch(unsigned const count)
{
size_t const max_events = _ds.size() / sizeof(Input::Event);
if (count > max_events)
warning("number of events exceeds dataspace capacity");
_pending_count = min(count, max_events);
auto update_key_cnt = [&] (Input::Event const &event)
{
if (event.press()) _key_cnt++;
if (event.release()) _key_cnt--;
};
_for_each_pending_event(update_key_cnt);
_trigger.trigger_generate();
_pending_count = 0;
}
};
class Event_filter::Event_root : public Root_component<Event_session>
{
private:
Env &_env;
Source::Trigger &_trigger;
Attached_rom_dataspace const &_config;
Registry<Registered<Event_session>> _sessions { };
protected:
Event_session *_create_session(const char *args) override
{
Event_session &session = *new (md_alloc())
Registered<Event_session>(_sessions,
_env,
session_resources_from_args(args),
session_label_from_args(args),
session_diag_from_args(args),
_trigger);
session.assign_input_name(_config.xml());
return &session;
}
void _upgrade_session(Event_session *s, const char *args) override
{
s->upgrade(ram_quota_from_args(args));
s->upgrade(cap_quota_from_args(args));
}
void _destroy_session(Event_session *session) override
{
Genode::destroy(md_alloc(), session);
}
public:
/**
* Constructor
*/
Event_root(Env &env, Allocator &md_alloc, Source::Trigger &trigger,
Attached_rom_dataspace const &config)
:
Root_component<Event_session>(&env.ep().rpc_ep(), &md_alloc),
_env(env), _trigger(trigger), _config(config)
{ }
template <typename FN>
void for_each_pending_event(Input_name const &input_name, FN const &fn) const
{
_sessions.for_each([&] (Event_session const &session) {
session.for_each_pending_event(input_name, fn); });
}
/**
* Return true if no client holds any keys pressed
*/
bool all_sessions_idle() const
{
bool idle = true;
_sessions.for_each([&] (Event_session const &session) {
if (!session.idle())
idle = false; });
return idle;
}
void apply_config(Xml_node const &config)
{
_sessions.for_each([&] (Event_session &session) {
session.assign_input_name(config); });
}
};
#endif /* _EVENT_FILTER__EVENT_SESSION_H_ */

View File

@ -11,8 +11,8 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__INCLUDE_ACCESSOR_H_
#define _INPUT_FILTER__INCLUDE_ACCESSOR_H_
#ifndef _EVENT_FILTER__INCLUDE_ACCESSOR_H_
#define _EVENT_FILTER__INCLUDE_ACCESSOR_H_
/* Genode includes */
#include <util/xml_node.h>
@ -20,10 +20,10 @@
/* local includes */
#include <types.h>
namespace Input_filter { struct Include_accessor; }
namespace Event_filter { struct Include_accessor; }
class Input_filter::Include_accessor : Interface
class Event_filter::Include_accessor : Interface
{
public:
@ -64,4 +64,4 @@ class Input_filter::Include_accessor : Interface
}
};
#endif /* _INPUT_FILTER__INCLUDE_ACCESSOR_H_ */
#endif /* _EVENT_FILTER__INCLUDE_ACCESSOR_H_ */

View File

@ -0,0 +1,51 @@
/*
* \brief Input-event source that obtains events from input connection
* \author Norman Feske
* \date 2017-02-01
*/
/*
* Copyright (C) 2017 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__INPUT_SOURCE_H_
#define _EVENT_FILTER__INPUT_SOURCE_H_
/* local includes */
#include <source.h>
#include <event_session.h>
namespace Event_filter { class Input_source; }
class Event_filter::Input_source : public Source
{
private:
Input_name const _input_name;
Event_root const &_event_root;
public:
static char const *name() { return "input"; }
Input_source(Owner &owner, Input_name const &input_name,
Event_root const &event_root)
:
Source(owner), _input_name(input_name), _event_root(event_root)
{ }
void generate(Sink &sink) override
{
_event_root.for_each_pending_event(_input_name,
[&] (Input::Event const &event) {
sink.submit(event);
});
}
};
#endif /* _EVENT_FILTER__INPUT_SOURCE_H_ */

View File

@ -11,14 +11,14 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__KEY_CODE_BY_NAME_H_
#define _INPUT_FILTER__KEY_CODE_BY_NAME_H_
#ifndef _EVENT_FILTER__KEY_CODE_BY_NAME_H_
#define _EVENT_FILTER__KEY_CODE_BY_NAME_H_
/* Genode includes */
#include <base/exception.h>
#include <input/keycodes.h>
namespace Input_filter {
namespace Event_filter {
struct Unknown_key : Genode::Exception { };
@ -38,4 +38,4 @@ namespace Input_filter {
}
}
#endif /* _INPUT_FILTER__KEY_CODE_BY_NAME_H_ */
#endif /* _EVENT_FILTER__KEY_CODE_BY_NAME_H_ */

View File

@ -12,12 +12,10 @@
*/
/* Genode includes */
#include <input/component.h>
#include <os/static_root.h>
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <base/heap.h>
#include <timer_session/connection.h>
#include <event_session/connection.h>
/* local includes */
#include <input_source.h>
@ -26,12 +24,12 @@
#include <chargen_source.h>
#include <button_scroll_source.h>
#include <accelerate_source.h>
#include <event_session.h>
namespace Input_filter { struct Main; }
namespace Event_filter { struct Main; }
struct Input_filter::Main : Input_connection::Avail_handler,
Source::Factory, Source::Trigger
struct Event_filter::Main : Source::Factory, Source::Trigger
{
Env &_env;
@ -39,18 +37,16 @@ struct Input_filter::Main : Input_connection::Avail_handler,
Heap _heap { _env.ram(), _env.rm() };
Registry<Registered<Input_connection> > _input_connections { };
typedef String<Session_label::capacity()> Label;
Event_root _event_root { _env, _heap, *this, _config };
/*
* Mechanism to construct a 'Timer' on demand
*
* By lazily constructing the timer, the input-filter does not depend
* By lazily constructing the timer, the event-filter does not depend
* on a timer service unless its configuration defines time-related
* filtering operations like key repeat.
*/
struct Timer_accessor : Input_filter::Timer_accessor
struct Timer_accessor : Event_filter::Timer_accessor
{
struct Lazy
{
@ -80,7 +76,7 @@ struct Input_filter::Main : Input_connection::Avail_handler,
/**
* Pool of configuration include snippets, obtained as ROM modules
*/
struct Include_accessor : Input_filter::Include_accessor
struct Include_accessor : Event_filter::Include_accessor
{
struct Rom
{
@ -225,20 +221,11 @@ struct Input_filter::Main : Input_connection::Avail_handler,
} nesting_level_guard { _create_source_max_nesting_level };
/* return input source with the matching name */
if (node.type() == Input_source::name()) {
Label const label = node.attribute_value("name", Label());
Input_connection *match = nullptr;
_input_connections.for_each([&] (Input_connection &connection) {
if (connection.label() == label)
match = &connection; });
if (match)
return *new (_heap) Input_source(owner, *match);
warning("input named '", label, "' does not exist");
throw Source::Invalid_config();
}
if (node.type() == Input_source::name())
return *new (_heap)
Input_source(owner,
node.attribute_value("name", Input_name()),
_event_root);
/* create regular filter */
if (node.type() == Remap_source::name())
@ -274,20 +261,6 @@ struct Input_filter::Main : Input_connection::Avail_handler,
*/
bool _config_update_pending = false;
/**
* Return true if all input sources are in their default state
*/
bool _input_connections_idle() const
{
bool idle = true;
_input_connections.for_each([&] (Input_connection const &connection) {
if (!connection.idle())
idle = false; });
return idle;
}
struct Output
{
Source::Owner _owner;
@ -310,60 +283,15 @@ struct Input_filter::Main : Input_connection::Avail_handler,
Constructible<Output> _output { };
/*
* Input session provided to our client
*/
Input::Session_component _input_session { _env, _env.ram() };
/* process events */
struct Final_sink : Source::Sink
{
Input::Session_component &_input_session;
Final_sink(Input::Session_component &input_session)
: _input_session(input_session) { }
void submit_event(Input::Event const &event) override {
_input_session.submit(event); }
} _final_sink { _input_session };
/*
* Input_connection::Avail_handler
*/
void handle_input_avail() override
{
for (;;) {
/* fetch events in input sources */
_input_connections.for_each([&] (Input_connection &connection) {
connection.flush(); });
bool pending = false;
_input_connections.for_each([&] (Input_connection &connection) {
pending |= connection.pending(); });
if (pending && _output.constructed())
_output->generate(_final_sink);
if (_config_update_pending && _input_connections_idle())
Signal_transmitter(_config_handler).submit();
/* stop if no events are pending */
if (!pending)
break;
}
}
Static_root<Input::Session> _input_root { _env.ep().manage(_input_session) };
/* destination for filter results */
Event::Connection _event_connection { _env };
void _handle_config()
{
_config.update();
bool const force = _config.xml().attribute_value("force", false);
bool const idle = _input_connections_idle();
bool const idle = _event_root.all_sessions_idle();
/* defer reconfiguration until all sources are idle */
if (!idle && !force) {
@ -381,48 +309,11 @@ struct Input_filter::Main : Input_connection::Avail_handler,
{
Xml_node const config = _config.xml();
/* close input sessions that are no longer needed */
_input_connections.for_each([&] (Registered<Input_connection> &conn) {
bool obsolete = true;
config.for_each_sub_node("input", [&] (Xml_node input_node) {
if (conn.label() == input_node.attribute_value("label", Label()))
obsolete = false; });
if (obsolete)
destroy(_heap, &conn);
});
/* open new input sessions */
config.for_each_sub_node("input", [&] (Xml_node input_node) {
try {
Label const label =
input_node.attribute_value("label", Label());
bool already_exists = false;
_input_connections.for_each([&] (Input_connection const &conn) {
if (conn.label() == label)
already_exists = true; });
if (already_exists)
return;
try {
new (_heap)
Registered<Input_connection>(_input_connections, _env,
label, *this, _heap);
}
catch (Genode::Service_denied) {
warning("parent denied input source '", label, "'"); }
}
catch (Xml_node::Nonexistent_attribute) {
warning("ignoring invalid input node '", input_node); }
});
_event_root.apply_config(config);
try {
if (_config.xml().has_sub_node("output"))
_output.construct(_config.xml().sub_node("output"), *this);
if (config.has_sub_node("output"))
_output.construct(config.sub_node("output"), *this);
}
catch (Source::Invalid_config) {
warning("invalid <output> configuration"); }
@ -441,12 +332,19 @@ struct Input_filter::Main : Input_connection::Avail_handler,
/**
* Source::Trigger interface
*
* Trigger emission of character-repeat events.
* Process pending events, which may originate from an event client or
* artificially emitted by a filter (character-repeat events).
*/
void trigger_generate() override
{
if (_output.constructed())
_output->generate(_final_sink);
if (!_output.constructed())
return;
_event_connection.with_batch([&] (Event::Session_client::Batch &batch) {
_output->generate(batch); });
if (_config_update_pending && _event_root.all_sessions_idle())
Signal_transmitter(_config_handler).submit();
}
/**
@ -454,7 +352,6 @@ struct Input_filter::Main : Input_connection::Avail_handler,
*/
Main(Genode::Env &env) : _env(env)
{
_input_session.event_queue().enabled(true);
_config.sigh(_config_handler);
/*
@ -465,9 +362,9 @@ struct Input_filter::Main : Input_connection::Avail_handler,
/*
* Announce service
*/
_env.parent().announce(_env.ep().manage(_input_root));
_env.parent().announce(_env.ep().manage(_event_root));
}
};
void Component::construct(Genode::Env &env) { static Input_filter::Main inst(env); }
void Component::construct(Genode::Env &env) { static Event_filter::Main inst(env); }

View File

@ -11,16 +11,16 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__MERGE_SOURCE_H_
#define _INPUT_FILTER__MERGE_SOURCE_H_
#ifndef _EVENT_FILTER__MERGE_SOURCE_H_
#define _EVENT_FILTER__MERGE_SOURCE_H_
/* local includes */
#include <source.h>
namespace Input_filter { class Merge_source; }
namespace Event_filter { class Merge_source; }
class Input_filter::Merge_source : public Source
class Event_filter::Merge_source : public Source
{
private:
@ -46,4 +46,4 @@ class Input_filter::Merge_source : public Source
}
};
#endif /* _INPUT_FILTER__REMAP_SOURCE_H_ */
#endif /* _EVENT_FILTER__REMAP_SOURCE_H_ */

View File

@ -11,8 +11,8 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__REMAP_SOURCE_H_
#define _INPUT_FILTER__REMAP_SOURCE_H_
#ifndef _EVENT_FILTER__REMAP_SOURCE_H_
#define _EVENT_FILTER__REMAP_SOURCE_H_
/* Genode includes */
#include <input/keycodes.h>
@ -22,10 +22,10 @@
#include <source.h>
#include <key_code_by_name.h>
namespace Input_filter { class Remap_source; }
namespace Event_filter { class Remap_source; }
class Input_filter::Remap_source : public Source, Source::Filter
class Event_filter::Remap_source : public Source, Source::Filter
{
private:
@ -51,7 +51,7 @@ class Input_filter::Remap_source : public Source, Source::Filter
/* forward events that are unrelated to the remapper */
if (!event.press() && !event.release()) {
destination.submit_event(event);
destination.submit(event);
return;
}
@ -64,10 +64,10 @@ class Input_filter::Remap_source : public Source, Source::Filter
auto remap = [&] (Input::Keycode key) { return _keys[key].code; };
event.handle_press([&] (Input::Keycode key, Codepoint codepoint) {
destination.submit_event(Input::Press_char{remap(key), codepoint}); });
destination.submit(Input::Press_char{remap(key), codepoint}); });
event.handle_release([&] (Input::Keycode key) {
destination.submit_event(Input::Release{remap(key)}); });
destination.submit(Input::Release{remap(key)}); });
}
void _apply_config(Xml_node const config, unsigned const max_recursion = 4)
@ -143,4 +143,4 @@ class Input_filter::Remap_source : public Source, Source::Filter
}
};
#endif /* _INPUT_FILTER__REMAP_SOURCE_H_ */
#endif /* _EVENT_FILTER__REMAP_SOURCE_H_ */

View File

@ -11,20 +11,21 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__SOURCE_H_
#define _INPUT_FILTER__SOURCE_H_
#ifndef _EVENT_FILTER__SOURCE_H_
#define _EVENT_FILTER__SOURCE_H_
/* Genode includes */
#include <base/registry.h>
#include <util/xml_node.h>
#include <input/event.h>
/* local includes */
#include <types.h>
namespace Input_filter { struct Source; }
namespace Event_filter { struct Source; }
class Input_filter::Source
class Event_filter::Source
{
private:
@ -67,10 +68,7 @@ class Input_filter::Source
struct Owner;
struct Sink : Interface
{
virtual void submit_event(Input::Event const &) = 0;
};
using Sink = Event::Session_client::Batch;
virtual void generate(Sink &) = 0;
@ -94,7 +92,7 @@ class Input_filter::Source
Sink &_destination;
Filter &_filter;
void submit_event(Input::Event const &event) override
void submit(Input::Event const &event) override
{
_filter.filter_event(_destination, event);
}
@ -131,4 +129,4 @@ class Input_filter::Source
};
};
#endif /* _INPUT_FILTER__SOURCE_H_ */
#endif /* _EVENT_FILTER__SOURCE_H_ */

View File

@ -1,4 +1,4 @@
TARGET = input_filter
TARGET = event_filter
SRC_CC = main.cc
LIBS = base
INC_DIR += $(PRG_DIR)

View File

@ -11,14 +11,14 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__TIMER_ACCESSOR_H_
#define _INPUT_FILTER__TIMER_ACCESSOR_H_
#ifndef _EVENT_FILTER__TIMER_ACCESSOR_H_
#define _EVENT_FILTER__TIMER_ACCESSOR_H_
/* Genode includes */
#include <timer_session/connection.h>
namespace Input_filter { struct Timer_accessor; }
namespace Event_filter { struct Timer_accessor; }
struct Input_filter::Timer_accessor : Interface { virtual Timer::Connection &timer() = 0; };
struct Event_filter::Timer_accessor : Interface { virtual Timer::Connection &timer() = 0; };
#endif /* _INPUT_FILTER__TIMER_ACCESSOR_H_ */
#endif /* _EVENT_FILTER__TIMER_ACCESSOR_H_ */

View File

@ -1,5 +1,5 @@
/*
* \brief Types used by the input filter
* \brief Types used by the event filter
* \author Norman Feske
* \date 2017-02-01
*/
@ -11,13 +11,13 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INPUT_FILTER__TYPES_H_
#define _INPUT_FILTER__TYPES_H_
#ifndef _EVENT_FILTER__TYPES_H_
#define _EVENT_FILTER__TYPES_H_
/* Genode includes */
#include <util/string.h>
#include <base/session_label.h>
namespace Input_filter { using namespace Genode; }
namespace Event_filter { using namespace Genode; }
#endif /* _INPUT_FILTER__TYPES_H_ */
#endif /* _EVENT_FILTER__TYPES_H_ */

View File

@ -1,97 +0,0 @@
/*
* \brief Connection for incoming input events
* \author Norman Feske
* \date 2017-02-01
*/
/*
* Copyright (C) 2017 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 _INPUT_FILTER__CONNECTION_H_
#define _INPUT_FILTER__CONNECTION_H_
/* Genode includes */
#include <input_session/connection.h>
#include <base/session_label.h>
/* local includes */
#include <types.h>
namespace Input_filter { struct Input_connection; }
class Input_filter::Input_connection
{
public:
struct Avail_handler : Interface { virtual void handle_input_avail() = 0; };
private:
Session_label const _label;
Input::Connection _connection;
Attached_dataspace _events_ds;
Avail_handler &_avail_handler;
unsigned _key_cnt = 0;
Signal_handler<Input_connection> _input_handler;
void _handle_input() { _avail_handler.handle_input_avail(); }
size_t _num_ev = 0;
size_t const _max_events = _events_ds.size() / sizeof(Input::Event);
public:
static char const *name() { return "input"; }
Input_connection(Env &env, Session_label const &label,
Avail_handler &avail_handler, Allocator &)
:
_label(label),
_connection(env, label.string()),
_events_ds(env.rm(), _connection.dataspace()),
_avail_handler(avail_handler),
_input_handler(env.ep(), *this, &Input_connection::_handle_input)
{
_connection.sigh(_input_handler);
}
virtual ~Input_connection() { }
Session_label label() const { return _label; }
template <typename FUNC>
void for_each_event(FUNC const &func) const
{
Input::Event const *event_ptr = _events_ds.local_addr<Input::Event const>();
for (size_t i = 0; i < _num_ev; i++)
func(*event_ptr++);
}
void flush()
{
_num_ev = min(_max_events, (size_t)_connection.flush());
auto update_key_cnt = [&] (Input::Event const &event)
{
if (event.press()) _key_cnt++;
if (event.release()) _key_cnt--;
};
for_each_event(update_key_cnt);
}
bool idle() const { return _key_cnt == 0; }
bool pending() const { return _num_ev > 0; }
};
#endif /* _INPUT_FILTER__CONNECTION_H_ */

View File

@ -1,46 +0,0 @@
/*
* \brief Input-event source that obtains events from input connection
* \author Norman Feske
* \date 2017-02-01
*/
/*
* Copyright (C) 2017 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 _INPUT_FILTER__INPUT_SOURCE_H_
#define _INPUT_FILTER__INPUT_SOURCE_H_
/* local includes */
#include <source.h>
#include <connection.h>
namespace Input_filter { class Input_source; }
class Input_filter::Input_source : public Source
{
private:
Input_connection &_connection;
public:
static char const *name() { return "input"; }
Input_source(Owner &owner, Input_connection &connection)
:
Source(owner), _connection(connection)
{ }
void generate(Sink &sink) override
{
_connection.for_each_event([&] (Input::Event const &event) {
sink.submit_event(event); });
}
};
#endif /* _INPUT_FILTER__INPUT_SOURCE_H_ */

View File

@ -1,5 +1,5 @@
/*
* \brief Test for input filter
* \brief Test for event filter
* \author Norman Feske
* \date 2017-02-01
*/
@ -15,33 +15,113 @@
#include <base/component.h>
#include <base/session_label.h>
#include <base/attached_rom_dataspace.h>
#include <input_session/connection.h>
#include <input/component.h>
#include <base/attached_ram_dataspace.h>
#include <event_session/connection.h>
#include <base/session_object.h>
#include <timer_session/connection.h>
#include <os/static_root.h>
#include <root/component.h>
#include <input/event.h>
#include <input/keycodes.h>
#include <os/reporter.h>
#include <os/ring_buffer.h>
#include <base/sleep.h>
namespace Test {
class Input_from_filter;
class Input_to_filter;
class Input_root;
class Event_session;
class Event_root;
class Main;
using namespace Genode;
using Input::Event;
}
struct Test::Event_session : Rpc_object<Event::Session, Event_session>
{
Attached_ram_dataspace _ds;
Signal_context_capability _handle_input_sigh;
Ring_buffer<Input::Event, 100> _events { };
Event_session(Env &env, Signal_context_capability handle_input_sigh)
:
_ds(env.ram(), env.rm(), 4096), _handle_input_sigh(handle_input_sigh)
{ }
template <typename FN>
void for_each_pending_event(FN const &fn)
{
while (!_events.empty())
fn(_events.get());
}
/*****************************
** Event session interface **
*****************************/
Dataspace_capability dataspace() { return _ds.cap(); }
void submit_batch(unsigned count)
{
size_t const max_events = _ds.size() / sizeof(Input::Event);
if (count > max_events)
warning("number of events exceeds dataspace capacity");
count = min(count, max_events);
Input::Event const * const events = _ds.local_addr<Input::Event>();
for (unsigned i = 0; i < count; i++) {
if (_events.avail_capacity() < 1)
error("ring-buffer overflow");
_events.add(events[i]);
}
/* execute '_handle_input' in the context of the main entrypoint */
Signal_transmitter(_handle_input_sigh).submit();
}
};
struct Test::Event_root : Root_component<Event_session>
{
Event_session &_session;
bool _filter_connected = false;
Event_root(Entrypoint &ep, Allocator &md_alloc, Event_session &session)
:
Root_component(ep, md_alloc), _session(session)
{ }
Event_session *_create_session(const char *, Affinity const &) override
{
_filter_connected = true;
return &_session;
}
/*
* Prevent the default 'Root_component' implementation from attempting
* to free the session objects.
*/
void _destroy_session(Event_session *) override { }
};
class Test::Input_from_filter
{
public:
struct Event_handler : Interface
{
virtual void handle_event_from_filter(Event const &) = 0;
virtual void handle_event_from_filter(Input::Event const &) = 0;
};
private:
@ -50,33 +130,46 @@ class Test::Input_from_filter
Event_handler &_event_handler;
Input::Connection _connection;
bool _input_expected = false;
bool _handle_input_in_progress = false;
Signal_handler<Input_from_filter> _input_handler {
_env.ep(), *this, &Input_from_filter::_handle_input };
Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
/*
* Provide the event service via an independent entrypoint to avoid a
* possible deadlock between the event_filter and the test when
* both try to invoke 'Event::Session::submit' from each other.
*/
enum { STACK_SIZE = 4*1024*sizeof(long) };
Entrypoint _ep { _env, STACK_SIZE, "server_ep", Affinity::Location() };
Event_session _session { _env, _input_handler };
Event_root _root { _ep, _sliced_heap, _session };
void _handle_input()
{
_handle_input_in_progress = true;
if (_input_expected)
_connection.for_each_event([&] (Event const &event) {
_session.for_each_pending_event([&] (Input::Event const &event) {
_event_handler.handle_event_from_filter(event); });
_handle_input_in_progress = false;
}
Signal_handler<Input_from_filter> _input_handler {
_env.ep(), *this, &Input_from_filter::_handle_input };
public:
Input_from_filter(Env &env, Event_handler &event_handler)
:
_env(env), _event_handler(event_handler), _connection(env)
_env(env), _event_handler(event_handler)
{
_connection.sigh(_input_handler);
_env.parent().announce(_ep.manage(_root));
}
void input_expected(bool expected)
@ -93,68 +186,14 @@ class Test::Input_from_filter
};
class Test::Input_root : public Root_component<Input::Session_component>
{
private:
Input::Session_component &_usb_input;
Input::Session_component &_ps2_input;
public:
Input_root(Entrypoint &ep, Allocator &md_alloc,
Input::Session_component &usb_input,
Input::Session_component &ps2_input)
:
Root_component(ep, md_alloc),
_usb_input(usb_input), _ps2_input(ps2_input)
{ }
Input::Session_component *_create_session(const char *args,
Affinity const &) override
{
Session_label const label = label_from_args(args);
if (label.last_element() == "usb") return &_usb_input;
if (label.last_element() == "ps2") return &_ps2_input;
error("no matching policy for session label ", label);
throw Service_denied();
}
/*
* Prevent the default 'Root_component' implementation from attempting
* to free the session objects.
*/
void _destroy_session(Input::Session_component *) override { }
};
class Test::Input_to_filter
{
private:
Env &_env;
Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
/*
* Provide the input service via an independent entrypoint to avoid a
* possible deadlock between the input_filter and the test when
* both try to invoke 'Input::Session::flush' from each other.
*/
enum { STACK_SIZE = 4*1024*sizeof(long) };
Entrypoint _ep { _env, STACK_SIZE, "input_server_ep",
Affinity::Location() };
/*
* Input supplied to the input_filter
*/
Input::Session_component _usb { _env, _env.ram() };
Input::Session_component _ps2 { _env, _env.ram() };
Input_root _root { _ep, _sliced_heap, _usb, _ps2};
Constructible<Event::Connection> _ps2 { };
Constructible<Event::Connection> _usb { };
typedef String<20> Key_name;
@ -172,12 +211,17 @@ class Test::Input_to_filter
public:
Input_to_filter(Env &env) : _env(env)
{
_env.parent().announce(_ep.manage(_root));
Input_to_filter(Env &env) : _env(env) { }
_usb.event_queue().enabled(true);
_ps2.event_queue().enabled(true);
void apply_driver(Xml_node driver)
{
using Name = String<100>;
Name const name = driver.attribute_value("name", Name());
bool const connected = driver.attribute_value("connected", true);
if (name == "ps2") _ps2.conditional(connected, _env, "ps2");
if (name == "usb") _usb.conditional(connected, _env, "usb");
}
void submit_events(Xml_node step)
@ -187,32 +231,35 @@ class Test::Input_to_filter
throw Exception();
}
Input::Session_component &dst = step.type() == "usb" ? _usb : _ps2;
Event::Connection &dst = step.type() == "usb" ? *_usb : *_ps2;
step.for_each_sub_node([&] (Xml_node node) {
dst.with_batch([&] (Event::Session_client::Batch &batch) {
bool const press = node.has_type("press"),
release = node.has_type("release");
step.for_each_sub_node([&] (Xml_node node) {
if (press || release) {
bool const press = node.has_type("press"),
release = node.has_type("release");
Key_name const key_name = node.attribute_value("code", Key_name());
if (press || release) {
if (press) dst.submit(Input::Press {_code(key_name)});
if (release) dst.submit(Input::Release{_code(key_name)});
}
Key_name const key_name = node.attribute_value("code", Key_name());
bool const motion = node.has_type("motion");
bool const rel = node.has_attribute("rx") || node.has_attribute("ry");
bool const abs = node.has_attribute("ax") || node.has_attribute("ay");
if (press) batch.submit(Input::Press {_code(key_name)});
if (release) batch.submit(Input::Release{_code(key_name)});
}
if (motion && abs)
dst.submit(Input::Absolute_motion{(int)node.attribute_value("ax", 0L),
(int)node.attribute_value("ay", 0L)});
bool const motion = node.has_type("motion");
bool const rel = node.has_attribute("rx") || node.has_attribute("ry");
bool const abs = node.has_attribute("ax") || node.has_attribute("ay");
if (motion && rel)
dst.submit(Input::Relative_motion{(int)node.attribute_value("rx", 0L),
(int)node.attribute_value("ry", 0L)});
if (motion && abs)
batch.submit(Input::Absolute_motion{(int)node.attribute_value("ax", 0L),
(int)node.attribute_value("ay", 0L)});
if (motion && rel)
batch.submit(Input::Relative_motion{(int)node.attribute_value("rx", 0L),
(int)node.attribute_value("ry", 0L)});
});
});
}
};
@ -228,7 +275,7 @@ struct Test::Main : Input_from_filter::Event_handler
Input_to_filter _input_to_filter { _env };
Reporter _input_filter_config_reporter { _env, "config", "input_filter.config" };
Reporter _event_filter_config_reporter { _env, "config", "event_filter.config" };
Reporter _chargen_include_reporter { _env, "chargen", "chargen_include" };
Reporter _remap_include_reporter { _env, "remap", "remap_include" };
Reporter _capslock_reporter { _env, "capslock", "capslock" };
@ -292,14 +339,20 @@ struct Test::Main : Input_from_filter::Event_handler
step.type() == "expect_motion" ||
step.type() == "expect_wheel");
if (step.type() == "driver") {
_input_to_filter.apply_driver(step);
_advance_step();
continue;
}
if (step.type() == "filter_config") {
_publish_report(_input_filter_config_reporter, step);
_publish_report(_event_filter_config_reporter, step);
_advance_step();
continue;
}
if (step.type() == "deep_filter_config") {
_deep_filter_config(_input_filter_config_reporter, step);
_deep_filter_config(_event_filter_config_reporter, step);
_advance_step();
continue;
}
@ -364,7 +417,7 @@ struct Test::Main : Input_from_filter::Event_handler
/**
* Input_to_filter::Event_handler interface
*/
void handle_event_from_filter(Event const &ev) override
void handle_event_from_filter(Input::Event const &ev) override
{
typedef Genode::String<20> Value;
@ -446,7 +499,7 @@ struct Test::Main : Input_from_filter::Event_handler
Main(Env &env) : _env(env)
{
_timer.sigh(_timer_handler);
_input_filter_config_reporter.enabled(true);
_event_filter_config_reporter.enabled(true);
_chargen_include_reporter.enabled(true);
_remap_include_reporter.enabled(true);
_capslock_reporter.enabled(true);

View File

@ -1,3 +1,3 @@
TARGET = test-input_filter
TARGET = test-event_filter
SRC_CC = main.cc
LIBS += base

View File

@ -57,21 +57,22 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="default" layer="2" content="client" label="no" hover="always"/>
<default-policy domain="default"/>
</config>
<route>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>

View File

@ -73,18 +73,20 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="gdb_monitor"/> </service>
<service name="Event"> <child name="gdb_monitor"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="gdb_monitor" caps="200">
<resource name="RAM" quantum="10M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config>
<target name="nitpicker">
<config request_framebuffer="no">
<capture/>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<domain name="pointer" layer="1" xray="no" origin="pointer"
content="client" label="no"/>
<domain name="default" layer="3" content="client"

View File

@ -102,7 +102,7 @@ catch { exec dd if=/dev/urandom of=bin/test.bin bs=4096 count=8160 }
# Step 1: prepare and start the actual VM
#
set build_components {
server/input_filter
server/event_filter
server/report_rom server/fs_rom server/vfs
server/tcp_terminal drivers/nic
lib/vfs/lwip lib/vfs/pipe lib/vfs/import
@ -118,7 +118,7 @@ set boot_modules {
vfs fs_rom
posix.lib.so bash.tar coreutils.tar
tcp_terminal vfs_lwip.lib.so vfs_pipe.lib.so vfs_import.lib.so
ipxe_nic_drv report_rom input_filter
ipxe_nic_drv report_rom event_filter
test.bin template.bat
}
@ -246,17 +246,12 @@ set config_of_app {
</config>
</start>
<start name="input_filter" priority="-1">
<start name="event_filter" priority="-1">
<resource name="RAM" quantum="1M" />
<provides>
<service name="Input" />
<service name="Event" />
</provides>
<config>}
append_if [expr $use_ps2] config_of_app {
<input label="ps2"/> }
append_if [expr $use_usb] config_of_app {
<input label="usb_hid"/>}
append config_of_app {
<config>
<output>
<merge>}
append_if [expr $use_ps2] config_of_app {
@ -265,28 +260,30 @@ append_if [expr $use_usb] config_of_app {
<input name="usb_hid"/>}
append config_of_app {
</merge>
</output>
</config>
<route> }
</output>}
append_if [expr $use_ps2] config_of_app {
<service name="Input" label="ps2"> <child name="ps2_drv" /> </service> }
<policy label="ps2" input="ps2"/>}
append_if [expr $use_usb] config_of_app {
<service name="Input" label="usb_hid"> <child name="usb_drv" /> </service> }
<policy label="usb_hid" input="usb_hid"/>}
append config_of_app {
</config>
<route>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent /> <any-child /> </any-service>
</route>
</start>
<start name="nitpicker" priority="-1">
<resource name="RAM" quantum="12M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<route>
<service name="Input"> <child name="input_filter" /> </service>
<service name="Report"> <child name="report_rom" /> </service>
<any-service> <parent/> <any-child /> </any-service>
</route>
<config request_framebuffer="no">
<capture/>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<report focus="yes" hover="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
@ -350,7 +347,6 @@ append config_of_app {
<child name="ram_fs_to"/>
</service>
<service name="File_system"> <child name="rump_fs"/> </service>
<service name="Input"> <child name="input_filter"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>

View File

@ -25,7 +25,7 @@ if {[info exists flavor_extension]} {
}
set build_components {
server/input_filter
server/event_filter
drivers/nic
drivers/audio
server/report_rom
@ -33,7 +33,7 @@ set build_components {
}
set boot_modules {
input_filter
event_filter
ipxe_nic_drv
audio_drv
report_rom
@ -45,16 +45,12 @@ if {$use_vbox5_nova} { set virtualbox5_binary "virtualbox5-nova" }
set config_of_app {
<start name="input_filter">
<start name="event_filter">
<resource name="RAM" quantum="1M" />
<provides>
<service name="Input" />
<service name="Event" />
</provides>
<config>}
append_if [expr $use_ps2] config_of_app {
<input label="ps2"/> }
append_if [expr $use_usb] config_of_app {
<input label="usb_hid"/>}
append config_of_app {
<output>
<merge>}
@ -64,14 +60,15 @@ append_if [expr $use_usb] config_of_app {
<input name="usb_hid"/>}
append config_of_app {
</merge>
</output>
</config>
<route> }
</output>}
append_if [expr $use_ps2] config_of_app {
<service name="Input" label="ps2"> <child name="ps2_drv" /> </service> }
<policy label="ps2" input="ps2"/> }
append_if [expr $use_usb] config_of_app {
<service name="Input" label="usb_hid"> <child name="usb_drv" /> </service> }
<policy label="usb_hid" input="usb_hid"/>}
append config_of_app {
</config>
<route>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent /> <any-child /> </any-service>
</route>
</start>
@ -125,9 +122,10 @@ append config_of_app {
<start name="nitpicker" priority="-1" caps="150">
<resource name="RAM" quantum="12M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<route>
<service name="Input"> <child name="input_filter" /> </service>
<service name="Report"> <child name="report_rom" /> </service>
<service name="ROM" label="config">
<child name="dynamic-config" label="nitpicker.config"/> </service>
@ -181,8 +179,8 @@ append config_of_app {
</rom>
<rom name="nitpicker.config">
<inline description="standard_mode">
<config request_framebuffer="no">
<capture/>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<report focus="yes" hover="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
@ -198,8 +196,8 @@ append config_of_app {
append_if [expr !$use_rumpfs] config_of_app {
<inline description="shutdown">
<config request_framebuffer="no">
<capture/>
<config request_framebuffer="no" request_input="no">
<capture/> <event/>
<report focus="yes" hover="yes" />
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />

View File

@ -48,9 +48,9 @@ install_config {
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
<service name="Timer"> <child name="timer"/> </service>
<service name="Capture"> <child name="nitpicker"/> </service>
<service name="Event"> <child name="nitpicker"/> </service>
<any-service> <parent/> </any-service>
</route>
<provides> <service name="Input"/> </provides>
</start>
<start name="report_rom">
@ -65,9 +65,11 @@ install_config {
<start name="nitpicker">
<resource name="RAM" quantum="4M"/>
<provides> <service name="Gui"/> <service name="Capture"/> </provides>
<config focus="rom" request_framebuffer="no">
<capture/>
<provides>
<service name="Gui"/> <service name="Capture"/> <service name="Event"/>
</provides>
<config focus="rom" request_framebuffer="no" request_input="no">
<capture/> <event/>
<report focus="yes" /> <!-- interpreted by clipboard -->
<domain name="pointer" layer="1" content="client" label="no" origin="pointer" />
@ -78,7 +80,6 @@ install_config {
</config>
<route>
<service name="Report"> <child name="report_rom"/> </service>
<service name="Input"> <child name="drivers"/> </service>
<any-service> <parent/> <any-child/> </any-service>
</route>
</start>

View File

@ -35,6 +35,7 @@ append build_components {
server/fs_rom
drivers/ahci
drivers/framebuffer
app/input_event_client
}
lappend_if [expr $use_serial] build_components server/log_terminal
@ -212,8 +213,19 @@ append_platform_drv_config
append_if [expr $use_ps2] config {
<start name="ps2_drv" priority="-1">
<resource name="RAM" quantum="1M"/>
<provides><service name="Input"/></provides>
<provides> <service name="Input"/> </provides>
<config/>
</start>
<start name="ps2" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="ps2"/> </service>
<service name="Input"> <child name="ps2_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>}
append_if [expr $use_cpu_load] config {
@ -347,12 +359,23 @@ append_if [expr $use_usb] config {
<any-service><parent/><any-child/></any-service>
</route>
</start>
<start name="usb" caps="90">
<resource name="RAM" quantum="1M"/>
<binary name="input_event_client"/>
<config/>
<route>
<service name="Event"> <child name="event_filter" label="usb_hid"/> </service>
<service name="Input"> <child name="usb_drv"/> </service>
<any-service> <parent/> </any-service>
</route>
</start>
}
append_if [have_spec framebuffer] config {
<start name="fb_drv" priority="-1" caps="150">
<binary name="vesa_fb_drv"/>
<resource name="RAM" quantum="16M"/>
<resource name="RAM" quantum="32M"/>
<config/>
</start>}
@ -385,6 +408,7 @@ append boot_modules {
libc.lib.so vfs.lib.so libm.lib.so
libiconv.lib.so stdcxx.lib.so
qemu-usb.lib.so
input_event_client
}
lappend_if [expr $use_rumpfs] boot_modules rump.lib.so

View File

@ -14,7 +14,7 @@ fs_query
gdb_monitor
ieee754
init_smp
input_filter
event_filter
libc_vfs_fs_ext2
log_core
lwip