mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
loader: Adaptation to new nitpicker interface
This commit is contained in:
parent
8539239fc4
commit
7888e7be02
@ -21,41 +21,42 @@
|
||||
|
||||
namespace Loader {
|
||||
|
||||
struct Session_client : Rpc_client<Session>
|
||||
struct Session_client : Genode::Rpc_client<Session>
|
||||
{
|
||||
explicit Session_client(Loader::Session_capability 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); }
|
||||
|
||||
void commit_rom_module(Name const &name) {
|
||||
void commit_rom_module(Name const &name) override {
|
||||
call<Rpc_commit_rom_module>(name); }
|
||||
|
||||
void ram_quota(size_t quantum) {
|
||||
void ram_quota(size_t quantum) override {
|
||||
call<Rpc_ram_quota>(quantum); }
|
||||
|
||||
void constrain_geometry(int width, int height) {
|
||||
call<Rpc_constrain_geometry>(width, height); }
|
||||
void constrain_geometry(Area size) override {
|
||||
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); }
|
||||
|
||||
void view_ready_sigh(Signal_context_capability sigh) {
|
||||
void view_ready_sigh(Signal_context_capability sigh) override {
|
||||
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); }
|
||||
|
||||
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); }
|
||||
|
||||
Nitpicker::View_capability view() {
|
||||
return call<Rpc_view>(); }
|
||||
void view_geometry(Rect rect, Point offset) override {
|
||||
call<Rpc_view_geometry>(rect, offset); }
|
||||
|
||||
View_geometry view_geometry() {
|
||||
return call<Rpc_view_geometry>(); }
|
||||
Area view_size() const override {
|
||||
return call<Rpc_view_size>(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,18 @@
|
||||
#include <nitpicker_session/client.h>
|
||||
#include <base/signal.h>
|
||||
#include <session/session.h>
|
||||
#include <util/geometry.h>
|
||||
|
||||
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
|
||||
{
|
||||
@ -41,18 +49,6 @@ namespace Loader {
|
||||
struct View_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<128> Path;
|
||||
|
||||
@ -109,7 +105,7 @@ namespace Loader {
|
||||
* Calling this function prior 'start()' enables the virtualization
|
||||
* 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.
|
||||
@ -148,18 +144,14 @@ namespace Loader {
|
||||
Native_pd_args const &pd_args = Native_pd_args()) = 0;
|
||||
|
||||
/**
|
||||
* Return first nitpicker view created by the loaded subsystem
|
||||
*
|
||||
* \throw View_does_not_exist
|
||||
* Set view geometry and buffer offset
|
||||
*/
|
||||
virtual Nitpicker::View_capability view() = 0;
|
||||
virtual void view_geometry(Rect rect, Point offset) = 0;
|
||||
|
||||
/**
|
||||
* Return view geometry as initialized by the loaded subsystem
|
||||
*
|
||||
* \throw View_does_not_exist
|
||||
* Return view size as initialized by the loaded subsystem
|
||||
*/
|
||||
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),
|
||||
Name const &);
|
||||
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_view_ready_sigh, void, view_ready_sigh, Signal_context_capability);
|
||||
GENODE_RPC(Rpc_fault_sigh, void, fault_sigh, Signal_context_capability);
|
||||
GENODE_RPC_THROW(Rpc_start, void, start,
|
||||
GENODE_TYPE_LIST(Rom_module_does_not_exist),
|
||||
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_RPC(Rpc_view_geometry, View_geometry, view_geometry);
|
||||
|
||||
/*
|
||||
* 'GENODE_RPC_INTERFACE' declaration done manually
|
||||
@ -191,17 +185,17 @@ namespace Loader {
|
||||
* construct the type list by hand using nested type tuples instead
|
||||
* of employing the convenience macro 'GENODE_RPC_INTERFACE'.
|
||||
*/
|
||||
typedef Meta::Type_tuple<Rpc_alloc_rom_module,
|
||||
Meta::Type_tuple<Rpc_commit_rom_module,
|
||||
Meta::Type_tuple<Rpc_ram_quota,
|
||||
Meta::Type_tuple<Rpc_constrain_geometry,
|
||||
Meta::Type_tuple<Rpc_parent_view,
|
||||
Meta::Type_tuple<Rpc_view_ready_sigh,
|
||||
Meta::Type_tuple<Rpc_fault_sigh,
|
||||
Meta::Type_tuple<Rpc_start,
|
||||
Meta::Type_tuple<Rpc_view,
|
||||
Meta::Type_tuple<Rpc_view_geometry,
|
||||
Meta::Empty>
|
||||
typedef Type_tuple<Rpc_alloc_rom_module,
|
||||
Type_tuple<Rpc_commit_rom_module,
|
||||
Type_tuple<Rpc_ram_quota,
|
||||
Type_tuple<Rpc_constrain_geometry,
|
||||
Type_tuple<Rpc_parent_view,
|
||||
Type_tuple<Rpc_view_ready_sigh,
|
||||
Type_tuple<Rpc_fault_sigh,
|
||||
Type_tuple<Rpc_start,
|
||||
Type_tuple<Rpc_view_geometry,
|
||||
Type_tuple<Rpc_view_size,
|
||||
Genode::Meta::Empty>
|
||||
> > > > > > > > > Rpc_functions;
|
||||
};
|
||||
}
|
||||
|
@ -29,80 +29,78 @@ namespace Input {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Transformer
|
||||
{
|
||||
struct Delta { int const x, y; };
|
||||
typedef Genode::Point<> Motion_delta;
|
||||
|
||||
virtual Delta delta() = 0;
|
||||
};
|
||||
|
||||
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 Session_component;
|
||||
}
|
||||
|
||||
|
||||
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_ */
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <base/sleep.h>
|
||||
#include <loader_session/loader_session.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <nitpicker_view/capability.h>
|
||||
#include <root/component.h>
|
||||
|
||||
/* local includes */
|
||||
@ -33,395 +32,397 @@ namespace Loader {
|
||||
|
||||
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;
|
||||
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)
|
||||
{
|
||||
_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;
|
||||
_ep.dissolve(rom);
|
||||
_rom_sessions.remove(rom);
|
||||
destroy(&_md_alloc, rom);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(size_t quota, Ram_session &ram, Cap_session &cap)
|
||||
Local_rom_service(Rpc_entrypoint &ep,
|
||||
Allocator &md_alloc,
|
||||
Rom_module_registry &rom_modules)
|
||||
:
|
||||
_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, _md_alloc),
|
||||
_child(0)
|
||||
Service("virtual_rom"),
|
||||
_ep(ep),
|
||||
_md_alloc(md_alloc),
|
||||
_parent_rom_service(Rom_session::service_name()),
|
||||
_rom_modules(rom_modules)
|
||||
{ }
|
||||
|
||||
~Session_component()
|
||||
~Local_rom_service()
|
||||
{
|
||||
if (_child)
|
||||
destroy(&_md_alloc, _child);
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
/*
|
||||
* The parent-service registry is populated by the 'Child'
|
||||
* on demand. Revert those allocations.
|
||||
*/
|
||||
while (Service *service = _parent_services.find_by_server(0)) {
|
||||
_parent_services.remove(service);
|
||||
destroy(env()->heap(), service);
|
||||
}
|
||||
while (_rom_sessions.first()) {
|
||||
_close(_rom_sessions.first()); }
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
** 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)
|
||||
Genode::Session_capability session(char const *args,
|
||||
Affinity const &affinity)
|
||||
{
|
||||
/* try to find ROM module at local ROM service */
|
||||
try {
|
||||
_rom_modules.commit_rom_module(name.string()); }
|
||||
catch (Rom_module_registry::Lookup_failed) {
|
||||
throw Rom_module_does_not_exist(); }
|
||||
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 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)
|
||||
{
|
||||
_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)
|
||||
{
|
||||
/*
|
||||
* CPU exception handler for CPU sessions originating from the
|
||||
* subsystem.
|
||||
*/
|
||||
_cpu_service.fault_sigh = sigh;
|
||||
void upgrade(Genode::Session_capability session, const char *) { }
|
||||
};
|
||||
|
||||
/*
|
||||
* RM fault handler for RM sessions originating from the
|
||||
* subsystem.
|
||||
*/
|
||||
_rm_service.fault_sigh = sigh;
|
||||
enum { STACK_SIZE = 2*4096 };
|
||||
|
||||
/*
|
||||
* CPU exception and RM fault handler for the immediate child.
|
||||
*/
|
||||
_fault_sigh = sigh;
|
||||
}
|
||||
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;
|
||||
|
||||
void start(Name const &binary_name, Name const &label,
|
||||
Genode::Native_pd_args const &pd_args)
|
||||
{
|
||||
if (_child) {
|
||||
PWRN("cannot start subsystem twice");
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Return virtual nitpicker session component
|
||||
*/
|
||||
Nitpicker::Session_component &_virtual_nitpicker_session() const
|
||||
{
|
||||
if (!_nitpicker_service.open_session)
|
||||
throw View_does_not_exist();
|
||||
|
||||
size_t const ram_quota = (_subsystem_ram_quota_limit > 0) ?
|
||||
min(_subsystem_ram_quota_limit, _ram_session_client.avail()) :
|
||||
_ram_session_client.avail();
|
||||
return *_nitpicker_service.open_session;
|
||||
}
|
||||
|
||||
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(); }
|
||||
}
|
||||
public:
|
||||
|
||||
Nitpicker::View_capability view()
|
||||
{
|
||||
return _virtual_nitpicker_session()->loader_view();
|
||||
}
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
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()
|
||||
{
|
||||
return _virtual_nitpicker_session()->loader_view_geometry();
|
||||
}
|
||||
};
|
||||
~Session_component()
|
||||
{
|
||||
if (_child)
|
||||
destroy(&_md_alloc, _child);
|
||||
|
||||
|
||||
class 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
|
||||
/*
|
||||
* The parent-service registry is populated by the 'Child'
|
||||
* on demand. Revert those allocations.
|
||||
*/
|
||||
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)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
while (Service *service = _parent_services.find_by_server(0)) {
|
||||
_parent_services.remove(service);
|
||||
destroy(env()->heap(), service);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
** 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()
|
||||
|
@ -19,295 +19,259 @@
|
||||
#include <util/arg_string.h>
|
||||
#include <util/misc_math.h>
|
||||
#include <base/signal.h>
|
||||
#include <os/attached_ram_dataspace.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
#include <nitpicker_session/nitpicker_session.h>
|
||||
#include <nitpicker_view/client.h>
|
||||
|
||||
/* local includes */
|
||||
#include <input.h>
|
||||
|
||||
namespace Nitpicker {
|
||||
|
||||
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; }
|
||||
namespace Nitpicker { class Session_component; }
|
||||
|
||||
|
||||
/******************************
|
||||
** Nitpicker view interface **
|
||||
******************************/
|
||||
class Nitpicker::Session_component : public Genode::Rpc_object<Session>
|
||||
{
|
||||
private:
|
||||
|
||||
int viewport(int x, int y, int w, int h,
|
||||
int buf_x, int buf_y, bool redraw)
|
||||
{
|
||||
_x = x, _y = y, _buf_x = buf_x, _buf_y = buf_y;
|
||||
/**
|
||||
* Signal handler to be notified once the geometry of the view is
|
||||
* known.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
return _view.stack(neighbor_cap, behind, redraw);
|
||||
}
|
||||
public:
|
||||
|
||||
int title(Title const &title)
|
||||
{
|
||||
return _view.title(title.string());
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
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
|
||||
*/
|
||||
class View_component : public Rpc_object<View>
|
||||
{
|
||||
private:
|
||||
/*********************************
|
||||
** Nitpicker session interface **
|
||||
*********************************/
|
||||
|
||||
View_client _view; /* wrapped view */
|
||||
Signal_context_capability _sigh;
|
||||
bool _viewport_initialized;
|
||||
int _x, _y, _w, _h, _buf_x, _buf_y;
|
||||
Framebuffer::Session_capability framebuffer_session() override
|
||||
{
|
||||
return _nitpicker.framebuffer_session();
|
||||
}
|
||||
|
||||
public:
|
||||
Input::Session_capability input_session() override
|
||||
{
|
||||
return _proxy_input_cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
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)
|
||||
{ }
|
||||
View_handle create_view(View_handle) override
|
||||
{
|
||||
return View_handle(1);
|
||||
}
|
||||
|
||||
int x() const { return _x; }
|
||||
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; }
|
||||
void destroy_view(View_handle view) override { }
|
||||
|
||||
View_handle view_handle(View_capability, View_handle) override
|
||||
{
|
||||
return View_handle();
|
||||
}
|
||||
|
||||
/******************************
|
||||
** Nitpicker view interface **
|
||||
******************************/
|
||||
View_capability view_capability(View_handle) override
|
||||
{
|
||||
return View_capability();
|
||||
}
|
||||
|
||||
int viewport(int x, int y, int w, int h,
|
||||
int buf_x, int buf_y, bool redraw)
|
||||
{
|
||||
_x = x; _y = y; _w = w; _h = h;
|
||||
_buf_x = buf_x; _buf_y = buf_y;
|
||||
void release_view_handle(View_handle) override { }
|
||||
|
||||
if (_viewport_initialized)
|
||||
return 0;
|
||||
Genode::Dataspace_capability command_dataspace() override
|
||||
{
|
||||
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 */
|
||||
int result = _view.viewport(0, 0, 0, 0, 0, 0, true);
|
||||
Framebuffer::Mode mode() override
|
||||
{
|
||||
int mode_width = _max_size.valid() ?
|
||||
_max_size.w() :
|
||||
_nitpicker.mode().width();
|
||||
|
||||
/* signal readyness of the view */
|
||||
if (_sigh.valid())
|
||||
Signal_transmitter(_sigh).submit();
|
||||
int mode_height = _max_size.valid() ?
|
||||
_max_size.h() :
|
||||
_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)
|
||||
{
|
||||
/*
|
||||
* Only one child view is supported, so the stack request can
|
||||
* be ignored.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
void mode_sigh(Genode::Signal_context_capability) override { }
|
||||
|
||||
int title(Title const &title)
|
||||
{
|
||||
return _view.title(title.string());
|
||||
}
|
||||
};
|
||||
void buffer(Framebuffer::Mode mode, bool use_alpha) override
|
||||
{
|
||||
_nitpicker.buffer(mode, use_alpha);
|
||||
}
|
||||
|
||||
void focus(Genode::Capability<Session>) override { }
|
||||
|
||||
class Session_component : public Rpc_object<Session>,
|
||||
public Input::Transformer
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* Return geometry of loader view
|
||||
*/
|
||||
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;
|
||||
int _max_height;
|
||||
return Area(width, 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_capability _proxy_view_cap;
|
||||
_view_geometry = rect;
|
||||
_view_offset = offset;
|
||||
|
||||
Loader_view_component _loader_view;
|
||||
View_capability _loader_view_cap;
|
||||
_propagate_view_offset();
|
||||
_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;
|
||||
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;
|
||||
}
|
||||
};
|
||||
}
|
||||
_update_motion_delta();
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _NITPICKER_H_ */
|
||||
|
@ -14,18 +14,16 @@
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <loader_session/connection.h>
|
||||
#include <nitpicker_session/client.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
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));
|
||||
|
||||
@ -33,31 +31,22 @@ int main(int argc, char **argv)
|
||||
|
||||
sig_rec.wait_for_signal();
|
||||
|
||||
Loader::Session::View_geometry geometry = loader.view_geometry();
|
||||
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();
|
||||
Loader::Area size = loader.view_size();
|
||||
|
||||
Timer::Connection timer;
|
||||
|
||||
while(1) {
|
||||
while (1) {
|
||||
|
||||
for (unsigned i = 0; i < 10; i++) {
|
||||
|
||||
Nitpicker::Rect rect(Nitpicker::Point(50*i, 50*i),
|
||||
Nitpicker::Area(geometry.width, geometry.height));
|
||||
nitpicker.enqueue<Nitpicker::Session::Command::Geometry>(rect);
|
||||
loader.view_geometry(Loader::Rect(Loader::Point(50*i, 50*i), size),
|
||||
Loader::Point(0, 0));
|
||||
|
||||
timer.msleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
sleep_forever();
|
||||
Genode::sleep_forever();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user