From 7888e7be025d78fb632a8b0b5ed5306200e35b2f Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 30 Jun 2014 17:47:43 +0200 Subject: [PATCH] loader: Adaptation to new nitpicker interface --- repos/os/include/loader_session/client.h | 29 +- .../include/loader_session/loader_session.h | 66 +- repos/os/src/server/loader/input.h | 144 ++-- repos/os/src/server/loader/main.cc | 705 +++++++++--------- repos/os/src/server/loader/nitpicker.h | 470 ++++++------ repos/os/src/test/loader/main.cc | 25 +- 6 files changed, 693 insertions(+), 746 deletions(-) diff --git a/repos/os/include/loader_session/client.h b/repos/os/include/loader_session/client.h index 9d669f515a..21f4ab7956 100644 --- a/repos/os/include/loader_session/client.h +++ b/repos/os/include/loader_session/client.h @@ -21,41 +21,42 @@ namespace Loader { - struct Session_client : Rpc_client + struct Session_client : Genode::Rpc_client { explicit Session_client(Loader::Session_capability session) : Rpc_client(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(name, size); } - void commit_rom_module(Name const &name) { + void commit_rom_module(Name const &name) override { call(name); } - void ram_quota(size_t quantum) { + void ram_quota(size_t quantum) override { call(quantum); } - void constrain_geometry(int width, int height) { - call(width, height); } + void constrain_geometry(Area size) override { + call(size); } - void parent_view(Nitpicker::View_capability view) { + void parent_view(Nitpicker::View_capability view) override { call(view); } - void view_ready_sigh(Signal_context_capability sigh) { + void view_ready_sigh(Signal_context_capability sigh) override { call(sigh); } - void fault_sigh(Signal_context_capability sigh) { + void fault_sigh(Signal_context_capability sigh) override { call(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(binary, label, pd_args); } - Nitpicker::View_capability view() { - return call(); } + void view_geometry(Rect rect, Point offset) override { + call(rect, offset); } - View_geometry view_geometry() { - return call(); } + Area view_size() const override { + return call(); } }; } diff --git a/repos/os/include/loader_session/loader_session.h b/repos/os/include/loader_session/loader_session.h index b2c7a62acb..37eb8d3b6e 100644 --- a/repos/os/include/loader_session/loader_session.h +++ b/repos/os/include/loader_session/loader_session.h @@ -21,10 +21,18 @@ #include #include #include +#include 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 + typedef Type_tuple > > > > > > > > > Rpc_functions; }; } diff --git a/repos/os/src/server/loader/input.h b/repos/os/src/server/loader/input.h index 762a9b7d5b..1826df74f6 100644 --- a/repos/os/src/server/loader/input.h +++ b/repos/os/src/server/loader/input.h @@ -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 - { - 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 +{ + 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_ */ diff --git a/repos/os/src/server/loader/main.cc b/repos/os/src/server/loader/main.cc index 410d538327..6569611f31 100644 --- a/repos/os/src/server/loader/main.cc +++ b/repos/os/src/server/loader/main.cc @@ -19,7 +19,6 @@ #include #include #include -#include #include /* local includes */ @@ -33,395 +32,397 @@ namespace Loader { using namespace Genode; + class Session_component; + class Root; +} - class Session_component : public Rpc_object - { - private: - struct Local_rom_service : Service +class Loader::Session_component : public Rpc_object +{ + 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_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_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); - - 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 cap = env()->parent()->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 cap = env()->parent()->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); + + 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 cap = env()->parent()->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 cap = env()->parent()->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 - { - 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_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 +{ + 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_ep, &md_alloc), + _ram(ram), _cap(cap) + { } +}; int main() diff --git a/repos/os/src/server/loader/nitpicker.h b/repos/os/src/server/loader/nitpicker.h index 5cef2bd42e..ebbb5f85dd 100644 --- a/repos/os/src/server/loader/nitpicker.h +++ b/repos/os/src/server/loader/nitpicker.h @@ -19,295 +19,259 @@ #include #include #include +#include #include #include -#include /* local includes */ #include -namespace Nitpicker { - - using namespace Genode; - - /** - * View interface provided to the loader client - */ - class Loader_view_component : public Rpc_object - { - 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 +{ + 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(); + + void _propagate_view_offset() + { + _nitpicker.enqueue(_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(_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 - { - 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) override { } - class Session_component : public Rpc_object, - 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(_view_handle, _view_geometry); + _nitpicker.enqueue(_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) 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_ */ diff --git a/repos/os/src/test/loader/main.cc b/repos/os/src/test/loader/main.cc index 8bcd3c519d..1abf353086 100644 --- a/repos/os/src/test/loader/main.cc +++ b/repos/os/src/test/loader/main.cc @@ -14,18 +14,16 @@ #include #include #include -#include #include -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(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(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; }