mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
Add Input::Session::exclusive() interface
This interface allows a GUI client to express the intent to exclusively observe relative motion events while locking the absolute pointer position. This patch merely extends the interface without implementing it. As this change touches os/include/input/component.h, it moves the manage/dissolve operations into the class, ensuring the call of dissolve at destruction time. Issue #5355
This commit is contained in:
parent
318d641266
commit
d7830a0ce6
@ -125,7 +125,8 @@ namespace Liquid_fb {
|
||||
}
|
||||
|
||||
|
||||
class Liquid_fb::Main : public Scout::Event_handler
|
||||
class Liquid_fb::Main : public Scout::Event_handler,
|
||||
private Input::Session_component::Action
|
||||
{
|
||||
private:
|
||||
|
||||
@ -162,7 +163,16 @@ class Liquid_fb::Main : public Scout::Event_handler
|
||||
_graphics_backend { _env.rm(), _gui, _heap, _max_size,
|
||||
_initial_position, _initial_size };
|
||||
|
||||
Input::Session_component _input_session_component { _env, _env.ram() };
|
||||
Input::Session_component _input_session_component {
|
||||
_env.ep(), _env.ram(), _env.rm(), *this };
|
||||
|
||||
/**
|
||||
* Input::Session_component::Action interface
|
||||
*/
|
||||
void exclusive_input_requested(bool enabled) override
|
||||
{
|
||||
_gui.input.exclusive(enabled);
|
||||
}
|
||||
|
||||
bool const _window_content_initialized =
|
||||
(init_window_content(_env.ram(), _env.rm(), _heap, _input_session_component,
|
||||
|
@ -49,7 +49,8 @@ static bool clack(Input::Event const &event)
|
||||
}
|
||||
|
||||
|
||||
struct Gui::Session_component : Rpc_object<Gui::Session>
|
||||
struct Gui::Session_component : Rpc_object<Gui::Session>,
|
||||
private Input::Session_component::Action
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
@ -63,7 +64,16 @@ struct Gui::Session_component : Rpc_object<Gui::Session>
|
||||
|
||||
Input::Session_client _gui_input { _env.rm(), _gui_session.input() };
|
||||
|
||||
Input::Session_component _input_component { _env, _env.ram() };
|
||||
Input::Session_component _input_component {
|
||||
_env.ep(), _env.ram(), _env.rm(), *this };
|
||||
|
||||
/**
|
||||
* Input::Session_component::Action interface
|
||||
*/
|
||||
void exclusive_input_requested(bool enabled) override
|
||||
{
|
||||
_gui_input.exclusive(enabled);
|
||||
}
|
||||
|
||||
Signal_handler<Session_component> _input_handler {
|
||||
_env.ep(), *this, &Session_component::_handle_input };
|
||||
@ -104,12 +114,9 @@ struct Gui::Session_component : Rpc_object<Gui::Session>
|
||||
_connection(env, session_label_from_args(args), Ram_quota { 36*1024 }, { })
|
||||
{
|
||||
_gui_input.sigh(_input_handler);
|
||||
_env.ep().manage(_input_component);
|
||||
_input_component.event_queue().enabled(true);
|
||||
}
|
||||
|
||||
~Session_component() { _env.ep().dissolve(_input_component); }
|
||||
|
||||
void upgrade(Session::Resources const &resources)
|
||||
{
|
||||
_connection.upgrade(resources);
|
||||
|
@ -66,7 +66,14 @@ struct Sandboxed_runtime::Gui_session : Session_object<Gui::Session>
|
||||
|
||||
Input::Session_client _gui_input { _env.rm(), _gui_session.input() };
|
||||
|
||||
Input::Session_component _input_component { _env, _env.ram() };
|
||||
struct Input_action : Input::Session_component::Action
|
||||
{
|
||||
void exclusive_input_requested(bool) override { };
|
||||
|
||||
} _input_action { };
|
||||
|
||||
Input::Session_component _input_component {
|
||||
_env.ep(), _env.ram(), _env.rm(), _input_action };
|
||||
|
||||
Signal_handler<Gui_session> _input_handler {
|
||||
_env.ep(), *this, &Gui_session::_handle_input };
|
||||
@ -109,12 +116,9 @@ struct Sandboxed_runtime::Gui_session : Session_object<Gui::Session>
|
||||
_connection(env, _label, Ram_quota { 36*1024 }, { })
|
||||
{
|
||||
_gui_input.sigh(_input_handler);
|
||||
_env.ep().manage(_input_component);
|
||||
_input_component.event_queue().enabled(true);
|
||||
}
|
||||
|
||||
~Gui_session() { _env.ep().dissolve(_input_component); }
|
||||
|
||||
void upgrade(Session::Resources const &resources)
|
||||
{
|
||||
_connection.upgrade(resources);
|
||||
|
@ -94,10 +94,15 @@ struct Wm::Decorator_gui_session : Session_object<Gui::Session>,
|
||||
|
||||
Decorator_content_callback &_content_callback;
|
||||
|
||||
struct Dummy_input_action : Input::Session_component::Action
|
||||
{
|
||||
void exclusive_input_requested(bool) override { };
|
||||
|
||||
} _input_action { };
|
||||
|
||||
/* Gui::Connection requires a valid input session */
|
||||
Input::Session_component _dummy_input_component { _env, _env.ram() };
|
||||
Input::Session_capability _dummy_input_component_cap =
|
||||
_env.ep().manage(_dummy_input_component);
|
||||
Input::Session_component _dummy_input_component {
|
||||
_env.ep(), _env.ram(), _env.rm(), _input_action };
|
||||
|
||||
Signal_handler<Decorator_gui_session>
|
||||
_input_handler { _env.ep(), *this, &Decorator_gui_session::_handle_input };
|
||||
@ -126,11 +131,6 @@ struct Wm::Decorator_gui_session : Session_object<Gui::Session>,
|
||||
_input_session.sigh(_input_handler);
|
||||
}
|
||||
|
||||
~Decorator_gui_session()
|
||||
{
|
||||
_env.ep().dissolve(_dummy_input_component);
|
||||
}
|
||||
|
||||
void upgrade_local_or_remote(Resources const &resources)
|
||||
{
|
||||
_upgrade_local_or_remote(resources, *this, _real_gui);
|
||||
@ -219,7 +219,7 @@ struct Wm::Decorator_gui_session : Session_object<Gui::Session>,
|
||||
* Deny input to the decorator. User input referring to the
|
||||
* window decorations is routed to the window manager.
|
||||
*/
|
||||
return _dummy_input_component_cap;
|
||||
return _dummy_input_component.cap();
|
||||
}
|
||||
|
||||
Info_result info() override
|
||||
|
@ -496,7 +496,8 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
|
||||
private List<Session_component>::Element,
|
||||
private Input_origin_changed_handler,
|
||||
private Upgradeable,
|
||||
private Dynamic_rom_session::Xml_producer
|
||||
private Dynamic_rom_session::Xml_producer,
|
||||
private Input::Session_component::Action
|
||||
{
|
||||
public:
|
||||
|
||||
@ -556,21 +557,15 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
|
||||
List<Child_view> _child_views { };
|
||||
View_ids _view_ids { };
|
||||
|
||||
struct Input_session : Input::Session_component
|
||||
{
|
||||
Entrypoint &_ep;
|
||||
Input::Session_component _input_session {
|
||||
_env.ep(), _ram, _env.rm(), *this };
|
||||
|
||||
Input_session(Env &env, Ram_allocator &ram)
|
||||
: Input::Session_component(env, ram), _ep(env.ep())
|
||||
{
|
||||
_ep.manage(*this);
|
||||
}
|
||||
/**
|
||||
* Input::Session_component::Action interface
|
||||
*/
|
||||
void exclusive_input_requested(bool) override { }
|
||||
|
||||
~Input_session() { _ep.dissolve(*this); }
|
||||
};
|
||||
|
||||
Input_session _input_session { _env, _ram };
|
||||
Click_handler &_click_handler;
|
||||
Click_handler &_click_handler;
|
||||
|
||||
struct Info_rom_session : Dynamic_rom_session
|
||||
{
|
||||
@ -1281,8 +1276,9 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
|
||||
};
|
||||
|
||||
|
||||
class Wm::Gui::Root : public Rpc_object<Typed_root<Gui::Session> >,
|
||||
public Decorator_content_callback
|
||||
class Wm::Gui::Root : public Rpc_object<Typed_root<Gui::Session> >,
|
||||
public Decorator_content_callback,
|
||||
private Input::Session_component::Action
|
||||
{
|
||||
private:
|
||||
|
||||
@ -1306,9 +1302,13 @@ class Wm::Gui::Root : public Rpc_object<Typed_root<Gui::Session> >,
|
||||
|
||||
Window_registry &_window_registry;
|
||||
|
||||
Input::Session_component _window_layouter_input { _env, _env.ram() };
|
||||
Input::Session_component _window_layouter_input {
|
||||
_env.ep(), _env.ram(), _env.rm(), *this };
|
||||
|
||||
Input::Session_capability _window_layouter_input_cap { _env.ep().manage(_window_layouter_input) };
|
||||
/**
|
||||
* Input::Session_component::Action interface
|
||||
*/
|
||||
void exclusive_input_requested(bool) override { }
|
||||
|
||||
/* handler that forwards clicks into unfocused windows to the layouter */
|
||||
struct Click_handler : Gui::Click_handler
|
||||
@ -1475,7 +1475,7 @@ class Wm::Gui::Root : public Rpc_object<Typed_root<Gui::Session> >,
|
||||
{
|
||||
_layouter_session = new (_sliced_heap)
|
||||
Layouter_gui_session(_env, resources, label, diag,
|
||||
_window_layouter_input_cap);
|
||||
_window_layouter_input.cap());
|
||||
|
||||
return _layouter_session->cap();
|
||||
}
|
||||
|
@ -25,11 +25,21 @@
|
||||
namespace Input { class Session_component; }
|
||||
|
||||
|
||||
class Input::Session_component : public Genode::Rpc_object<Input::Session>
|
||||
class Input::Session_component : public Rpc_object<Input::Session>
|
||||
{
|
||||
public:
|
||||
|
||||
struct Action : Interface
|
||||
{
|
||||
virtual void exclusive_input_requested(bool) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Genode::Attached_ram_dataspace _ds;
|
||||
Entrypoint &_ep;
|
||||
Action &_action;
|
||||
|
||||
Attached_ram_dataspace _ds;
|
||||
|
||||
Event_queue _event_queue { };
|
||||
|
||||
@ -38,12 +48,18 @@ class Input::Session_component : public Genode::Rpc_object<Input::Session>
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param ram allocator for the session buffer
|
||||
* \param ram allocator for the shared-memory input buffer
|
||||
*/
|
||||
Session_component(Genode::Env &env, Genode::Ram_allocator &ram)
|
||||
Session_component(Entrypoint &ep, Ram_allocator &ram,
|
||||
Region_map &rm, Action &action)
|
||||
:
|
||||
_ds(ram, env.rm(), Event_queue::QUEUE_SIZE*sizeof(Input::Event))
|
||||
{ }
|
||||
_ep(ep), _action(action),
|
||||
_ds(ram, rm, Event_queue::QUEUE_SIZE*sizeof(Input::Event))
|
||||
{
|
||||
_ep.manage(*this);
|
||||
}
|
||||
|
||||
~Session_component() { _ep.dissolve(*this); }
|
||||
|
||||
/**
|
||||
* Return reference to event queue of the session
|
||||
@ -58,7 +74,7 @@ class Input::Session_component : public Genode::Rpc_object<Input::Session>
|
||||
try {
|
||||
_event_queue.add(event);
|
||||
} catch (Input::Event_queue::Overflow) {
|
||||
Genode::warning("input overflow - resetting queue");
|
||||
warning("input overflow - resetting queue");
|
||||
_event_queue.reset();
|
||||
}
|
||||
}
|
||||
@ -68,7 +84,7 @@ class Input::Session_component : public Genode::Rpc_object<Input::Session>
|
||||
** Input::Session interface **
|
||||
******************************/
|
||||
|
||||
Genode::Dataspace_capability dataspace() override { return _ds.cap(); }
|
||||
Dataspace_capability dataspace() override { return _ds.cap(); }
|
||||
|
||||
bool pending() const override { return !_event_queue.empty(); }
|
||||
|
||||
@ -83,10 +99,15 @@ class Input::Session_component : public Genode::Rpc_object<Input::Session>
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) override
|
||||
void sigh(Signal_context_capability sigh) override
|
||||
{
|
||||
_event_queue.sigh(sigh);
|
||||
}
|
||||
|
||||
void exclusive(bool enabled) override
|
||||
{
|
||||
_action.exclusive_input_requested(enabled);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__INPUT__COMPONENT_H_ */
|
||||
|
@ -22,26 +22,25 @@
|
||||
namespace Input { struct Session_client; }
|
||||
|
||||
|
||||
class Input::Session_client : public Genode::Rpc_client<Session>
|
||||
class Input::Session_client : public Rpc_client<Session>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Attached_dataspace _event_ds;
|
||||
Attached_dataspace _event_ds;
|
||||
|
||||
Genode::size_t const _max_events =
|
||||
_event_ds.size() / sizeof(Input::Event);
|
||||
size_t const _max_events = _event_ds.size() / sizeof(Input::Event);
|
||||
|
||||
friend class Input::Binding;
|
||||
|
||||
public:
|
||||
|
||||
Session_client(Genode::Region_map &local_rm, Session_capability session)
|
||||
Session_client(Region_map &local_rm, Session_capability session)
|
||||
:
|
||||
Genode::Rpc_client<Session>(session),
|
||||
Rpc_client<Session>(session),
|
||||
_event_ds(local_rm, call<Rpc_dataspace>())
|
||||
{ }
|
||||
|
||||
Genode::Dataspace_capability dataspace() override {
|
||||
Dataspace_capability dataspace() override {
|
||||
return call<Rpc_dataspace>(); }
|
||||
|
||||
bool pending() const override {
|
||||
@ -50,9 +49,12 @@ class Input::Session_client : public Genode::Rpc_client<Session>
|
||||
int flush() override {
|
||||
return call<Rpc_flush>(); }
|
||||
|
||||
void sigh(Genode::Signal_context_capability sigh) override {
|
||||
void sigh(Signal_context_capability sigh) override {
|
||||
call<Rpc_sigh>(sigh); }
|
||||
|
||||
void exclusive(bool enabled) override {
|
||||
call<Rpc_exclusive>(enabled); }
|
||||
|
||||
/**
|
||||
* Flush and apply functor to pending events
|
||||
*
|
||||
@ -61,10 +63,10 @@ class Input::Session_client : public Genode::Rpc_client<Session>
|
||||
*/
|
||||
void for_each_event(auto const &fn)
|
||||
{
|
||||
Genode::size_t const n = Genode::min((Genode::size_t)call<Rpc_flush>(), _max_events);
|
||||
size_t const n = min((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)
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
fn(ev_buf[i]);
|
||||
}
|
||||
};
|
||||
|
@ -19,7 +19,12 @@
|
||||
#include <session/session.h>
|
||||
#include <base/signal.h>
|
||||
|
||||
namespace Input { struct Session; }
|
||||
namespace Input {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Session;
|
||||
}
|
||||
|
||||
|
||||
struct Input::Session : Genode::Session
|
||||
@ -41,7 +46,7 @@ struct Input::Session : Genode::Session
|
||||
/**
|
||||
* Return capability to event buffer dataspace
|
||||
*/
|
||||
virtual Genode::Dataspace_capability dataspace() = 0;
|
||||
virtual Dataspace_capability dataspace() = 0;
|
||||
|
||||
/**
|
||||
* Request input state
|
||||
@ -60,19 +65,26 @@ struct Input::Session : Genode::Session
|
||||
/**
|
||||
* Register signal handler to be notified on arrival of new input
|
||||
*/
|
||||
virtual void sigh(Genode::Signal_context_capability) = 0;
|
||||
virtual void sigh(Signal_context_capability) = 0;
|
||||
|
||||
/**
|
||||
* Express intent to receive relative pointer events exclusively
|
||||
*/
|
||||
virtual void exclusive(bool) = 0;
|
||||
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
*********************/
|
||||
|
||||
GENODE_RPC(Rpc_dataspace, Genode::Dataspace_capability, dataspace);
|
||||
GENODE_RPC(Rpc_pending, bool, pending);
|
||||
GENODE_RPC(Rpc_flush, int, flush);
|
||||
GENODE_RPC(Rpc_sigh, void, sigh, Genode::Signal_context_capability);
|
||||
GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace);
|
||||
GENODE_RPC(Rpc_pending, bool, pending);
|
||||
GENODE_RPC(Rpc_flush, int, flush);
|
||||
GENODE_RPC(Rpc_sigh, void, sigh, Signal_context_capability);
|
||||
GENODE_RPC(Rpc_exclusive, void, exclusive, bool);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_pending, Rpc_flush, Rpc_sigh);
|
||||
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_pending, Rpc_flush, Rpc_sigh,
|
||||
Rpc_exclusive);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__INPUT_SESSION__INPUT_SESSION_H_ */
|
||||
|
@ -247,7 +247,7 @@ struct Framebuffer::Session_component : Genode::Rpc_object<Framebuffer::Session>
|
||||
** Main program **
|
||||
******************/
|
||||
|
||||
struct Gui_fb::Main : View_updater
|
||||
struct Gui_fb::Main : View_updater, Input::Session_component::Action
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
@ -316,10 +316,19 @@ struct Gui_fb::Main : View_updater
|
||||
/*
|
||||
* Input and framebuffer sessions provided to our client
|
||||
*/
|
||||
Input::Session_component _input_session { _env, _env.ram() };
|
||||
Input::Session_component _input_session { _env.ep(), _env.ram(), _env.rm(), *this };
|
||||
|
||||
/**
|
||||
* Input::Session_component::Action interface
|
||||
*/
|
||||
void exclusive_input_requested(bool enabled) override
|
||||
{
|
||||
_gui.input.exclusive(enabled);
|
||||
}
|
||||
|
||||
Framebuffer::Session_component _fb_session { _env.pd(), _gui, *this, _initial_mode() };
|
||||
|
||||
Static_root<Input::Session> _input_root { _env.ep().manage(_input_session) };
|
||||
Static_root<Input::Session> _input_root { _input_session.cap() };
|
||||
|
||||
/*
|
||||
* Attach root interfaces to the entry point
|
||||
|
@ -113,6 +113,8 @@ class Input::Session_component : public Rpc_object<Session>
|
||||
}
|
||||
|
||||
void sigh(Signal_context_capability sigh) override { _sigh = sigh; }
|
||||
|
||||
void exclusive(bool) override { }
|
||||
};
|
||||
|
||||
#endif /* _INPUT_SESSION_COMPONENT_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user