mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-20 16:10:29 +00:00
loader: Adaptation to new nitpicker interface
This commit is contained in:
@ -21,41 +21,42 @@
|
|||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
|
|
||||||
struct Session_client : Rpc_client<Session>
|
struct Session_client : Genode::Rpc_client<Session>
|
||||||
{
|
{
|
||||||
explicit Session_client(Loader::Session_capability session)
|
explicit Session_client(Loader::Session_capability session)
|
||||||
: Rpc_client<Session>(session) { }
|
: Rpc_client<Session>(session) { }
|
||||||
|
|
||||||
Dataspace_capability alloc_rom_module(Name const &name, size_t size) {
|
Dataspace_capability alloc_rom_module(Name const &name,
|
||||||
|
size_t size) override {
|
||||||
return call<Rpc_alloc_rom_module>(name, size); }
|
return call<Rpc_alloc_rom_module>(name, size); }
|
||||||
|
|
||||||
void commit_rom_module(Name const &name) {
|
void commit_rom_module(Name const &name) override {
|
||||||
call<Rpc_commit_rom_module>(name); }
|
call<Rpc_commit_rom_module>(name); }
|
||||||
|
|
||||||
void ram_quota(size_t quantum) {
|
void ram_quota(size_t quantum) override {
|
||||||
call<Rpc_ram_quota>(quantum); }
|
call<Rpc_ram_quota>(quantum); }
|
||||||
|
|
||||||
void constrain_geometry(int width, int height) {
|
void constrain_geometry(Area size) override {
|
||||||
call<Rpc_constrain_geometry>(width, height); }
|
call<Rpc_constrain_geometry>(size); }
|
||||||
|
|
||||||
void parent_view(Nitpicker::View_capability view) {
|
void parent_view(Nitpicker::View_capability view) override {
|
||||||
call<Rpc_parent_view>(view); }
|
call<Rpc_parent_view>(view); }
|
||||||
|
|
||||||
void view_ready_sigh(Signal_context_capability sigh) {
|
void view_ready_sigh(Signal_context_capability sigh) override {
|
||||||
call<Rpc_view_ready_sigh>(sigh); }
|
call<Rpc_view_ready_sigh>(sigh); }
|
||||||
|
|
||||||
void fault_sigh(Signal_context_capability sigh) {
|
void fault_sigh(Signal_context_capability sigh) override {
|
||||||
call<Rpc_fault_sigh>(sigh); }
|
call<Rpc_fault_sigh>(sigh); }
|
||||||
|
|
||||||
void start(Name const &binary, Name const &label = "",
|
void start(Name const &binary, Name const &label = "",
|
||||||
Native_pd_args const &pd_args = Native_pd_args()) {
|
Native_pd_args const &pd_args = Native_pd_args()) override {
|
||||||
call<Rpc_start>(binary, label, pd_args); }
|
call<Rpc_start>(binary, label, pd_args); }
|
||||||
|
|
||||||
Nitpicker::View_capability view() {
|
void view_geometry(Rect rect, Point offset) override {
|
||||||
return call<Rpc_view>(); }
|
call<Rpc_view_geometry>(rect, offset); }
|
||||||
|
|
||||||
View_geometry view_geometry() {
|
Area view_size() const override {
|
||||||
return call<Rpc_view_geometry>(); }
|
return call<Rpc_view_size>(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,10 +21,18 @@
|
|||||||
#include <nitpicker_session/client.h>
|
#include <nitpicker_session/client.h>
|
||||||
#include <base/signal.h>
|
#include <base/signal.h>
|
||||||
#include <session/session.h>
|
#include <session/session.h>
|
||||||
|
#include <util/geometry.h>
|
||||||
|
|
||||||
namespace Loader {
|
namespace Loader {
|
||||||
|
|
||||||
using namespace Genode;
|
typedef Genode::Point<> Point;
|
||||||
|
typedef Genode::Area<> Area;
|
||||||
|
typedef Genode::Rect<> Rect;
|
||||||
|
|
||||||
|
using Genode::Dataspace_capability;
|
||||||
|
using Genode::Signal_context_capability;
|
||||||
|
using Genode::Native_pd_args;
|
||||||
|
using Genode::Meta::Type_tuple;
|
||||||
|
|
||||||
struct Session : Genode::Session
|
struct Session : Genode::Session
|
||||||
{
|
{
|
||||||
@ -41,18 +49,6 @@ namespace Loader {
|
|||||||
struct View_does_not_exist : Exception { };
|
struct View_does_not_exist : Exception { };
|
||||||
struct Rom_module_does_not_exist : Exception { };
|
struct Rom_module_does_not_exist : Exception { };
|
||||||
|
|
||||||
/**
|
|
||||||
* Return argument of 'view_geometry()'
|
|
||||||
*/
|
|
||||||
struct View_geometry
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
int buf_x, buf_y;
|
|
||||||
|
|
||||||
View_geometry(): width(0), height(0), buf_x(0), buf_y() {}
|
|
||||||
View_geometry(int w, int h, int x, int y): width(w), height(h), buf_x(x), buf_y(y) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Genode::Rpc_in_buffer<64> Name;
|
typedef Genode::Rpc_in_buffer<64> Name;
|
||||||
typedef Genode::Rpc_in_buffer<128> Path;
|
typedef Genode::Rpc_in_buffer<128> Path;
|
||||||
|
|
||||||
@ -109,7 +105,7 @@ namespace Loader {
|
|||||||
* Calling this function prior 'start()' enables the virtualization
|
* Calling this function prior 'start()' enables the virtualization
|
||||||
* of the nitpicker session interface.
|
* of the nitpicker session interface.
|
||||||
*/
|
*/
|
||||||
virtual void constrain_geometry(int width, int height) = 0;
|
virtual void constrain_geometry(Area size) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the parent view of the subsystem's view.
|
* Set the parent view of the subsystem's view.
|
||||||
@ -148,18 +144,14 @@ namespace Loader {
|
|||||||
Native_pd_args const &pd_args = Native_pd_args()) = 0;
|
Native_pd_args const &pd_args = Native_pd_args()) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return first nitpicker view created by the loaded subsystem
|
* Set view geometry and buffer offset
|
||||||
*
|
|
||||||
* \throw View_does_not_exist
|
|
||||||
*/
|
*/
|
||||||
virtual Nitpicker::View_capability view() = 0;
|
virtual void view_geometry(Rect rect, Point offset) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return view geometry as initialized by the loaded subsystem
|
* Return view size as initialized by the loaded subsystem
|
||||||
*
|
|
||||||
* \throw View_does_not_exist
|
|
||||||
*/
|
*/
|
||||||
virtual View_geometry view_geometry() = 0;
|
virtual Area view_size() const = 0;
|
||||||
|
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
@ -172,16 +164,18 @@ namespace Loader {
|
|||||||
GENODE_TYPE_LIST(Rom_module_does_not_exist),
|
GENODE_TYPE_LIST(Rom_module_does_not_exist),
|
||||||
Name const &);
|
Name const &);
|
||||||
GENODE_RPC(Rpc_ram_quota, void, ram_quota, size_t);
|
GENODE_RPC(Rpc_ram_quota, void, ram_quota, size_t);
|
||||||
GENODE_RPC(Rpc_constrain_geometry, void, constrain_geometry, int, int);
|
GENODE_RPC(Rpc_constrain_geometry, void, constrain_geometry, Area);
|
||||||
GENODE_RPC(Rpc_parent_view, void, parent_view, Nitpicker::View_capability);
|
GENODE_RPC(Rpc_parent_view, void, parent_view, Nitpicker::View_capability);
|
||||||
GENODE_RPC(Rpc_view_ready_sigh, void, view_ready_sigh, Signal_context_capability);
|
GENODE_RPC(Rpc_view_ready_sigh, void, view_ready_sigh, Signal_context_capability);
|
||||||
GENODE_RPC(Rpc_fault_sigh, void, fault_sigh, Signal_context_capability);
|
GENODE_RPC(Rpc_fault_sigh, void, fault_sigh, Signal_context_capability);
|
||||||
GENODE_RPC_THROW(Rpc_start, void, start,
|
GENODE_RPC_THROW(Rpc_start, void, start,
|
||||||
GENODE_TYPE_LIST(Rom_module_does_not_exist),
|
GENODE_TYPE_LIST(Rom_module_does_not_exist),
|
||||||
Name const &, Name const &, Native_pd_args const &);
|
Name const &, Name const &, Native_pd_args const &);
|
||||||
GENODE_RPC_THROW(Rpc_view, Nitpicker::View_capability, view,
|
GENODE_RPC_THROW(Rpc_view_geometry, void, view_geometry,
|
||||||
|
GENODE_TYPE_LIST(View_does_not_exist),
|
||||||
|
Rect, Point);
|
||||||
|
GENODE_RPC_THROW(Rpc_view_size, Area, view_size,
|
||||||
GENODE_TYPE_LIST(View_does_not_exist));
|
GENODE_TYPE_LIST(View_does_not_exist));
|
||||||
GENODE_RPC(Rpc_view_geometry, View_geometry, view_geometry);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'GENODE_RPC_INTERFACE' declaration done manually
|
* 'GENODE_RPC_INTERFACE' declaration done manually
|
||||||
@ -191,17 +185,17 @@ namespace Loader {
|
|||||||
* construct the type list by hand using nested type tuples instead
|
* construct the type list by hand using nested type tuples instead
|
||||||
* of employing the convenience macro 'GENODE_RPC_INTERFACE'.
|
* of employing the convenience macro 'GENODE_RPC_INTERFACE'.
|
||||||
*/
|
*/
|
||||||
typedef Meta::Type_tuple<Rpc_alloc_rom_module,
|
typedef Type_tuple<Rpc_alloc_rom_module,
|
||||||
Meta::Type_tuple<Rpc_commit_rom_module,
|
Type_tuple<Rpc_commit_rom_module,
|
||||||
Meta::Type_tuple<Rpc_ram_quota,
|
Type_tuple<Rpc_ram_quota,
|
||||||
Meta::Type_tuple<Rpc_constrain_geometry,
|
Type_tuple<Rpc_constrain_geometry,
|
||||||
Meta::Type_tuple<Rpc_parent_view,
|
Type_tuple<Rpc_parent_view,
|
||||||
Meta::Type_tuple<Rpc_view_ready_sigh,
|
Type_tuple<Rpc_view_ready_sigh,
|
||||||
Meta::Type_tuple<Rpc_fault_sigh,
|
Type_tuple<Rpc_fault_sigh,
|
||||||
Meta::Type_tuple<Rpc_start,
|
Type_tuple<Rpc_start,
|
||||||
Meta::Type_tuple<Rpc_view,
|
Type_tuple<Rpc_view_geometry,
|
||||||
Meta::Type_tuple<Rpc_view_geometry,
|
Type_tuple<Rpc_view_size,
|
||||||
Meta::Empty>
|
Genode::Meta::Empty>
|
||||||
> > > > > > > > > Rpc_functions;
|
> > > > > > > > > Rpc_functions;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -29,80 +29,78 @@ namespace Input {
|
|||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
struct Transformer
|
typedef Genode::Point<> Motion_delta;
|
||||||
{
|
|
||||||
struct Delta { int const x, y; };
|
|
||||||
|
|
||||||
virtual Delta delta() = 0;
|
class Session_component;
|
||||||
};
|
|
||||||
|
|
||||||
class Session_component : public Rpc_object<Session>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
Session_client _real_input;
|
|
||||||
Transformer &_transformer;
|
|
||||||
Event * const _ev_buf;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
Session_component(Session_capability real_input,
|
|
||||||
Transformer &transformer)
|
|
||||||
:
|
|
||||||
_real_input(real_input), _transformer(transformer),
|
|
||||||
_ev_buf(env()->rm_session()->attach(_real_input.dataspace()))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor
|
|
||||||
*/
|
|
||||||
~Session_component() { env()->rm_session()->detach(_ev_buf); }
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************
|
|
||||||
** Input session interface **
|
|
||||||
*****************************/
|
|
||||||
|
|
||||||
Dataspace_capability dataspace() override { return _real_input.dataspace(); }
|
|
||||||
|
|
||||||
bool is_pending() const override { return _real_input.is_pending(); }
|
|
||||||
|
|
||||||
int flush() override
|
|
||||||
{
|
|
||||||
/* translate mouse position to child's coordinate system */
|
|
||||||
Transformer::Delta delta = _transformer.delta();
|
|
||||||
|
|
||||||
int const num_ev = _real_input.flush();
|
|
||||||
for (int i = 0; i < num_ev; i++) {
|
|
||||||
|
|
||||||
Input::Event &ev = _ev_buf[i];
|
|
||||||
|
|
||||||
if ((ev.type() == Input::Event::MOTION)
|
|
||||||
|| (ev.type() == Input::Event::WHEEL)
|
|
||||||
|| (ev.code() == Input::BTN_LEFT)
|
|
||||||
|| (ev.code() == Input::BTN_RIGHT)
|
|
||||||
|| (ev.code() == Input::BTN_MIDDLE)) {
|
|
||||||
|
|
||||||
ev = Input::Event(ev.type(),
|
|
||||||
ev.code(),
|
|
||||||
ev.ax() - delta.x,
|
|
||||||
ev.ay() - delta.y,
|
|
||||||
ev.rx(),
|
|
||||||
ev.ry());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return num_ev;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sigh(Signal_context_capability sigh) override
|
|
||||||
{
|
|
||||||
_real_input.sigh(sigh);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Input::Session_component : public Rpc_object<Session>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Session_client _real_input;
|
||||||
|
Motion_delta &_motion_delta;
|
||||||
|
Event * const _ev_buf;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
Session_component(Session_capability real_input,
|
||||||
|
Motion_delta &motion_delta)
|
||||||
|
:
|
||||||
|
_real_input(real_input), _motion_delta(motion_delta),
|
||||||
|
_ev_buf(env()->rm_session()->attach(_real_input.dataspace()))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
~Session_component() { env()->rm_session()->detach(_ev_buf); }
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************
|
||||||
|
** Input session interface **
|
||||||
|
*****************************/
|
||||||
|
|
||||||
|
Dataspace_capability dataspace() override { return _real_input.dataspace(); }
|
||||||
|
|
||||||
|
bool is_pending() const override { return _real_input.is_pending(); }
|
||||||
|
|
||||||
|
int flush() override
|
||||||
|
{
|
||||||
|
/* translate mouse position to child's coordinate system */
|
||||||
|
Motion_delta const delta = _motion_delta;
|
||||||
|
|
||||||
|
int const num_ev = _real_input.flush();
|
||||||
|
for (int i = 0; i < num_ev; i++) {
|
||||||
|
|
||||||
|
Input::Event &ev = _ev_buf[i];
|
||||||
|
|
||||||
|
if ((ev.type() == Input::Event::MOTION)
|
||||||
|
|| (ev.type() == Input::Event::WHEEL)
|
||||||
|
|| (ev.code() == Input::BTN_LEFT)
|
||||||
|
|| (ev.code() == Input::BTN_RIGHT)
|
||||||
|
|| (ev.code() == Input::BTN_MIDDLE)) {
|
||||||
|
|
||||||
|
ev = Input::Event(ev.type(),
|
||||||
|
ev.code(),
|
||||||
|
ev.ax() + delta.x(),
|
||||||
|
ev.ay() + delta.y(),
|
||||||
|
ev.rx(),
|
||||||
|
ev.ry());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_ev;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sigh(Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
_real_input.sigh(sigh);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* _INPUT_H_ */
|
#endif /* _INPUT_H_ */
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <loader_session/loader_session.h>
|
#include <loader_session/loader_session.h>
|
||||||
#include <cap_session/connection.h>
|
#include <cap_session/connection.h>
|
||||||
#include <nitpicker_view/capability.h>
|
|
||||||
#include <root/component.h>
|
#include <root/component.h>
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
@ -33,395 +32,397 @@ namespace Loader {
|
|||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
class Session_component;
|
||||||
|
class Root;
|
||||||
|
}
|
||||||
|
|
||||||
class Session_component : public Rpc_object<Session>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
struct Local_rom_service : Service
|
class Loader::Session_component : public Rpc_object<Session>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct Local_rom_service : Service
|
||||||
|
{
|
||||||
|
Rpc_entrypoint &_ep;
|
||||||
|
Allocator &_md_alloc;
|
||||||
|
Parent_service _parent_rom_service;
|
||||||
|
Rom_module_registry &_rom_modules;
|
||||||
|
Lock _lock;
|
||||||
|
List<Rom_session_component> _rom_sessions;
|
||||||
|
|
||||||
|
void _close(Rom_session_component *rom)
|
||||||
{
|
{
|
||||||
Rpc_entrypoint &_ep;
|
_ep.dissolve(rom);
|
||||||
Allocator &_md_alloc;
|
_rom_sessions.remove(rom);
|
||||||
Parent_service _parent_rom_service;
|
destroy(&_md_alloc, rom);
|
||||||
Rom_module_registry &_rom_modules;
|
|
||||||
Lock _lock;
|
|
||||||
List<Rom_session_component> _rom_sessions;
|
|
||||||
|
|
||||||
void _close(Rom_session_component *rom)
|
|
||||||
{
|
|
||||||
_ep.dissolve(rom);
|
|
||||||
_rom_sessions.remove(rom);
|
|
||||||
destroy(&_md_alloc, rom);
|
|
||||||
}
|
|
||||||
|
|
||||||
Local_rom_service(Rpc_entrypoint &ep,
|
|
||||||
Allocator &md_alloc,
|
|
||||||
Rom_module_registry &rom_modules)
|
|
||||||
:
|
|
||||||
Service("virtual_rom"),
|
|
||||||
_ep(ep),
|
|
||||||
_md_alloc(md_alloc),
|
|
||||||
_parent_rom_service(Rom_session::service_name()),
|
|
||||||
_rom_modules(rom_modules)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
~Local_rom_service()
|
|
||||||
{
|
|
||||||
Lock::Guard guard(_lock);
|
|
||||||
|
|
||||||
while (_rom_sessions.first()) {
|
|
||||||
_close(_rom_sessions.first()); }
|
|
||||||
}
|
|
||||||
|
|
||||||
Genode::Session_capability session(char const *args,
|
|
||||||
Affinity const &affinity)
|
|
||||||
{
|
|
||||||
/* try to find ROM module at local ROM service */
|
|
||||||
try {
|
|
||||||
Lock::Guard guard(_lock);
|
|
||||||
|
|
||||||
char name[Session::Name::MAX_SIZE];
|
|
||||||
|
|
||||||
/* extract filename from session arguments */
|
|
||||||
Arg_string::find_arg(args, "filename")
|
|
||||||
.string(name, sizeof(name), "");
|
|
||||||
|
|
||||||
Rom_module &module = _rom_modules.lookup_and_lock(name);
|
|
||||||
|
|
||||||
Rom_session_component *rom = new (&_md_alloc)
|
|
||||||
Rom_session_component(module);
|
|
||||||
|
|
||||||
_rom_sessions.insert(rom);
|
|
||||||
|
|
||||||
return _ep.manage(rom);
|
|
||||||
|
|
||||||
} catch (...) { }
|
|
||||||
|
|
||||||
/* fall back to parent_rom_service */
|
|
||||||
return _parent_rom_service.session(args, affinity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void close(Session_capability session)
|
|
||||||
{
|
|
||||||
Lock::Guard guard(_lock);
|
|
||||||
|
|
||||||
Rpc_object_base *rom = _ep.lookup_and_lock(session);
|
|
||||||
|
|
||||||
Rom_session_component *component =
|
|
||||||
dynamic_cast<Rom_session_component *>(rom);
|
|
||||||
|
|
||||||
if (component) {
|
|
||||||
_close(component);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_parent_rom_service.close(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void upgrade(Session_capability session, const char *) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common base class of 'Local_cpu_service' and 'Local_rm_service'
|
|
||||||
*/
|
|
||||||
struct Intercepted_parent_service : Service
|
|
||||||
{
|
|
||||||
Signal_context_capability fault_sigh;
|
|
||||||
|
|
||||||
Intercepted_parent_service(char const *name) : Service(name) { }
|
|
||||||
|
|
||||||
void close(Session_capability session)
|
|
||||||
{
|
|
||||||
env()->parent()->close(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void upgrade(Session_capability session, const char *) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intercept CPU session requests to install default exception
|
|
||||||
* handler
|
|
||||||
*/
|
|
||||||
struct Local_cpu_service : Intercepted_parent_service
|
|
||||||
{
|
|
||||||
Local_cpu_service() : Intercepted_parent_service("CPU") { }
|
|
||||||
|
|
||||||
Genode::Session_capability session(char const *args,
|
|
||||||
Affinity const &affinity)
|
|
||||||
{
|
|
||||||
Capability<Cpu_session> cap = env()->parent()->session<Cpu_session>(args, affinity);
|
|
||||||
Cpu_session_client(cap).exception_handler(Thread_capability(), fault_sigh);
|
|
||||||
return cap;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intercept RM session requests to install default fault handler
|
|
||||||
*/
|
|
||||||
struct Local_rm_service : Intercepted_parent_service
|
|
||||||
{
|
|
||||||
Local_rm_service() : Intercepted_parent_service("RM") { }
|
|
||||||
|
|
||||||
Genode::Session_capability session(char const *args,
|
|
||||||
Affinity const &affinity)
|
|
||||||
{
|
|
||||||
Capability<Rm_session> cap = env()->parent()->session<Rm_session>(args, affinity);
|
|
||||||
Rm_session_client(cap).fault_handler(fault_sigh);
|
|
||||||
return cap;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Local_nitpicker_service : Service
|
|
||||||
{
|
|
||||||
Rpc_entrypoint &ep;
|
|
||||||
Allocator &_md_alloc;
|
|
||||||
|
|
||||||
int _max_width;
|
|
||||||
int _max_height;
|
|
||||||
Nitpicker::View_capability _parent_view;
|
|
||||||
|
|
||||||
Signal_context_capability view_ready_sigh;
|
|
||||||
|
|
||||||
Nitpicker::Session_component *open_session;
|
|
||||||
|
|
||||||
Local_nitpicker_service(Rpc_entrypoint &ep,
|
|
||||||
Allocator &md_alloc)
|
|
||||||
:
|
|
||||||
Service("virtual_nitpicker"),
|
|
||||||
ep(ep),
|
|
||||||
_md_alloc(md_alloc),
|
|
||||||
_max_width(-1),
|
|
||||||
_max_height(-1),
|
|
||||||
open_session(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
~Local_nitpicker_service()
|
|
||||||
{
|
|
||||||
if (!open_session)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ep.dissolve(open_session);
|
|
||||||
destroy(&_md_alloc, open_session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void constrain_geometry(int width, int height)
|
|
||||||
{
|
|
||||||
_max_width = width, _max_height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void parent_view(Nitpicker::View_capability view)
|
|
||||||
{
|
|
||||||
_parent_view = view;
|
|
||||||
}
|
|
||||||
|
|
||||||
Genode::Session_capability session(char const *args,
|
|
||||||
Affinity const &)
|
|
||||||
{
|
|
||||||
if (open_session)
|
|
||||||
throw Unavailable();
|
|
||||||
|
|
||||||
open_session = new (&_md_alloc)
|
|
||||||
Nitpicker::Session_component(ep,
|
|
||||||
_max_width,
|
|
||||||
_max_height,
|
|
||||||
_parent_view,
|
|
||||||
view_ready_sigh,
|
|
||||||
args);
|
|
||||||
|
|
||||||
return ep.manage(open_session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void upgrade(Genode::Session_capability session, const char *) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
enum { STACK_SIZE = 2*4096 };
|
|
||||||
|
|
||||||
size_t _ram_quota;
|
|
||||||
Ram_session_client_guard _ram_session_client;
|
|
||||||
Heap _md_alloc;
|
|
||||||
size_t _subsystem_ram_quota_limit;
|
|
||||||
Rpc_entrypoint _ep;
|
|
||||||
Service_registry _parent_services;
|
|
||||||
Rom_module_registry _rom_modules;
|
|
||||||
Local_rom_service _rom_service;
|
|
||||||
Local_cpu_service _cpu_service;
|
|
||||||
Local_rm_service _rm_service;
|
|
||||||
Local_nitpicker_service _nitpicker_service;
|
|
||||||
Signal_context_capability _fault_sigh;
|
|
||||||
Child *_child;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return virtual nitpicker session component
|
|
||||||
*/
|
|
||||||
Nitpicker::Session_component *_virtual_nitpicker_session()
|
|
||||||
{
|
|
||||||
if (!_nitpicker_service.open_session)
|
|
||||||
throw View_does_not_exist();
|
|
||||||
|
|
||||||
return _nitpicker_service.open_session;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
Local_rom_service(Rpc_entrypoint &ep,
|
||||||
|
Allocator &md_alloc,
|
||||||
/**
|
Rom_module_registry &rom_modules)
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
Session_component(size_t quota, Ram_session &ram, Cap_session &cap)
|
|
||||||
:
|
:
|
||||||
_ram_quota(quota),
|
Service("virtual_rom"),
|
||||||
_ram_session_client(env()->ram_session_cap(), _ram_quota),
|
_ep(ep),
|
||||||
_md_alloc(&_ram_session_client, env()->rm_session()),
|
_md_alloc(md_alloc),
|
||||||
_subsystem_ram_quota_limit(0),
|
_parent_rom_service(Rom_session::service_name()),
|
||||||
_ep(&cap, STACK_SIZE, "session_ep"),
|
_rom_modules(rom_modules)
|
||||||
_rom_modules(_ram_session_client, _md_alloc),
|
|
||||||
_rom_service(_ep, _md_alloc, _rom_modules),
|
|
||||||
_nitpicker_service(_ep, _md_alloc),
|
|
||||||
_child(0)
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Session_component()
|
~Local_rom_service()
|
||||||
{
|
{
|
||||||
if (_child)
|
Lock::Guard guard(_lock);
|
||||||
destroy(&_md_alloc, _child);
|
|
||||||
|
|
||||||
/*
|
while (_rom_sessions.first()) {
|
||||||
* The parent-service registry is populated by the 'Child'
|
_close(_rom_sessions.first()); }
|
||||||
* on demand. Revert those allocations.
|
|
||||||
*/
|
|
||||||
while (Service *service = _parent_services.find_by_server(0)) {
|
|
||||||
_parent_services.remove(service);
|
|
||||||
destroy(env()->heap(), service);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Genode::Session_capability session(char const *args,
|
||||||
/******************************
|
Affinity const &affinity)
|
||||||
** Loader session interface **
|
|
||||||
******************************/
|
|
||||||
|
|
||||||
Dataspace_capability alloc_rom_module(Name const &name, size_t size)
|
|
||||||
{
|
|
||||||
return _rom_modules.alloc_rom_module(name.string(), size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void commit_rom_module(Name const &name)
|
|
||||||
{
|
{
|
||||||
|
/* try to find ROM module at local ROM service */
|
||||||
try {
|
try {
|
||||||
_rom_modules.commit_rom_module(name.string()); }
|
Lock::Guard guard(_lock);
|
||||||
catch (Rom_module_registry::Lookup_failed) {
|
|
||||||
throw Rom_module_does_not_exist(); }
|
char name[Session::Name::MAX_SIZE];
|
||||||
|
|
||||||
|
/* extract filename from session arguments */
|
||||||
|
Arg_string::find_arg(args, "filename")
|
||||||
|
.string(name, sizeof(name), "");
|
||||||
|
|
||||||
|
Rom_module &module = _rom_modules.lookup_and_lock(name);
|
||||||
|
|
||||||
|
Rom_session_component *rom = new (&_md_alloc)
|
||||||
|
Rom_session_component(module);
|
||||||
|
|
||||||
|
_rom_sessions.insert(rom);
|
||||||
|
|
||||||
|
return _ep.manage(rom);
|
||||||
|
|
||||||
|
} catch (...) { }
|
||||||
|
|
||||||
|
/* fall back to parent_rom_service */
|
||||||
|
return _parent_rom_service.session(args, affinity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ram_quota(size_t quantum)
|
void close(Session_capability session)
|
||||||
{
|
{
|
||||||
_subsystem_ram_quota_limit = quantum;
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
|
Rpc_object_base *rom = _ep.lookup_and_lock(session);
|
||||||
|
|
||||||
|
Rom_session_component *component =
|
||||||
|
dynamic_cast<Rom_session_component *>(rom);
|
||||||
|
|
||||||
|
if (component) {
|
||||||
|
_close(component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parent_rom_service.close(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void constrain_geometry(int width, int height)
|
void upgrade(Session_capability session, const char *) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common base class of 'Local_cpu_service' and 'Local_rm_service'
|
||||||
|
*/
|
||||||
|
struct Intercepted_parent_service : Service
|
||||||
|
{
|
||||||
|
Signal_context_capability fault_sigh;
|
||||||
|
|
||||||
|
Intercepted_parent_service(char const *name) : Service(name) { }
|
||||||
|
|
||||||
|
void close(Session_capability session)
|
||||||
{
|
{
|
||||||
_nitpicker_service.constrain_geometry(width, height);
|
env()->parent()->close(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
void upgrade(Session_capability session, const char *) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intercept CPU session requests to install default exception
|
||||||
|
* handler
|
||||||
|
*/
|
||||||
|
struct Local_cpu_service : Intercepted_parent_service
|
||||||
|
{
|
||||||
|
Local_cpu_service() : Intercepted_parent_service("CPU") { }
|
||||||
|
|
||||||
|
Genode::Session_capability session(char const *args,
|
||||||
|
Affinity const &affinity)
|
||||||
|
{
|
||||||
|
Capability<Cpu_session> cap = env()->parent()->session<Cpu_session>(args, affinity);
|
||||||
|
Cpu_session_client(cap).exception_handler(Thread_capability(), fault_sigh);
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intercept RM session requests to install default fault handler
|
||||||
|
*/
|
||||||
|
struct Local_rm_service : Intercepted_parent_service
|
||||||
|
{
|
||||||
|
Local_rm_service() : Intercepted_parent_service("RM") { }
|
||||||
|
|
||||||
|
Genode::Session_capability session(char const *args,
|
||||||
|
Affinity const &affinity)
|
||||||
|
{
|
||||||
|
Capability<Rm_session> cap = env()->parent()->session<Rm_session>(args, affinity);
|
||||||
|
Rm_session_client(cap).fault_handler(fault_sigh);
|
||||||
|
return cap;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Local_nitpicker_service : Service
|
||||||
|
{
|
||||||
|
Rpc_entrypoint &_ep;
|
||||||
|
Ram_session &_ram;
|
||||||
|
Allocator &_md_alloc;
|
||||||
|
|
||||||
|
Area _max_size;
|
||||||
|
Nitpicker::View_capability _parent_view;
|
||||||
|
|
||||||
|
Signal_context_capability view_ready_sigh;
|
||||||
|
|
||||||
|
Nitpicker::Session_component *open_session;
|
||||||
|
|
||||||
|
Local_nitpicker_service(Rpc_entrypoint &ep, Ram_session &ram,
|
||||||
|
Allocator &md_alloc)
|
||||||
|
:
|
||||||
|
Service("virtual_nitpicker"),
|
||||||
|
_ep(ep),
|
||||||
|
_ram(ram),
|
||||||
|
_md_alloc(md_alloc),
|
||||||
|
open_session(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~Local_nitpicker_service()
|
||||||
|
{
|
||||||
|
if (!open_session)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_ep.dissolve(open_session);
|
||||||
|
destroy(&_md_alloc, open_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
void constrain_geometry(Area size)
|
||||||
|
{
|
||||||
|
_max_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parent_view(Nitpicker::View_capability view)
|
void parent_view(Nitpicker::View_capability view)
|
||||||
{
|
{
|
||||||
_nitpicker_service.parent_view(view);
|
_parent_view = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_ready_sigh(Signal_context_capability sigh)
|
Genode::Session_capability session(char const *args,
|
||||||
|
Affinity const &)
|
||||||
{
|
{
|
||||||
_nitpicker_service.view_ready_sigh = sigh;
|
if (open_session)
|
||||||
|
throw Unavailable();
|
||||||
|
|
||||||
|
open_session = new (&_md_alloc)
|
||||||
|
Nitpicker::Session_component(_ep,
|
||||||
|
_ram,
|
||||||
|
_max_size,
|
||||||
|
_parent_view,
|
||||||
|
view_ready_sigh,
|
||||||
|
args);
|
||||||
|
|
||||||
|
return _ep.manage(open_session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fault_sigh(Signal_context_capability sigh)
|
void upgrade(Genode::Session_capability session, const char *) { }
|
||||||
{
|
};
|
||||||
/*
|
|
||||||
* CPU exception handler for CPU sessions originating from the
|
|
||||||
* subsystem.
|
|
||||||
*/
|
|
||||||
_cpu_service.fault_sigh = sigh;
|
|
||||||
|
|
||||||
/*
|
enum { STACK_SIZE = 2*4096 };
|
||||||
* RM fault handler for RM sessions originating from the
|
|
||||||
* subsystem.
|
|
||||||
*/
|
|
||||||
_rm_service.fault_sigh = sigh;
|
|
||||||
|
|
||||||
/*
|
size_t _ram_quota;
|
||||||
* CPU exception and RM fault handler for the immediate child.
|
Ram_session_client_guard _ram_session_client;
|
||||||
*/
|
Heap _md_alloc;
|
||||||
_fault_sigh = sigh;
|
size_t _subsystem_ram_quota_limit;
|
||||||
}
|
Rpc_entrypoint _ep;
|
||||||
|
Service_registry _parent_services;
|
||||||
|
Rom_module_registry _rom_modules;
|
||||||
|
Local_rom_service _rom_service;
|
||||||
|
Local_cpu_service _cpu_service;
|
||||||
|
Local_rm_service _rm_service;
|
||||||
|
Local_nitpicker_service _nitpicker_service;
|
||||||
|
Signal_context_capability _fault_sigh;
|
||||||
|
Child *_child;
|
||||||
|
|
||||||
void start(Name const &binary_name, Name const &label,
|
/**
|
||||||
Genode::Native_pd_args const &pd_args)
|
* Return virtual nitpicker session component
|
||||||
{
|
*/
|
||||||
if (_child) {
|
Nitpicker::Session_component &_virtual_nitpicker_session() const
|
||||||
PWRN("cannot start subsystem twice");
|
{
|
||||||
return;
|
if (!_nitpicker_service.open_session)
|
||||||
}
|
throw View_does_not_exist();
|
||||||
|
|
||||||
size_t const ram_quota = (_subsystem_ram_quota_limit > 0) ?
|
return *_nitpicker_service.open_session;
|
||||||
min(_subsystem_ram_quota_limit, _ram_session_client.avail()) :
|
}
|
||||||
_ram_session_client.avail();
|
|
||||||
|
|
||||||
try {
|
public:
|
||||||
_child = new (&_md_alloc)
|
|
||||||
Child(binary_name.string(), label.string(),
|
|
||||||
pd_args, _ep, _ram_session_client,
|
|
||||||
ram_quota, _parent_services, _rom_service,
|
|
||||||
_cpu_service, _rm_service, _nitpicker_service,
|
|
||||||
_fault_sigh);
|
|
||||||
}
|
|
||||||
catch (Genode::Parent::Service_denied) {
|
|
||||||
throw Rom_module_does_not_exist(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
Nitpicker::View_capability view()
|
/**
|
||||||
{
|
* Constructor
|
||||||
return _virtual_nitpicker_session()->loader_view();
|
*/
|
||||||
}
|
Session_component(size_t quota, Ram_session &ram, Cap_session &cap)
|
||||||
|
:
|
||||||
|
_ram_quota(quota),
|
||||||
|
_ram_session_client(env()->ram_session_cap(), _ram_quota),
|
||||||
|
_md_alloc(&_ram_session_client, env()->rm_session()),
|
||||||
|
_subsystem_ram_quota_limit(0),
|
||||||
|
_ep(&cap, STACK_SIZE, "session_ep"),
|
||||||
|
_rom_modules(_ram_session_client, _md_alloc),
|
||||||
|
_rom_service(_ep, _md_alloc, _rom_modules),
|
||||||
|
_nitpicker_service(_ep, _ram_session_client, _md_alloc),
|
||||||
|
_child(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
View_geometry view_geometry()
|
~Session_component()
|
||||||
{
|
{
|
||||||
return _virtual_nitpicker_session()->loader_view_geometry();
|
if (_child)
|
||||||
}
|
destroy(&_md_alloc, _child);
|
||||||
};
|
|
||||||
|
|
||||||
|
/*
|
||||||
class Root : public Root_component<Session_component>
|
* The parent-service registry is populated by the 'Child'
|
||||||
{
|
* on demand. Revert those allocations.
|
||||||
private:
|
|
||||||
|
|
||||||
Ram_session &_ram;
|
|
||||||
Cap_session &_cap;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Session_component *_create_session(const char *args)
|
|
||||||
{
|
|
||||||
size_t quota =
|
|
||||||
Arg_string::find_arg(args, "ram_quota").long_value(0);
|
|
||||||
|
|
||||||
return new (md_alloc()) Session_component(quota, _ram, _cap);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* \param session_ep entry point for managing ram session objects
|
|
||||||
* \param md_alloc meta-data allocator to be used by root
|
|
||||||
* component
|
|
||||||
*/
|
*/
|
||||||
Root(Rpc_entrypoint &session_ep, Allocator &md_alloc,
|
while (Service *service = _parent_services.find_by_server(0)) {
|
||||||
Ram_session &ram, Cap_session &cap)
|
_parent_services.remove(service);
|
||||||
:
|
destroy(env()->heap(), service);
|
||||||
Root_component<Session_component>(&session_ep, &md_alloc),
|
}
|
||||||
_ram(ram), _cap(cap)
|
}
|
||||||
{ }
|
|
||||||
};
|
|
||||||
}
|
/******************************
|
||||||
|
** Loader session interface **
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
Dataspace_capability alloc_rom_module(Name const &name, size_t size) override
|
||||||
|
{
|
||||||
|
return _rom_modules.alloc_rom_module(name.string(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void commit_rom_module(Name const &name) override
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
_rom_modules.commit_rom_module(name.string()); }
|
||||||
|
catch (Rom_module_registry::Lookup_failed) {
|
||||||
|
throw Rom_module_does_not_exist(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void ram_quota(size_t quantum) override
|
||||||
|
{
|
||||||
|
_subsystem_ram_quota_limit = quantum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void constrain_geometry(Area size) override
|
||||||
|
{
|
||||||
|
_nitpicker_service.constrain_geometry(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void parent_view(Nitpicker::View_capability view) override
|
||||||
|
{
|
||||||
|
_nitpicker_service.parent_view(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void view_ready_sigh(Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
_nitpicker_service.view_ready_sigh = sigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fault_sigh(Signal_context_capability sigh) override
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* CPU exception handler for CPU sessions originating from the
|
||||||
|
* subsystem.
|
||||||
|
*/
|
||||||
|
_cpu_service.fault_sigh = sigh;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RM fault handler for RM sessions originating from the
|
||||||
|
* subsystem.
|
||||||
|
*/
|
||||||
|
_rm_service.fault_sigh = sigh;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU exception and RM fault handler for the immediate child.
|
||||||
|
*/
|
||||||
|
_fault_sigh = sigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start(Name const &binary_name, Name const &label,
|
||||||
|
Genode::Native_pd_args const &pd_args) override
|
||||||
|
{
|
||||||
|
if (_child) {
|
||||||
|
PWRN("cannot start subsystem twice");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t const ram_quota = (_subsystem_ram_quota_limit > 0) ?
|
||||||
|
min(_subsystem_ram_quota_limit, _ram_session_client.avail()) :
|
||||||
|
_ram_session_client.avail();
|
||||||
|
|
||||||
|
try {
|
||||||
|
_child = new (&_md_alloc)
|
||||||
|
Child(binary_name.string(), label.string(),
|
||||||
|
pd_args, _ep, _ram_session_client,
|
||||||
|
ram_quota, _parent_services, _rom_service,
|
||||||
|
_cpu_service, _rm_service, _nitpicker_service,
|
||||||
|
_fault_sigh);
|
||||||
|
}
|
||||||
|
catch (Genode::Parent::Service_denied) {
|
||||||
|
throw Rom_module_does_not_exist(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void view_geometry(Rect rect, Point offset) override
|
||||||
|
{
|
||||||
|
_virtual_nitpicker_session().loader_view_geometry(rect, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
Area view_size() const override
|
||||||
|
{
|
||||||
|
return _virtual_nitpicker_session().loader_view_size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Loader::Root : public Root_component<Session_component>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Ram_session &_ram;
|
||||||
|
Cap_session &_cap;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Session_component *_create_session(const char *args)
|
||||||
|
{
|
||||||
|
size_t quota =
|
||||||
|
Arg_string::find_arg(args, "ram_quota").long_value(0);
|
||||||
|
|
||||||
|
return new (md_alloc()) Session_component(quota, _ram, _cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* \param session_ep entry point for managing ram session objects
|
||||||
|
* \param md_alloc meta-data allocator to be used by root
|
||||||
|
* component
|
||||||
|
*/
|
||||||
|
Root(Rpc_entrypoint &session_ep, Allocator &md_alloc,
|
||||||
|
Ram_session &ram, Cap_session &cap)
|
||||||
|
:
|
||||||
|
Root_component<Session_component>(&session_ep, &md_alloc),
|
||||||
|
_ram(ram), _cap(cap)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
@ -19,295 +19,259 @@
|
|||||||
#include <util/arg_string.h>
|
#include <util/arg_string.h>
|
||||||
#include <util/misc_math.h>
|
#include <util/misc_math.h>
|
||||||
#include <base/signal.h>
|
#include <base/signal.h>
|
||||||
|
#include <os/attached_ram_dataspace.h>
|
||||||
#include <nitpicker_session/connection.h>
|
#include <nitpicker_session/connection.h>
|
||||||
#include <nitpicker_session/nitpicker_session.h>
|
#include <nitpicker_session/nitpicker_session.h>
|
||||||
#include <nitpicker_view/client.h>
|
|
||||||
|
|
||||||
/* local includes */
|
/* local includes */
|
||||||
#include <input.h>
|
#include <input.h>
|
||||||
|
|
||||||
namespace Nitpicker {
|
namespace Nitpicker { class Session_component; }
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View interface provided to the loader client
|
|
||||||
*/
|
|
||||||
class Loader_view_component : public Rpc_object<View>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
View_client _view; /* wrapped view */
|
|
||||||
|
|
||||||
int _x, _y, _buf_x, _buf_y;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
Loader_view_component(View_capability view_cap)
|
|
||||||
:
|
|
||||||
_view(view_cap), _x(0), _y(0), _buf_x(0), _buf_y(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
int x() const { return _x; }
|
|
||||||
int y() const { return _y; }
|
|
||||||
int buf_x() const { return _buf_x; }
|
|
||||||
int buf_y() const { return _buf_y; }
|
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
class Nitpicker::Session_component : public Genode::Rpc_object<Session>
|
||||||
** Nitpicker view interface **
|
{
|
||||||
******************************/
|
private:
|
||||||
|
|
||||||
int viewport(int x, int y, int w, int h,
|
/**
|
||||||
int buf_x, int buf_y, bool redraw)
|
* Signal handler to be notified once the geometry of the view is
|
||||||
{
|
* known.
|
||||||
_x = x, _y = y, _buf_x = buf_x, _buf_y = buf_y;
|
*/
|
||||||
|
Genode::Signal_context_capability _view_ready_sigh;
|
||||||
|
|
||||||
return _view.viewport(x, y, w, h, buf_x, buf_y, redraw);
|
Genode::Rpc_entrypoint &_ep;
|
||||||
|
|
||||||
|
Area _max_size;
|
||||||
|
|
||||||
|
Nitpicker::Connection _nitpicker;
|
||||||
|
|
||||||
|
View_handle _parent_view_handle;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Physical view
|
||||||
|
*/
|
||||||
|
View_handle _view_handle;
|
||||||
|
Rect _view_geometry;
|
||||||
|
Point _view_offset;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Geometry of virtual view presented to the loaded subsystem
|
||||||
|
*/
|
||||||
|
Rect _virt_view_geometry;
|
||||||
|
Point _virt_view_offset;
|
||||||
|
bool _virt_view_geometry_defined = false;
|
||||||
|
|
||||||
|
Input::Motion_delta _motion_delta;
|
||||||
|
|
||||||
|
Input::Session_component _proxy_input;
|
||||||
|
Input::Session_capability _proxy_input_cap;
|
||||||
|
|
||||||
|
static long _session_arg(const char *arg, const char *key) {
|
||||||
|
return Genode::Arg_string::find_arg(arg, key).long_value(0); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command buffer
|
||||||
|
*/
|
||||||
|
typedef Nitpicker::Session::Command_buffer Command_buffer;
|
||||||
|
Genode::Attached_ram_dataspace _command_ds;
|
||||||
|
Command_buffer &_command_buffer = *_command_ds.local_addr<Command_buffer>();
|
||||||
|
|
||||||
|
void _propagate_view_offset()
|
||||||
|
{
|
||||||
|
_nitpicker.enqueue<Command::Offset>(_view_handle,
|
||||||
|
_view_offset + _virt_view_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _update_motion_delta()
|
||||||
|
{
|
||||||
|
_motion_delta = _virt_view_geometry.p1() - _view_geometry.p1();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _execute_command(Command const &command)
|
||||||
|
{
|
||||||
|
switch (command.opcode) {
|
||||||
|
|
||||||
|
case Command::OP_GEOMETRY:
|
||||||
|
{
|
||||||
|
_virt_view_geometry = command.geometry.rect;
|
||||||
|
|
||||||
|
if (!_virt_view_geometry_defined)
|
||||||
|
Genode::Signal_transmitter(_view_ready_sigh).submit();
|
||||||
|
|
||||||
|
_virt_view_geometry_defined = true;
|
||||||
|
|
||||||
|
_update_motion_delta();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_OFFSET:
|
||||||
|
{
|
||||||
|
_virt_view_offset = command.offset.offset;
|
||||||
|
_propagate_view_offset();
|
||||||
|
_nitpicker.execute();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_TO_FRONT:
|
||||||
|
{
|
||||||
|
_nitpicker.enqueue<Command::To_front>(_view_handle, _parent_view_handle);
|
||||||
|
_nitpicker.execute();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_TO_BACK:
|
||||||
|
{
|
||||||
|
PDBG("OP_TO_BACK not implemented");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_BACKGROUND:
|
||||||
|
{
|
||||||
|
PDBG("OP_BACKGROUND not implemented");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_TITLE:
|
||||||
|
{
|
||||||
|
_nitpicker.enqueue(command);
|
||||||
|
_nitpicker.execute();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Command::OP_NOP:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int stack(View_capability neighbor_cap, bool behind, bool redraw)
|
public:
|
||||||
{
|
|
||||||
return _view.stack(neighbor_cap, behind, redraw);
|
|
||||||
}
|
|
||||||
|
|
||||||
int title(Title const &title)
|
/**
|
||||||
{
|
* Constructor
|
||||||
return _view.title(title.string());
|
*/
|
||||||
}
|
Session_component(Genode::Rpc_entrypoint &ep,
|
||||||
};
|
Genode::Ram_session &ram,
|
||||||
|
Area max_size,
|
||||||
|
Nitpicker::View_capability parent_view,
|
||||||
|
Genode::Signal_context_capability view_ready_sigh,
|
||||||
|
const char *args)
|
||||||
|
:
|
||||||
|
_view_ready_sigh(view_ready_sigh),
|
||||||
|
_ep(ep),
|
||||||
|
_max_size(max_size),
|
||||||
|
|
||||||
|
/* import parent view */
|
||||||
|
_parent_view_handle(_nitpicker.view_handle(parent_view)),
|
||||||
|
|
||||||
|
/* create nitpicker view */
|
||||||
|
_view_handle(_nitpicker.create_view(_parent_view_handle)),
|
||||||
|
|
||||||
|
_proxy_input(_nitpicker.input_session(), _motion_delta),
|
||||||
|
_proxy_input_cap(_ep.manage(&_proxy_input)),
|
||||||
|
|
||||||
|
_command_ds(&ram, sizeof(Command_buffer))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*********************************
|
||||||
* View interface exposed to the subsystem
|
** Nitpicker session interface **
|
||||||
*/
|
*********************************/
|
||||||
class View_component : public Rpc_object<View>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
View_client _view; /* wrapped view */
|
Framebuffer::Session_capability framebuffer_session() override
|
||||||
Signal_context_capability _sigh;
|
{
|
||||||
bool _viewport_initialized;
|
return _nitpicker.framebuffer_session();
|
||||||
int _x, _y, _w, _h, _buf_x, _buf_y;
|
}
|
||||||
|
|
||||||
public:
|
Input::Session_capability input_session() override
|
||||||
|
{
|
||||||
|
return _proxy_input_cap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
View_handle create_view(View_handle) override
|
||||||
* Constructor
|
{
|
||||||
*/
|
return View_handle(1);
|
||||||
View_component(View_capability view_cap,
|
}
|
||||||
Signal_context_capability sigh)
|
|
||||||
:
|
|
||||||
_view(view_cap), _sigh(sigh), _viewport_initialized(false),
|
|
||||||
_x(0), _y(0), _w(0), _h(0), _buf_x(0), _buf_y(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
int x() const { return _x; }
|
void destroy_view(View_handle view) override { }
|
||||||
int y() const { return _y; }
|
|
||||||
int w() const { return _w; }
|
|
||||||
int h() const { return _h; }
|
|
||||||
int buf_x() const { return _buf_x; }
|
|
||||||
int buf_y() const { return _buf_y; }
|
|
||||||
|
|
||||||
|
View_handle view_handle(View_capability, View_handle) override
|
||||||
|
{
|
||||||
|
return View_handle();
|
||||||
|
}
|
||||||
|
|
||||||
/******************************
|
View_capability view_capability(View_handle) override
|
||||||
** Nitpicker view interface **
|
{
|
||||||
******************************/
|
return View_capability();
|
||||||
|
}
|
||||||
|
|
||||||
int viewport(int x, int y, int w, int h,
|
void release_view_handle(View_handle) override { }
|
||||||
int buf_x, int buf_y, bool redraw)
|
|
||||||
{
|
|
||||||
_x = x; _y = y; _w = w; _h = h;
|
|
||||||
_buf_x = buf_x; _buf_y = buf_y;
|
|
||||||
|
|
||||||
if (_viewport_initialized)
|
Genode::Dataspace_capability command_dataspace() override
|
||||||
return 0;
|
{
|
||||||
|
return _command_ds.cap();
|
||||||
|
}
|
||||||
|
|
||||||
_viewport_initialized = true;
|
void execute() override
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < _command_buffer.num(); i++)
|
||||||
|
_execute_command(_command_buffer.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
/* hide the view and let the application set the viewport */
|
Framebuffer::Mode mode() override
|
||||||
int result = _view.viewport(0, 0, 0, 0, 0, 0, true);
|
{
|
||||||
|
int mode_width = _max_size.valid() ?
|
||||||
|
_max_size.w() :
|
||||||
|
_nitpicker.mode().width();
|
||||||
|
|
||||||
/* signal readyness of the view */
|
int mode_height = _max_size.valid() ?
|
||||||
if (_sigh.valid())
|
_max_size.h() :
|
||||||
Signal_transmitter(_sigh).submit();
|
_nitpicker.mode().height();
|
||||||
|
|
||||||
return result;
|
return Framebuffer::Mode(mode_width, mode_height,
|
||||||
}
|
_nitpicker.mode().format());
|
||||||
|
}
|
||||||
|
|
||||||
int stack(View_capability neighbor_cap, bool behind, bool redraw)
|
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Only one child view is supported, so the stack request can
|
|
||||||
* be ignored.
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int title(Title const &title)
|
void buffer(Framebuffer::Mode mode, bool use_alpha) override
|
||||||
{
|
{
|
||||||
return _view.title(title.string());
|
_nitpicker.buffer(mode, use_alpha);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
void focus(Genode::Capability<Session>) override { }
|
||||||
|
|
||||||
class Session_component : public Rpc_object<Session>,
|
/**
|
||||||
public Input::Transformer
|
* Return geometry of loader view
|
||||||
{
|
*/
|
||||||
private:
|
Area loader_view_size() const
|
||||||
|
{
|
||||||
|
int const width = _max_size.valid()
|
||||||
|
? Genode::min(_virt_view_geometry.w(), _max_size.w())
|
||||||
|
: _virt_view_geometry.w();
|
||||||
|
|
||||||
Rpc_entrypoint &_ep;
|
int const height = _max_size.valid()
|
||||||
|
? Genode::min(_virt_view_geometry.h(), _max_size.h())
|
||||||
|
: _virt_view_geometry.h();
|
||||||
|
|
||||||
int _max_width;
|
return Area(width, height);
|
||||||
int _max_height;
|
}
|
||||||
|
|
||||||
Nitpicker::Connection _nitpicker;
|
/**
|
||||||
View_capability _nitpicker_view;
|
* Define geometry of loader view
|
||||||
|
*/
|
||||||
|
void loader_view_geometry(Rect rect, Point offset)
|
||||||
|
{
|
||||||
|
typedef Nitpicker::Session::Command Command;
|
||||||
|
|
||||||
View_component _proxy_view;
|
_view_geometry = rect;
|
||||||
View_capability _proxy_view_cap;
|
_view_offset = offset;
|
||||||
|
|
||||||
Loader_view_component _loader_view;
|
_propagate_view_offset();
|
||||||
View_capability _loader_view_cap;
|
_nitpicker.enqueue<Command::Geometry>(_view_handle, _view_geometry);
|
||||||
|
_nitpicker.enqueue<Command::To_front>(_view_handle, _parent_view_handle);
|
||||||
|
_nitpicker.execute();
|
||||||
|
|
||||||
Input::Session_component _proxy_input;
|
_update_motion_delta();
|
||||||
Input::Session_capability _proxy_input_cap;
|
}
|
||||||
|
};
|
||||||
static long _session_arg(const char *arg, const char *key) {
|
|
||||||
return Arg_string::find_arg(arg, key).long_value(0); }
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
Session_component(Rpc_entrypoint &ep,
|
|
||||||
int max_width,
|
|
||||||
int max_height,
|
|
||||||
Nitpicker::View_capability parent_view,
|
|
||||||
Signal_context_capability view_ready_sigh,
|
|
||||||
const char *args)
|
|
||||||
:
|
|
||||||
_ep(ep),
|
|
||||||
|
|
||||||
_max_width(max_width),
|
|
||||||
_max_height(max_height),
|
|
||||||
|
|
||||||
/* create Nitpicker view */
|
|
||||||
_nitpicker_view(_nitpicker.create_view(parent_view)),
|
|
||||||
|
|
||||||
/* create proxy view component for the child */
|
|
||||||
_proxy_view(_nitpicker_view, view_ready_sigh),
|
|
||||||
_proxy_view_cap(_ep.manage(&_proxy_view)),
|
|
||||||
|
|
||||||
/* create view component accessed by the loader client */
|
|
||||||
_loader_view(_nitpicker_view),
|
|
||||||
_loader_view_cap(_ep.manage(&_loader_view)),
|
|
||||||
|
|
||||||
_proxy_input(_nitpicker.input_session(), *this),
|
|
||||||
_proxy_input_cap(_ep.manage(&_proxy_input))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************
|
|
||||||
** Nitpicker session interface **
|
|
||||||
*********************************/
|
|
||||||
|
|
||||||
Framebuffer::Session_capability framebuffer_session() override
|
|
||||||
{
|
|
||||||
return _nitpicker.framebuffer_session();
|
|
||||||
}
|
|
||||||
|
|
||||||
Input::Session_capability input_session() override
|
|
||||||
{
|
|
||||||
return _proxy_input_cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
View_capability create_view(View_capability) override
|
|
||||||
{
|
|
||||||
return _proxy_view_cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy_view(View_capability view) override
|
|
||||||
{
|
|
||||||
_nitpicker.destroy_view(_nitpicker_view);
|
|
||||||
}
|
|
||||||
|
|
||||||
int background(View_capability view) override
|
|
||||||
{
|
|
||||||
/* not forwarding to real nitpicker session */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Framebuffer::Mode mode() override
|
|
||||||
{
|
|
||||||
int mode_width = (_max_width > -1) ?
|
|
||||||
_max_width :
|
|
||||||
_nitpicker.mode().width();
|
|
||||||
|
|
||||||
int mode_height = (_max_height > -1) ?
|
|
||||||
_max_height :
|
|
||||||
_nitpicker.mode().height();
|
|
||||||
|
|
||||||
return Framebuffer::Mode(mode_width, mode_height,
|
|
||||||
_nitpicker.mode().format());
|
|
||||||
}
|
|
||||||
|
|
||||||
void buffer(Framebuffer::Mode mode, bool use_alpha) override
|
|
||||||
{
|
|
||||||
_nitpicker.buffer(mode, use_alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
void focus(Capability<Session>) override { }
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************
|
|
||||||
** Input::Transformer interface **
|
|
||||||
**********************************/
|
|
||||||
|
|
||||||
Input::Transformer::Delta delta()
|
|
||||||
{
|
|
||||||
/* translate mouse position to child's coordinate system */
|
|
||||||
Input::Transformer::Delta result = {
|
|
||||||
_loader_view.x() + _loader_view.buf_x() +
|
|
||||||
_proxy_view.x() + _proxy_view.buf_x(),
|
|
||||||
_loader_view.y() + _loader_view.buf_y() +
|
|
||||||
_proxy_view.y() + _proxy_view.buf_y() };
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the client-specific wrapper view for the Nitpicker view
|
|
||||||
* showing the child content
|
|
||||||
*/
|
|
||||||
View_capability loader_view() { return _loader_view_cap; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return geometry of loader view
|
|
||||||
*/
|
|
||||||
Loader::Session::View_geometry loader_view_geometry()
|
|
||||||
{
|
|
||||||
int view_width = (_max_width > -1) ?
|
|
||||||
min(_proxy_view.w(), _max_width) :
|
|
||||||
_proxy_view.w();
|
|
||||||
|
|
||||||
int view_height = (_max_height > -1) ?
|
|
||||||
min(_proxy_view.h(), _max_height) :
|
|
||||||
_proxy_view.h();
|
|
||||||
|
|
||||||
Loader::Session::View_geometry result(
|
|
||||||
view_width,
|
|
||||||
view_height,
|
|
||||||
_proxy_view.buf_x(),
|
|
||||||
_proxy_view.buf_y());
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _NITPICKER_H_ */
|
#endif /* _NITPICKER_H_ */
|
||||||
|
@ -14,18 +14,16 @@
|
|||||||
#include <base/printf.h>
|
#include <base/printf.h>
|
||||||
#include <base/sleep.h>
|
#include <base/sleep.h>
|
||||||
#include <loader_session/connection.h>
|
#include <loader_session/connection.h>
|
||||||
#include <nitpicker_session/client.h>
|
|
||||||
#include <timer_session/connection.h>
|
#include <timer_session/connection.h>
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
Loader::Connection loader(8*1024*1024);
|
Loader::Connection loader(8*1024*1024);
|
||||||
|
|
||||||
static Signal_receiver sig_rec;
|
static Genode::Signal_receiver sig_rec;
|
||||||
|
|
||||||
Signal_context sig_ctx;
|
Genode::Signal_context sig_ctx;
|
||||||
|
|
||||||
loader.view_ready_sigh(sig_rec.manage(&sig_ctx));
|
loader.view_ready_sigh(sig_rec.manage(&sig_ctx));
|
||||||
|
|
||||||
@ -33,31 +31,22 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
sig_rec.wait_for_signal();
|
sig_rec.wait_for_signal();
|
||||||
|
|
||||||
Loader::Session::View_geometry geometry = loader.view_geometry();
|
Loader::Area size = loader.view_size();
|
||||||
Nitpicker::View_capability view_cap = loader.view();
|
|
||||||
|
|
||||||
static Nitpicker_connection nitpicker;
|
|
||||||
|
|
||||||
Nitpicker::Session::View_handle view_handle = nitpicker.view_handle(view_cap);
|
|
||||||
|
|
||||||
nitpicker.enqueue<Nitpicker::Session::Command::To_front>(view_handle);
|
|
||||||
nitpicker.execute();
|
|
||||||
|
|
||||||
Timer::Connection timer;
|
Timer::Connection timer;
|
||||||
|
|
||||||
while(1) {
|
while (1) {
|
||||||
|
|
||||||
for (unsigned i = 0; i < 10; i++) {
|
for (unsigned i = 0; i < 10; i++) {
|
||||||
|
|
||||||
Nitpicker::Rect rect(Nitpicker::Point(50*i, 50*i),
|
loader.view_geometry(Loader::Rect(Loader::Point(50*i, 50*i), size),
|
||||||
Nitpicker::Area(geometry.width, geometry.height));
|
Loader::Point(0, 0));
|
||||||
nitpicker.enqueue<Nitpicker::Session::Command::Geometry>(rect);
|
|
||||||
|
|
||||||
timer.msleep(1000);
|
timer.msleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep_forever();
|
Genode::sleep_forever();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user