mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +00:00
transition Input infrastructure to new base API
* Supply Env to Input::Session_component * Attach input event dataspace at Input::Client * Process input events by lambda rather than pointer * Supply Env and a label to Input::Connection * Wm serves valid input_session to decorator * Per-source signal handling at input_merger * Base API update for dummy_input_drv, test_input * Input API update for launcher, menu_view, terminal, mupdf, sdl, seoul, virtualbox Ref #1987
This commit is contained in:
parent
80558374f5
commit
71f0757a30
@ -62,10 +62,6 @@ struct Launcher::Main
|
||||
*/
|
||||
Nitpicker::Connection _nitpicker;
|
||||
|
||||
Genode::Attached_dataspace _input_ds { _nitpicker.input()->dataspace() };
|
||||
|
||||
Input::Event const *_ev_buf() { return _input_ds.local_addr<Input::Event>(); }
|
||||
|
||||
Genode::Signal_rpc_member<Main> _input_dispatcher =
|
||||
{ _ep, *this, &Main::_handle_input };
|
||||
|
||||
@ -128,12 +124,7 @@ void Launcher::Main::_handle_config(unsigned)
|
||||
|
||||
void Launcher::Main::_handle_input(unsigned)
|
||||
{
|
||||
unsigned const num_ev = _nitpicker.input()->flush();
|
||||
|
||||
for (unsigned i = 0; i < num_ev; i++) {
|
||||
|
||||
Input::Event const &e = _ev_buf()[i];
|
||||
|
||||
_nitpicker.input()->for_each_event([&] (Input::Event const &e) {
|
||||
if (e.type() == Input::Event::PRESS) _key_cnt++;
|
||||
if (e.type() == Input::Event::RELEASE) _key_cnt--;
|
||||
|
||||
@ -148,7 +139,7 @@ void Launcher::Main::_handle_input(unsigned)
|
||||
if (e.keycode() == Input::KEY_TAB)
|
||||
_panel_dialog.focus_next();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -185,13 +185,7 @@ void Menu_view::Main::handle_config(unsigned)
|
||||
|
||||
void Menu_view::Main::handle_input(unsigned)
|
||||
{
|
||||
Input::Event const *ev_buf = input_ds.local_addr<Input::Event>();
|
||||
|
||||
unsigned const num_events = nitpicker.input()->flush();
|
||||
for (unsigned i = 0; i < num_events; i++) {
|
||||
|
||||
Input::Event ev = ev_buf[i];
|
||||
|
||||
nitpicker.input()->for_each_event([&] (Input::Event const &ev) {
|
||||
if (ev.absolute_motion()) {
|
||||
|
||||
Point const at = Point(ev.ax(), ev.ay()) - position;
|
||||
@ -221,7 +215,7 @@ void Menu_view::Main::handle_input(unsigned)
|
||||
Genode::Reporter::Xml_generator xml(hover_reporter, [&] () { });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -511,11 +511,6 @@ int main(int, char **)
|
||||
static Timer::Connection timer;
|
||||
static Cap_connection cap;
|
||||
|
||||
Dataspace_capability ev_ds_cap = input.dataspace();
|
||||
|
||||
Input::Event *ev_buf = static_cast<Input::Event *>
|
||||
(env()->rm_session()->attach(ev_ds_cap));
|
||||
|
||||
/* initialize entry point that serves the root interface */
|
||||
enum { STACK_SIZE = sizeof(addr_t)*1024 };
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "terminal_ep");
|
||||
@ -628,13 +623,10 @@ int main(int, char **)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned num_events = input.flush();
|
||||
|
||||
for (Input::Event *event = ev_buf; num_events--; event++) {
|
||||
|
||||
bool press = (event->type() == Input::Event::PRESS ? true : false);
|
||||
bool release = (event->type() == Input::Event::RELEASE ? true : false);
|
||||
int keycode = event->code();
|
||||
input.for_each_event([&] (Input::Event const &event) {
|
||||
bool press = (event.type() == Input::Event::PRESS ? true : false);
|
||||
bool release = (event.type() == Input::Event::RELEASE ? true : false);
|
||||
int keycode = event.code();
|
||||
|
||||
if (press || release)
|
||||
scancode_tracker.submit(keycode, press);
|
||||
@ -644,7 +636,7 @@ int main(int, char **)
|
||||
|
||||
/* setup first key repeat */
|
||||
repeat_cnt = repeat_delay;
|
||||
}
|
||||
});
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -171,10 +171,6 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
|
||||
|
||||
Command_buffer &_command_buffer = *_command_ds.local_addr<Command_buffer>();
|
||||
|
||||
Input::Session_client _nitpicker_input { _nitpicker_session.input_session() };
|
||||
|
||||
Attached_dataspace _nitpicker_input_ds { _nitpicker_input.dataspace() };
|
||||
|
||||
Reporter &_pointer_reporter;
|
||||
|
||||
Last_motion &_last_motion;
|
||||
@ -190,6 +186,11 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
|
||||
|
||||
Allocator &_md_alloc;
|
||||
|
||||
/* Nitpicker::Connection requires a valid input session */
|
||||
Input::Session_component _dummy_input_component;
|
||||
Input::Session_capability _dummy_input_component_cap =
|
||||
_ep.manage(_dummy_input_component);
|
||||
|
||||
Signal_rpc_member<Decorator_nitpicker_session>
|
||||
_input_dispatcher { _ep, *this, &Decorator_nitpicker_session::_input_handler };
|
||||
|
||||
@ -212,23 +213,13 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
|
||||
_content_callback(content_callback),
|
||||
_ep(ep), _md_alloc(md_alloc)
|
||||
{
|
||||
_nitpicker_input.sigh(_input_dispatcher);
|
||||
_nitpicker_session.input()->sigh(_input_dispatcher);
|
||||
}
|
||||
|
||||
void _input_handler(unsigned)
|
||||
{
|
||||
Input::Event const * const events =
|
||||
_nitpicker_input_ds.local_addr<Input::Event>();
|
||||
|
||||
while (_nitpicker_input.pending()) {
|
||||
|
||||
size_t const num_events = _nitpicker_input.flush();
|
||||
|
||||
/* we trust nitpicker to return a valid number of events */
|
||||
|
||||
for (size_t i = 0; i < num_events; i++) {
|
||||
|
||||
Input::Event const &ev = events[i];
|
||||
while (_nitpicker_session.input()->pending())
|
||||
_nitpicker_session.input()->for_each_event([&] (Input::Event const &ev) {
|
||||
|
||||
if (ev.type() == Input::Event::MOTION) {
|
||||
|
||||
@ -259,8 +250,7 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
|
||||
}
|
||||
|
||||
_window_layouter_input.submit(ev);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _execute_command(Command const &cmd)
|
||||
@ -381,7 +371,7 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object<Nitpicker::Session>,
|
||||
* Deny input to the decorator. User input referring to the
|
||||
* window decorations is routed to the window manager.
|
||||
*/
|
||||
return Input::Session_capability();
|
||||
return _dummy_input_component_cap;
|
||||
}
|
||||
|
||||
View_handle create_view(View_handle parent) override
|
||||
|
@ -308,7 +308,6 @@ int main(int, char **)
|
||||
static Input::Connection input;
|
||||
static Timer::Connection timer;
|
||||
|
||||
Input::Event *ev_buf = Genode::env()->rm_session()->attach(input.dataspace());
|
||||
int key_cnt = 0;
|
||||
|
||||
/*
|
||||
@ -317,10 +316,7 @@ int main(int, char **)
|
||||
for (;;) {
|
||||
while (!input.pending()) timer.msleep(20);
|
||||
|
||||
for (int i = 0, num_ev = input.flush(); i < num_ev; i++) {
|
||||
|
||||
Input::Event const &ev = ev_buf[i];
|
||||
|
||||
input.for_each_event([&] (Input::Event const &ev) {
|
||||
if (ev.type() == Input::Event::PRESS) key_cnt++;
|
||||
if (ev.type() == Input::Event::RELEASE) key_cnt--;
|
||||
|
||||
@ -330,7 +326,7 @@ int main(int, char **)
|
||||
if (ascii)
|
||||
pdf_view.handle_key(ascii);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
|
@ -41,7 +41,6 @@ extern "C" {
|
||||
#include "SDL_genode_fb_events.h"
|
||||
|
||||
static Input::Connection *input = 0;
|
||||
static Input::Event *ev_buf = 0;
|
||||
static const int KEYNUM_MAX = 512;
|
||||
static SDLKey keymap[KEYNUM_MAX];
|
||||
static int buttonmap[KEYNUM_MAX];
|
||||
@ -61,10 +60,7 @@ extern "C" {
|
||||
{
|
||||
if (!input->pending())
|
||||
return;
|
||||
int num_ev = input->flush();
|
||||
for (int src_ev_cnt = 0; src_ev_cnt < num_ev; src_ev_cnt++)
|
||||
{
|
||||
Input::Event curr = ev_buf[src_ev_cnt];
|
||||
input->for_each_event([&] (Input::Event const &curr) {
|
||||
SDL_keysym ksym;
|
||||
switch(curr.type())
|
||||
{
|
||||
@ -102,7 +98,7 @@ extern "C" {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -116,9 +112,6 @@ extern "C" {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Attach event buffer to address space */
|
||||
ev_buf = Genode::env()->rm_session()->attach(input->dataspace());
|
||||
|
||||
/* Prepare button mappings */
|
||||
for (int i=0; i<KEYNUM_MAX; i++)
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2006-2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -29,13 +29,34 @@ class Input::Session_component : public Genode::Rpc_object<Input::Session>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Attached_ram_dataspace _ds { Genode::env()->ram_session(),
|
||||
Event_queue::QUEUE_SIZE*sizeof(Input::Event) };
|
||||
Genode::Attached_ram_dataspace _ds;
|
||||
|
||||
Event_queue _event_queue;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param env Env containing local region map
|
||||
* \param ram Ram session at which to allocate session buffer
|
||||
*/
|
||||
Session_component(Genode::Env &env, Genode::Ram_session &ram)
|
||||
: _ds(ram, env.rm(),
|
||||
Event_queue::QUEUE_SIZE*sizeof(Input::Event)) { }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \noapi
|
||||
* \deprecated
|
||||
*/
|
||||
Session_component()
|
||||
: _ds(*Genode::env()->ram_session(),
|
||||
*Genode::env()->rm_session(),
|
||||
Event_queue::QUEUE_SIZE*sizeof(Input::Event))
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Return reference to event queue of the session
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2006-2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -15,27 +15,64 @@
|
||||
#define _INCLUDE__INPUT_SESSION__CLIENT_H_
|
||||
|
||||
#include <input_session/capability.h>
|
||||
#include <input/event.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <base/rpc_client.h>
|
||||
|
||||
namespace Input { struct Session_client; }
|
||||
|
||||
|
||||
struct Input::Session_client : Genode::Rpc_client<Session>
|
||||
class Input::Session_client : public Genode::Rpc_client<Session>
|
||||
{
|
||||
explicit Session_client(Session_capability session)
|
||||
: Genode::Rpc_client<Session>(session) { }
|
||||
private:
|
||||
|
||||
Genode::Dataspace_capability dataspace() override {
|
||||
return call<Rpc_dataspace>(); }
|
||||
Genode::Attached_dataspace _event_ds;
|
||||
|
||||
bool pending() const override {
|
||||
return call<Rpc_pending>(); }
|
||||
Genode::size_t const _max_events =
|
||||
_event_ds.size() / sizeof(Input::Event);
|
||||
|
||||
int flush() override {
|
||||
return call<Rpc_flush>(); }
|
||||
public:
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) override {
|
||||
call<Rpc_sigh>(sigh); }
|
||||
explicit Session_client(Genode::Env &env,
|
||||
Session_capability session)
|
||||
:
|
||||
Genode::Rpc_client<Session>(session),
|
||||
_event_ds(env.rm(), call<Rpc_dataspace>())
|
||||
{ }
|
||||
|
||||
explicit Session_client(Session_capability session)
|
||||
:
|
||||
Genode::Rpc_client<Session>(session),
|
||||
_event_ds(*Genode::env()->rm_session(), call<Rpc_dataspace>())
|
||||
{ }
|
||||
|
||||
Genode::Dataspace_capability dataspace() override {
|
||||
return call<Rpc_dataspace>(); }
|
||||
|
||||
bool pending() const override {
|
||||
return call<Rpc_pending>(); }
|
||||
|
||||
int flush() override {
|
||||
return call<Rpc_flush>(); }
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) override {
|
||||
call<Rpc_sigh>(sigh); }
|
||||
|
||||
/**
|
||||
* Flush and apply functor to pending events
|
||||
*
|
||||
* \param func functor in the form of f(Event const &e)
|
||||
* \return number of events processed
|
||||
*/
|
||||
template <typename FUNC>
|
||||
void for_each_event(FUNC const &func)
|
||||
{
|
||||
Genode::size_t const n = Genode::min((Genode::size_t)call<Rpc_flush>(), _max_events);
|
||||
|
||||
Event const *ev_buf = _event_ds.local_addr<const Event>();
|
||||
for (Genode::size_t i = 0; i < n; ++i)
|
||||
func(ev_buf[i]);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__INPUT_SESSION__CLIENT_H_ */
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2008-2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -21,13 +21,21 @@ namespace Input { struct Connection; }
|
||||
|
||||
struct Input::Connection : Genode::Connection<Session>, Session_client
|
||||
{
|
||||
/**
|
||||
* Issue session request
|
||||
*
|
||||
* \noapi
|
||||
*/
|
||||
Capability<Input::Session> _session(Genode::Parent &parent, char const *label) {
|
||||
return session(parent, "ram_quota=16K, label=\"%s\"", label); }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Connection(Genode::Env &env)
|
||||
Connection(Genode::Env &env, char const *label = "")
|
||||
:
|
||||
Genode::Connection<Session>(env, session(env.parent(), "ram_quota=16K")),
|
||||
Session_client(cap())
|
||||
Genode::Connection<Input::Session>(env, _session(env.parent(), label)),
|
||||
Session_client(env, cap())
|
||||
{ }
|
||||
|
||||
/**
|
||||
@ -39,7 +47,8 @@ struct Input::Connection : Genode::Connection<Session>, Session_client
|
||||
*/
|
||||
Connection()
|
||||
:
|
||||
Genode::Connection<Session>(session("ram_quota=16K")),
|
||||
Genode::Connection<Input::Session>(
|
||||
session(*Genode::env()->parent(), "ram_quota=16K")),
|
||||
Session_client(cap())
|
||||
{ }
|
||||
};
|
||||
|
@ -67,7 +67,7 @@ class Nitpicker::Connection : public Genode::Connection<Session>,
|
||||
|
||||
/* request frame-buffer and input sub sessions */
|
||||
_framebuffer(framebuffer_session()),
|
||||
_input(input_session())
|
||||
_input(env, input_session())
|
||||
{ }
|
||||
|
||||
/**
|
||||
@ -113,7 +113,7 @@ class Nitpicker::Connection : public Genode::Connection<Session>,
|
||||
/**
|
||||
* Return sub session for Nitpicker's input service
|
||||
*/
|
||||
Input::Session *input() { return &_input; }
|
||||
Input::Session_client *input() { return &_input; }
|
||||
|
||||
/**
|
||||
* Return sub session for session's frame buffer
|
||||
|
@ -166,8 +166,8 @@ struct Main
|
||||
|
||||
Genode::Static_root<Framebuffer::Session> fb_root { env.ep().manage(fb_session) };
|
||||
|
||||
Input::Session_component input_session;
|
||||
Input::Root_component input_root { env.ep().rpc_ep(), input_session };
|
||||
Input::Session_component input_session { env, env.ram() };
|
||||
Input::Root_component input_root { env.ep().rpc_ep(), input_session };
|
||||
|
||||
Input::Handler_component input_handler_component { input_session };
|
||||
Input::Handler_client input_handler_client { env.ep().manage(input_handler_component) };
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2015 Genode Labs GmbH
|
||||
* Copyright (C) 2006-2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -14,15 +14,14 @@
|
||||
|
||||
/* Genode */
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/signal.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/component.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <root/component.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <input_session/input_session.h>
|
||||
#include <input/event.h>
|
||||
#include <base/log.h>
|
||||
#include <os/server.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
@ -66,39 +65,40 @@ namespace Input {
|
||||
|
||||
public:
|
||||
|
||||
Root(Rpc_entrypoint *session_ep, Allocator *md_alloc)
|
||||
: Root_component<Session_component>(session_ep, md_alloc) { }
|
||||
Root(Genode::Entrypoint &ep, Allocator &md_alloc)
|
||||
: Root_component<Session_component>(ep, md_alloc) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
struct Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
Input::Root root;
|
||||
Genode::Sliced_heap heap;
|
||||
|
||||
Main(Server::Entrypoint &ep)
|
||||
: ep(ep), root(&ep.rpc_ep(), Genode::env()->heap())
|
||||
Input::Root root;
|
||||
|
||||
Main(Genode::Env &env)
|
||||
:
|
||||
heap(env.ram(), env.rm()),
|
||||
root(env.ep(), heap)
|
||||
{
|
||||
/* create dataspace for event buffer that is shared with the client */
|
||||
try { ev_ds_cap = env()->ram_session()->alloc(MAX_EVENTS*sizeof(Input::Event)); }
|
||||
try { ev_ds_cap = env.ram().alloc(MAX_EVENTS*sizeof(Input::Event)); }
|
||||
catch (Ram_session::Alloc_failed) {
|
||||
Genode::error("could not allocate dataspace for event buffer");
|
||||
throw Genode::Exception();
|
||||
}
|
||||
|
||||
/* tell parent about the service */
|
||||
env()->parent()->announce(ep.manage(root));
|
||||
env.parent().announce(env.ep().manage(root));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
namespace Server {
|
||||
char const *name() { return "input_drv_ep"; }
|
||||
size_t stack_size() { return 2048*sizeof(long); }
|
||||
void construct(Entrypoint &ep) { static Main server(ep); }
|
||||
}
|
||||
Genode::size_t Component::stack_size() { return 2048*sizeof(long); }
|
||||
|
||||
void Component::construct(Genode::Env &env) { static Main server(env); }
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = dummy_input_drv
|
||||
SRC_CC = main.cc
|
||||
LIBS = base server
|
||||
LIBS = base
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
* Copyright (C) 2014-2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -14,10 +14,12 @@
|
||||
/* Genode includes */
|
||||
#include <input/component.h>
|
||||
#include <input_session/connection.h>
|
||||
#include <os/attached_dataspace.h>
|
||||
#include <os/config.h>
|
||||
#include <os/server.h>
|
||||
#include <os/static_root.h>
|
||||
#include <base/component.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/session_label.h>
|
||||
#include <util/list.h>
|
||||
|
||||
|
||||
@ -25,145 +27,122 @@ namespace Input_merger
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
class Input_source : public List<Input_source>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
Input::Session_capability _create_session(const char *label)
|
||||
{
|
||||
char session_args[sizeof(Parent::Session_args)] { 0 };
|
||||
|
||||
Arg_string::set_arg(session_args, sizeof(Parent::Session_args),
|
||||
"ram_quota", "16K");
|
||||
Arg_string::set_arg_string(session_args, sizeof(Parent::Session_args),
|
||||
"label", label);
|
||||
|
||||
return env()->parent()->session<Input::Session>(session_args);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Input::Session_client session_client;
|
||||
Attached_dataspace dataspace;
|
||||
|
||||
Input_source(const char *label)
|
||||
: session_client(_create_session(label)),
|
||||
dataspace(session_client.dataspace()) { }
|
||||
|
||||
~Input_source()
|
||||
{
|
||||
env()->parent()->close(session_client);
|
||||
}
|
||||
};
|
||||
|
||||
struct Input_source;
|
||||
struct Main;
|
||||
|
||||
typedef List<Input_source> Input_sources;
|
||||
typedef String<Session_label::capacity()> Label;
|
||||
}
|
||||
|
||||
|
||||
struct Input_merger::Input_source : Input_sources::Element
|
||||
{
|
||||
Input::Connection conn;
|
||||
Input::Session_component &sink;
|
||||
|
||||
Genode::Signal_handler<Input_source> event_handler;
|
||||
|
||||
void handle_events()
|
||||
{
|
||||
conn.for_each_event([&] (Input::Event const &e) { sink.submit(e); });
|
||||
}
|
||||
|
||||
Input_source(Genode::Env &env, Label const &label, Input::Session_component &sink)
|
||||
:
|
||||
conn(env, label.string()), sink(sink),
|
||||
event_handler(env.ep(), *this, &Input_source::handle_events)
|
||||
{
|
||||
conn.sigh(event_handler);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/******************
|
||||
** Main program **
|
||||
******************/
|
||||
|
||||
struct Input_merger::Main
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
List<Input_source> input_source_list;
|
||||
Env &env;
|
||||
|
||||
Attached_rom_dataspace config_rom { env, "config" };
|
||||
|
||||
Heap heap { env.ram(), env.rm() };
|
||||
|
||||
Input_sources input_source_list;
|
||||
|
||||
/*
|
||||
* Input session provided to our client
|
||||
*/
|
||||
Input::Session_component input_session_component;
|
||||
Input::Session_component input_session_component { env, env.ram() };
|
||||
|
||||
/*
|
||||
* Attach root interface to the entry point
|
||||
*/
|
||||
Static_root<Input::Session> input_root { ep.manage(input_session_component) };
|
||||
Static_root<Input::Session> input_root { env.ep().manage(input_session_component) };
|
||||
|
||||
void handle_input(unsigned)
|
||||
void handle_config_update()
|
||||
{
|
||||
for (Input_source *input_source = input_source_list.first();
|
||||
input_source;
|
||||
input_source = input_source->next()) {
|
||||
config_rom.update();
|
||||
|
||||
Input::Event const * const events =
|
||||
input_source->dataspace.local_addr<Input::Event>();
|
||||
|
||||
unsigned const num = input_source->session_client.flush();
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
input_session_component.submit(events[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Signal_rpc_member<Main> input_dispatcher =
|
||||
{ ep, *this, &Main::handle_input};
|
||||
|
||||
|
||||
void handle_config_update(unsigned)
|
||||
{
|
||||
Genode::config()->reload();
|
||||
|
||||
for (Input_source *input_source;
|
||||
(input_source = input_source_list.first()); ) {
|
||||
while (Input_source *input_source = input_source_list.first()) {
|
||||
input_source_list.remove(input_source);
|
||||
destroy(env()->heap(), input_source);
|
||||
destroy(heap, input_source);
|
||||
}
|
||||
|
||||
try {
|
||||
for (Xml_node input_node = config()->xml_node().sub_node("input");
|
||||
;
|
||||
input_node = input_node.next("input")) {
|
||||
config_rom.xml().for_each_sub_node("input", [&] (Xml_node input_node) {
|
||||
try {
|
||||
Label label;
|
||||
input_node.attribute("label").value(&label);
|
||||
|
||||
char label_buf[128];
|
||||
input_node.attribute("label").value(label_buf, sizeof(label_buf));
|
||||
try {
|
||||
Input_source *input_source = new (heap)
|
||||
Input_source(env, label.string(), input_session_component);
|
||||
|
||||
Input_source *input_source(new (env()->heap()) Input_source(label_buf));
|
||||
input_source_list.insert(input_source);
|
||||
|
||||
input_source_list.insert(input_source);
|
||||
|
||||
input_source->session_client.sigh(input_dispatcher);
|
||||
} catch (Genode::Parent::Service_denied) {
|
||||
error("parent denied input source '", label, "'");
|
||||
}
|
||||
} catch (Xml_node::Nonexistent_attribute) {
|
||||
error("ignoring invalid input node '", input_node);
|
||||
}
|
||||
} catch (Xml_node::Nonexistent_sub_node) { }
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
Signal_rpc_member<Main> config_update_dispatcher =
|
||||
{ ep, *this, &Main::handle_config_update};
|
||||
Signal_handler<Main> config_update_handler
|
||||
{ env.ep(), *this, &Main::handle_config_update };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Main(Server::Entrypoint &ep) : ep(ep)
|
||||
Main(Genode::Env &env) : env(env)
|
||||
{
|
||||
input_session_component.event_queue().enabled(true);
|
||||
|
||||
/*
|
||||
* Apply initial configuration
|
||||
*/
|
||||
handle_config_update(0);
|
||||
handle_config_update();
|
||||
|
||||
/*
|
||||
* Register signal handler
|
||||
*/
|
||||
Genode::config()->sigh(config_update_dispatcher);
|
||||
config_rom.sigh(config_update_handler);
|
||||
|
||||
/*
|
||||
* Announce service
|
||||
*/
|
||||
Genode::env()->parent()->announce(ep.manage(input_root));
|
||||
env.parent().announce(env.ep().manage(input_root));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
namespace Server {
|
||||
Genode::size_t Component::stack_size() { return 4*1024*sizeof(Genode::addr_t); }
|
||||
|
||||
char const *name() { return "input_merger_ep"; }
|
||||
|
||||
size_t stack_size() { return 4*1024*sizeof(addr_t); }
|
||||
|
||||
void construct(Entrypoint &ep) { static Input_merger::Main inst(ep); }
|
||||
}
|
||||
void Component::construct(Genode::Env &env) { static Input_merger::Main inst(env); }
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = input_merger
|
||||
SRC_CC = main.cc
|
||||
LIBS = base config server
|
||||
LIBS = base
|
||||
|
@ -236,7 +236,7 @@ struct Nit_fb::Main : View_updater
|
||||
/*
|
||||
* Input and framebuffer sessions provided to our client
|
||||
*/
|
||||
Input::Session_component input_session;
|
||||
Input::Session_component input_session { env, env.ram() };
|
||||
Framebuffer::Session_component fb_session { nitpicker, *this, _initial_mode() };
|
||||
|
||||
/*
|
||||
|
@ -38,12 +38,12 @@ static char const * ev_type(Input::Event::Type type)
|
||||
}
|
||||
|
||||
|
||||
static char const * key_name(Input::Event *ev)
|
||||
static char const * key_name(Input::Event const &ev)
|
||||
{
|
||||
if (ev->type() == Input::Event::MOTION)
|
||||
if (ev.type() == Input::Event::MOTION)
|
||||
return "";
|
||||
|
||||
return Input::key_name(static_cast<Input::Keycode>(ev->code()));
|
||||
return Input::key_name(static_cast<Input::Keycode>(ev.code()));
|
||||
}
|
||||
|
||||
|
||||
@ -55,8 +55,6 @@ class Test_environment
|
||||
|
||||
Input::Connection _input;
|
||||
|
||||
Input::Event *_ev_buf = { _env.rm().attach(_input.dataspace()) };
|
||||
|
||||
Genode::Signal_handler<Test_environment> _input_sigh;
|
||||
|
||||
unsigned int event_count = 0;
|
||||
@ -71,8 +69,6 @@ class Test_environment
|
||||
{
|
||||
log("--- Input test is up ---");
|
||||
|
||||
log("input buffer at ", _ev_buf);
|
||||
|
||||
_input.sigh(_input_sigh);
|
||||
}
|
||||
};
|
||||
@ -85,25 +81,22 @@ void Test_environment::_handle_input()
|
||||
*/
|
||||
int key_cnt = 0;
|
||||
|
||||
for (int i = 0, num_ev = _input.flush(); i < num_ev; ++i) {
|
||||
|
||||
_input.for_each_event([&] (Input::Event const &ev) {
|
||||
event_count++;
|
||||
|
||||
Input::Event *ev = &_ev_buf[i];
|
||||
|
||||
if (ev->type() == Input::Event::PRESS) key_cnt++;
|
||||
if (ev->type() == Input::Event::RELEASE) key_cnt--;
|
||||
if (ev.type() == Input::Event::PRESS) key_cnt++;
|
||||
if (ev.type() == Input::Event::RELEASE) key_cnt--;
|
||||
|
||||
/* log event */
|
||||
log("Input event #", event_count, "\t"
|
||||
"type=", ev_type(ev->type()), "\t"
|
||||
"code=", ev->code(), "\t"
|
||||
"rx=", ev->rx(), "\t"
|
||||
"ry=", ev->ry(), "\t"
|
||||
"ax=", ev->ax(), "\t"
|
||||
"ay=", ev->ay(), "\t"
|
||||
"type=", ev_type(ev.type()), "\t"
|
||||
"code=", ev.code(), "\t"
|
||||
"rx=", ev.rx(), "\t"
|
||||
"ry=", ev.ry(), "\t"
|
||||
"ax=", ev.ax(), "\t"
|
||||
"ay=", ev.ay(), "\t"
|
||||
"key_cnt=", key_cnt, "\t", key_name(ev));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
|
@ -165,8 +165,6 @@ int main(int argc, char **argv)
|
||||
unsigned char *alpha = (unsigned char *)&pixels[scr_w*scr_h];
|
||||
unsigned char *input_mask = CONFIG_ALPHA ? alpha + scr_w*scr_h : 0;
|
||||
|
||||
Input::Event *ev_buf = (env()->rm_session()->attach(nitpicker.input()->dataspace()));
|
||||
|
||||
/*
|
||||
* Paint some crap into pixel buffer, fill alpha channel and input-mask buffer
|
||||
*
|
||||
@ -208,28 +206,25 @@ int main(int argc, char **argv)
|
||||
|
||||
while (!nitpicker.input()->pending()) timer.msleep(20);
|
||||
|
||||
for (int i = 0, num_ev = nitpicker.input()->flush(); i < num_ev; i++) {
|
||||
|
||||
Input::Event *ev = &ev_buf[i];
|
||||
|
||||
if (ev->type() == Input::Event::PRESS) key_cnt++;
|
||||
if (ev->type() == Input::Event::RELEASE) key_cnt--;
|
||||
nitpicker.input()->for_each_event([&] (Input::Event const &ev) {
|
||||
if (ev.type() == Input::Event::PRESS) key_cnt++;
|
||||
if (ev.type() == Input::Event::RELEASE) key_cnt--;
|
||||
|
||||
/* move selected view */
|
||||
if (ev->type() == Input::Event::MOTION && key_cnt > 0 && tv)
|
||||
tv->move(tv->x() + ev->ax() - omx, tv->y() + ev->ay() - omy);
|
||||
if (ev.type() == Input::Event::MOTION && key_cnt > 0 && tv)
|
||||
tv->move(tv->x() + ev.ax() - omx, tv->y() + ev.ay() - omy);
|
||||
|
||||
/* find selected view and bring it to front */
|
||||
if (ev->type() == Input::Event::PRESS && key_cnt == 1) {
|
||||
if (ev.type() == Input::Event::PRESS && key_cnt == 1) {
|
||||
|
||||
tv = tvs.find(ev->ax(), ev->ay());
|
||||
tv = tvs.find(ev.ax(), ev.ay());
|
||||
|
||||
if (tv)
|
||||
tvs.top(tv);
|
||||
}
|
||||
|
||||
omx = ev->ax(); omy = ev->ay();
|
||||
}
|
||||
omx = ev.ax(); omy = ev.ay();
|
||||
});
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -61,16 +61,16 @@ struct Ps2_mouse_packet : Genode::Register<32>
|
||||
};
|
||||
|
||||
|
||||
static bool mouse_event(Input::Event const *ev)
|
||||
static bool mouse_event(Input::Event const &ev)
|
||||
{
|
||||
using Input::Event;
|
||||
if (ev->type() == Event::PRESS || ev->type() == Event::RELEASE) {
|
||||
if (ev->code() == Input::BTN_LEFT) return true;
|
||||
if (ev->code() == Input::BTN_MIDDLE) return true;
|
||||
if (ev->code() == Input::BTN_RIGHT) return true;
|
||||
if (ev.type() == Event::PRESS || ev.type() == Event::RELEASE) {
|
||||
if (ev.code() == Input::BTN_LEFT) return true;
|
||||
if (ev.code() == Input::BTN_MIDDLE) return true;
|
||||
if (ev.code() == Input::BTN_RIGHT) return true;
|
||||
}
|
||||
|
||||
if (ev->type() == Event::MOTION)
|
||||
if (ev.type() == Event::MOTION)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -82,28 +82,28 @@ static bool mouse_event(Input::Event const *ev)
|
||||
*
|
||||
* This function updates _left, _middle, and _right as a side effect.
|
||||
*/
|
||||
unsigned Vancouver_console::_input_to_ps2mouse(Input::Event const *ev)
|
||||
unsigned Vancouver_console::_input_to_ps2mouse(Input::Event const &ev)
|
||||
{
|
||||
/* track state of mouse buttons */
|
||||
using Input::Event;
|
||||
if (ev->type() == Event::PRESS || ev->type() == Event::RELEASE) {
|
||||
bool const pressed = ev->type() == Event::PRESS;
|
||||
if (ev->code() == Input::BTN_LEFT) _left = pressed;
|
||||
if (ev->code() == Input::BTN_MIDDLE) _middle = pressed;
|
||||
if (ev->code() == Input::BTN_RIGHT) _right = pressed;
|
||||
if (ev.type() == Event::PRESS || ev.type() == Event::RELEASE) {
|
||||
bool const pressed = ev.type() == Event::PRESS;
|
||||
if (ev.code() == Input::BTN_LEFT) _left = pressed;
|
||||
if (ev.code() == Input::BTN_MIDDLE) _middle = pressed;
|
||||
if (ev.code() == Input::BTN_RIGHT) _right = pressed;
|
||||
}
|
||||
|
||||
int rx;
|
||||
int ry;
|
||||
|
||||
if (ev->absolute_motion()) {
|
||||
if (ev.absolute_motion()) {
|
||||
static Input::Event last_event;
|
||||
rx = ev->ax() - last_event.ax();
|
||||
ry = ev->ay() - last_event.ay();
|
||||
last_event = *ev;
|
||||
rx = ev.ax() - last_event.ax();
|
||||
ry = ev.ay() - last_event.ay();
|
||||
last_event = ev;
|
||||
} else {
|
||||
rx = ev->rx();
|
||||
ry = ev->ry();
|
||||
rx = ev.rx();
|
||||
ry = ev.ry();
|
||||
}
|
||||
|
||||
/* clamp relative motion vector to bounds */
|
||||
@ -228,11 +228,6 @@ void Vancouver_console::entry()
|
||||
return;
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability ev_ds_cap = input.dataspace();
|
||||
|
||||
Input::Event *ev_buf = static_cast<Input::Event *>
|
||||
(env()->rm_session()->attach(ev_ds_cap));
|
||||
|
||||
_fb_size = Dataspace_client(framebuffer->dataspace()).size();
|
||||
_fb_mode = framebuffer->mode();
|
||||
|
||||
@ -335,28 +330,26 @@ void Vancouver_console::entry()
|
||||
timer.msleep(10);
|
||||
}
|
||||
|
||||
for (int i = 0, num_ev = input.flush(); i < num_ev; i++) {
|
||||
input.for_each_event([&] (Input::Event const &ev) {
|
||||
if (!fb_active) fb_active = true;
|
||||
|
||||
Input::Event *ev = &ev_buf[i];
|
||||
|
||||
/* update mouse model (PS2) */
|
||||
if (mouse_event(ev)) {
|
||||
MessageInput msg(0x10001, _input_to_ps2mouse(ev));
|
||||
_motherboard()->bus_input.send(msg);
|
||||
}
|
||||
|
||||
if (ev->type() == Input::Event::PRESS) {
|
||||
if (ev->code() <= 0xee) {
|
||||
vkeyb.handle_keycode_press(ev->code());
|
||||
if (ev.type() == Input::Event::PRESS) {
|
||||
if (ev.code() <= 0xee) {
|
||||
vkeyb.handle_keycode_press(ev.code());
|
||||
}
|
||||
}
|
||||
if (ev->type() == Input::Event::RELEASE) {
|
||||
if (ev->code() <= 0xee) { /* keyboard event */
|
||||
vkeyb.handle_keycode_release(ev->code());
|
||||
if (ev.type() == Input::Event::RELEASE) {
|
||||
if (ev.code() <= 0xee) { /* keyboard event */
|
||||
vkeyb.handle_keycode_release(ev.code());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ class Vancouver_console : public Thread_deprecated<8192>, public StaticReceiver<
|
||||
Framebuffer::Mode _fb_mode;
|
||||
bool _left, _middle, _right;
|
||||
|
||||
unsigned _input_to_ps2mouse(Input::Event const *);
|
||||
unsigned _input_to_ps2mouse(Input::Event const &);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -189,9 +189,7 @@ void GenodeConsole::handle_input(unsigned)
|
||||
_vbox_mouse->COMGETTER(RelativeSupported)(&guest_rel);
|
||||
_vbox_mouse->COMGETTER(MultiTouchSupported)(&guest_multi);
|
||||
|
||||
for (int i = 0, num_ev = _input.flush(); i < num_ev; ++i) {
|
||||
Input::Event &ev = _ev_buf[i];
|
||||
|
||||
_input.for_each_event([&] (Input::Event const &ev) {
|
||||
bool const press = ev.type() == Input::Event::PRESS;
|
||||
bool const release = ev.type() == Input::Event::RELEASE;
|
||||
bool const key = press || release;
|
||||
@ -322,7 +320,7 @@ void GenodeConsole::handle_input(unsigned)
|
||||
mt_events[mt_number++] = RT_MAKE_U64_FROM_U16(x, y, s, 0);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
/* if there are elements - send it */
|
||||
if (mt_number)
|
||||
|
@ -112,7 +112,6 @@ class GenodeConsole : public Console {
|
||||
|
||||
Input::Connection _input;
|
||||
Genode::Signal_receiver _receiver;
|
||||
Input::Event *_ev_buf;
|
||||
unsigned _ax, _ay;
|
||||
bool _last_received_motion_event_was_absolute;
|
||||
Report::Connection _shape_report_connection;
|
||||
@ -140,7 +139,6 @@ class GenodeConsole : public Console {
|
||||
GenodeConsole()
|
||||
:
|
||||
Console(),
|
||||
_ev_buf(static_cast<Input::Event *>(Genode::env()->rm_session()->attach(_input.dataspace()))),
|
||||
_ax(0), _ay(0),
|
||||
_last_received_motion_event_was_absolute(false),
|
||||
_shape_report_connection("shape", sizeof(Vbox_pointer::Shape_report)),
|
||||
|
@ -134,9 +134,7 @@ void GenodeConsole::handle_input(unsigned)
|
||||
_vbox_mouse->COMGETTER(RelativeSupported)(&guest_rel);
|
||||
_vbox_mouse->COMGETTER(MultiTouchSupported)(&guest_multi);
|
||||
|
||||
for (int i = 0, num_ev = _input.flush(); i < num_ev; ++i) {
|
||||
Input::Event &ev = _ev_buf[i];
|
||||
|
||||
_input.for_each_event([&] (Input::Event const &ev) {
|
||||
bool const press = ev.type() == Input::Event::PRESS;
|
||||
bool const release = ev.type() == Input::Event::RELEASE;
|
||||
bool const key = press || release;
|
||||
@ -267,7 +265,7 @@ void GenodeConsole::handle_input(unsigned)
|
||||
mt_events[mt_number++] = RT_MAKE_U64_FROM_U16(x, y, s, 0);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
/* if there are elements - send it */
|
||||
if (mt_number)
|
||||
|
@ -112,7 +112,6 @@ class GenodeConsole : public Console {
|
||||
|
||||
Input::Connection _input;
|
||||
Genode::Signal_receiver _receiver;
|
||||
Input::Event *_ev_buf;
|
||||
unsigned _ax, _ay;
|
||||
bool _last_received_motion_event_was_absolute;
|
||||
Report::Connection _shape_report_connection;
|
||||
@ -140,7 +139,6 @@ class GenodeConsole : public Console {
|
||||
GenodeConsole()
|
||||
:
|
||||
Console(),
|
||||
_ev_buf(static_cast<Input::Event *>(Genode::env()->rm_session()->attach(_input.dataspace()))),
|
||||
_ax(0), _ay(0),
|
||||
_last_received_motion_event_was_absolute(false),
|
||||
_shape_report_connection("shape", sizeof(Vbox_pointer::Shape_report)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user