diff --git a/repos/demo/src/server/nitlog/main.cc b/repos/demo/src/server/nitlog/main.cc index d9a0998585..0f735860a5 100644 --- a/repos/demo/src/server/nitlog/main.cc +++ b/repos/demo/src/server/nitlog/main.cc @@ -352,7 +352,7 @@ class Log_view { private: - Gui::Session_client &_gui; + Gui::Connection &_gui; Gui::Point _pos; Gui::Area _size; Gui::Session::View_handle _handle; @@ -362,7 +362,7 @@ class Log_view public: - Log_view(Gui::Session_client &gui, Gui::Rect geometry) + Log_view(Gui::Connection &gui, Gui::Rect geometry) : _gui(gui), _pos(geometry.at), diff --git a/repos/gems/src/app/decorator/main.cc b/repos/gems/src/app/decorator/main.cc index 10b19c55f6..8c83f395f4 100644 --- a/repos/gems/src/app/decorator/main.cc +++ b/repos/gems/src/app/decorator/main.cc @@ -183,22 +183,9 @@ struct Decorator::Main : Window_factory_base */ Window_base *create(Xml_node window_node) override { - for (;;) { - try { - return new (_heap) - Window(window_node.attribute_value("id", 0U), - _gui, _animator, _decorator_config); - } - catch (Genode::Out_of_ram) { - Genode::log("Handle Out_of_ram of GUI session - upgrade by 8K"); - _gui.upgrade_ram(8192); - } - catch (Genode::Out_of_caps) { - Genode::log("Handle Out_of_caps of GUI session - upgrade by 2"); - _gui.upgrade_caps(2); - } - } - return nullptr; + return new (_heap) + Window(window_node.attribute_value("id", 0U), + _gui, _animator, _decorator_config); } /** diff --git a/repos/gems/src/app/decorator/window.h b/repos/gems/src/app/decorator/window.h index b233fc14d0..ee57f973ee 100644 --- a/repos/gems/src/app/decorator/window.h +++ b/repos/gems/src/app/decorator/window.h @@ -16,6 +16,7 @@ /* Genode includes */ #include +#include /* local includes */ #include "config.h" @@ -29,7 +30,7 @@ class Decorator::Window : public Window_base { private: - Gui::Session_client &_gui; + Gui::Connection &_gui; /* * Flag indicating that the current window position has been propagated @@ -39,13 +40,13 @@ class Decorator::Window : public Window_base struct Gui_view { - Gui::Session_client &_gui; + Gui::Connection &_gui; View_handle _handle { _gui.create_view() }; using Command = Gui::Session::Command; - Gui_view(Gui::Session_client &gui, unsigned id = 0) + Gui_view(Gui::Connection &gui, unsigned id = 0) : _gui(gui) { @@ -419,7 +420,7 @@ class Decorator::Window : public Window_base public: - Window(unsigned id, Gui::Session_client &gui, + Window(unsigned id, Gui::Connection &gui, Animator &animator, Config const &config) : Window_base(id), diff --git a/repos/gems/src/app/sculpt_manager/gui.cc b/repos/gems/src/app/sculpt_manager/gui.cc index bb6b235bbc..ec082f731b 100644 --- a/repos/gems/src/app/sculpt_manager/gui.cc +++ b/repos/gems/src/app/sculpt_manager/gui.cc @@ -57,7 +57,11 @@ struct Gui::Session_component : Rpc_object Input::Seq_number &_global_input_seq_number; - Gui::Connection _connection; + Genode::Connection _connection; + + Gui::Session_client _gui_session { _connection.cap() }; + + Input::Session_client _gui_input { _env.rm(), _gui_session.input_session() }; Input::Session_component _input_component { _env, _env.ram() }; @@ -68,7 +72,7 @@ struct Gui::Session_component : Rpc_object void _handle_input() { - _connection.input()->for_each_event([&] (Input::Event ev) { + _gui_input.for_each_event([&] (Input::Event ev) { /* * Assign new event sequence number, pass seq event to menu view @@ -97,9 +101,9 @@ struct Gui::Session_component : Rpc_object : _env(env), _event_handler(event_handler), _global_input_seq_number(global_input_seq_number), - _connection(env, session_label_from_args(args).string()) + _connection(env, session_label_from_args(args), Ram_quota { 36*1024 }, { }) { - _connection.input()->sigh(_input_handler); + _gui_input.sigh(_input_handler); _env.ep().manage(_input_component); _input_component.event_queue().enabled(true); } @@ -112,52 +116,46 @@ struct Gui::Session_component : Rpc_object } Framebuffer::Session_capability framebuffer_session() override { - return _connection.framebuffer_session(); } + return _gui_session.framebuffer_session(); } Input::Session_capability input_session() override { return _input_component.cap(); } - View_handle create_view() override { - return _connection.create_view(); } + Create_view_result create_view() override { + return _gui_session.create_view(); } - View_handle create_child_view(View_handle parent) override { - return _connection.create_child_view(parent); } + Create_child_view_result create_child_view(View_handle parent) override { + return _gui_session.create_child_view(parent); } void destroy_view(View_handle view) override { - _connection.destroy_view(view); } + _gui_session.destroy_view(view); } - View_handle view_handle(View_capability view_cap, View_handle handle) override { - return _connection.view_handle(view_cap, handle); } + View_handle_result view_handle(View_capability view_cap, View_handle handle) override { + return _gui_session.view_handle(view_cap, handle); } View_capability view_capability(View_handle view) override { - return _connection.view_capability(view); } + return _gui_session.view_capability(view); } void release_view_handle(View_handle view) override { - _connection.release_view_handle(view); } + _gui_session.release_view_handle(view); } Dataspace_capability command_dataspace() override { - return _connection.command_dataspace(); } + return _gui_session.command_dataspace(); } void execute() override { - _connection.execute(); } + _gui_session.execute(); } Framebuffer::Mode mode() override { - return _connection.mode(); } + return _gui_session.mode(); } void mode_sigh(Signal_context_capability sigh) override { - _connection.mode_sigh(sigh); } + _gui_session.mode_sigh(sigh); } - void buffer(Framebuffer::Mode mode, bool use_alpha) override - { - /* - * Do not call 'Connection::buffer' to avoid paying session quota - * from our own budget. - */ - _connection.Session_client::buffer(mode, use_alpha); - } + Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override { + return _gui_session.buffer(mode, use_alpha); } void focus(Capability session) override { - _connection.focus(session); } + _gui_session.focus(session); } }; diff --git a/repos/gems/src/app/themed_decorator/main.cc b/repos/gems/src/app/themed_decorator/main.cc index c751df8cc9..b3e1640478 100644 --- a/repos/gems/src/app/themed_decorator/main.cc +++ b/repos/gems/src/app/themed_decorator/main.cc @@ -170,21 +170,9 @@ struct Decorator::Main : Window_factory_base */ Window_base *create(Xml_node window_node) override { - for (;;) { - try { - return new (_heap) - Window(_env, window_node.attribute_value("id", 0U), - _gui, _animator, _theme, _decorator_config); - } - catch (Out_of_ram) { - log("Handle Out_of_ram of GUI session - upgrade by 8K"); - _gui.upgrade_ram(8192); - } - catch (Out_of_caps) { - log("Handle Out_of_caps of GUI session - upgrade by 2"); - _gui.upgrade_caps(2); - } - } + return new (_heap) + Window(_env, window_node.attribute_value("id", 0U), + _gui, _animator, _theme, _decorator_config); } /** diff --git a/repos/gems/src/app/themed_decorator/window.h b/repos/gems/src/app/themed_decorator/window.h index de11481e36..17a1a965e4 100644 --- a/repos/gems/src/app/themed_decorator/window.h +++ b/repos/gems/src/app/themed_decorator/window.h @@ -147,11 +147,11 @@ class Decorator::Window : public Window_base, public Animator::Item bool const _view_is_remote; - Gui::Session_client &_gui; + Gui::Connection &_gui; View_handle _handle; - Gui_view(Gui::Session_client &gui, unsigned id = 0) + Gui_view(Gui::Connection &gui, unsigned id = 0) : _view_is_remote(false), _gui(gui), @@ -165,7 +165,7 @@ class Decorator::Window : public Window_base, public Animator::Item Genode::String<128>(id).string()); } - View_handle _create_remote_view(Gui::Session_client &remote_gui) + View_handle _create_remote_view(Gui::Connection &remote_gui) { /* create view at the remote GUI session */ View_handle handle = remote_gui.create_view(); @@ -179,8 +179,8 @@ class Decorator::Window : public Window_base, public Animator::Item * Constructor called for creating a view that refers to a buffer * of another GUI session */ - Gui_view(Gui::Session_client &gui, - Gui::Session_client &remote_gui) + Gui_view(Gui::Connection &gui, + Gui::Connection &remote_gui) : _view_is_remote(true), _gui(gui), @@ -217,7 +217,7 @@ class Decorator::Window : public Window_base, public Animator::Item /** * GUI session used as a global namespace of view handles */ - Gui::Session_client &_gui; + Gui::Connection &_gui; Config const &_config; @@ -369,7 +369,7 @@ class Decorator::Window : public Window_base, public Animator::Item public: - Window(Genode::Env &env, unsigned id, Gui::Session_client &gui, + Window(Genode::Env &env, unsigned id, Gui::Connection &gui, Animator &animator, Theme const &theme, Config const &config) : Window_base(id), diff --git a/repos/gems/src/app/window_layouter/main.cc b/repos/gems/src/app/window_layouter/main.cc index 3b22eea48a..e37a910aef 100644 --- a/repos/gems/src/app/window_layouter/main.cc +++ b/repos/gems/src/app/window_layouter/main.cc @@ -336,7 +336,7 @@ struct Window_layouter::Main : Operations, _env.ep(), *this, &Main::_handle_mode_change }; - Input::Session_client _input { _env.rm(), _gui.input_session() }; + Input::Session_client &_input = *_gui.input(); Attached_dataspace _input_ds { _env.rm(), _input.dataspace() }; diff --git a/repos/gems/src/lib/dialog/sandboxed_runtime.cc b/repos/gems/src/lib/dialog/sandboxed_runtime.cc index 9a9e40f0fb..e668cf1553 100644 --- a/repos/gems/src/lib/dialog/sandboxed_runtime.cc +++ b/repos/gems/src/lib/dialog/sandboxed_runtime.cc @@ -59,7 +59,11 @@ struct Sandboxed_runtime::Gui_session : Session_object using View_capability = Gui::View_capability; - Gui::Connection _connection; + Genode::Connection _connection; + + Gui::Session_client _gui_session { _connection.cap() }; + + Input::Session_client _gui_input { _env.rm(), _gui_session.input_session() }; Input::Session_component _input_component { _env, _env.ram() }; @@ -70,7 +74,7 @@ struct Sandboxed_runtime::Gui_session : Session_object void _handle_input() { - _connection.input()->for_each_event([&] (Input::Event const &ev) { + _gui_input.for_each_event([&] (Input::Event const &ev) { /* * Assign new event sequence number, pass seq event to menu view @@ -101,9 +105,9 @@ struct Sandboxed_runtime::Gui_session : Session_object Session_object(args...), _env(env), _view(view), _element(_view._gui_sessions, *this), - _connection(env, _label.string()) + _connection(env, _label, Ram_quota { 36*1024 }, { }) { - _connection.input()->sigh(_input_handler); + _gui_input.sigh(_input_handler); _env.ep().manage(_input_component); _input_component.event_queue().enabled(true); } @@ -116,52 +120,46 @@ struct Sandboxed_runtime::Gui_session : Session_object } Framebuffer::Session_capability framebuffer_session() override { - return _connection.framebuffer_session(); } + return _gui_session.framebuffer_session(); } Input::Session_capability input_session() override { return _input_component.cap(); } - View_handle create_view() override { - return _connection.create_view(); } + Create_view_result create_view() override { + return _gui_session.create_view(); } - View_handle create_child_view(View_handle parent) override { - return _connection.create_child_view(parent); } + Create_child_view_result create_child_view(View_handle parent) override { + return _gui_session.create_child_view(parent); } void destroy_view(View_handle view) override { - _connection.destroy_view(view); } + _gui_session.destroy_view(view); } - View_handle view_handle(View_capability view_cap, View_handle handle) override { - return _connection.view_handle(view_cap, handle); } + View_handle_result view_handle(View_capability view_cap, View_handle handle) override { + return _gui_session.view_handle(view_cap, handle); } View_capability view_capability(View_handle view) override { - return _connection.view_capability(view); } + return _gui_session.view_capability(view); } void release_view_handle(View_handle view) override { - _connection.release_view_handle(view); } + _gui_session.release_view_handle(view); } Dataspace_capability command_dataspace() override { - return _connection.command_dataspace(); } + return _gui_session.command_dataspace(); } void execute() override { - _connection.execute(); } + _gui_session.execute(); } Framebuffer::Mode mode() override { - return _connection.mode(); } + return _gui_session.mode(); } void mode_sigh(Signal_context_capability sigh) override { - _connection.mode_sigh(sigh); } + _gui_session.mode_sigh(sigh); } - void buffer(Framebuffer::Mode mode, bool use_alpha) override - { - /* - * Do not call 'Connection::buffer' to avoid paying session quota - * from our own budget. - */ - _connection.Session_client::buffer(mode, use_alpha); - } + Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override { + return _gui_session.buffer(mode, use_alpha); } void focus(Capability session) override { - _connection.focus(session); } + _gui_session.focus(session); } }; diff --git a/repos/gems/src/server/gui_fader/main.cc b/repos/gems/src/server/gui_fader/main.cc index 0d28404e54..65add4e064 100644 --- a/repos/gems/src/server/gui_fader/main.cc +++ b/repos/gems/src/server/gui_fader/main.cc @@ -342,17 +342,17 @@ class Gui_fader::Gui_session_component Input::Session_capability input_session() override { - return _gui.input_session(); + return _gui.cap().call(); } - View_handle create_view() override + Create_view_result create_view() override { _view_handle = _gui.create_view(); _update_view_visibility(); return _view_handle; } - View_handle create_child_view(View_handle parent) override + Create_child_view_result create_child_view(View_handle parent) override { _view_handle = _gui.create_child_view(parent); _update_view_visibility(); @@ -364,8 +364,8 @@ class Gui_fader::Gui_session_component return _gui.destroy_view(handle); } - View_handle view_handle(View_capability view_cap, - View_handle handle) override + View_handle_result view_handle(View_capability view_cap, + View_handle handle) override { return _gui.view_handle(view_cap, handle); } @@ -420,7 +420,7 @@ class Gui_fader::Gui_session_component _gui.mode_sigh(sigh); } - void buffer(Framebuffer::Mode mode, bool use_alpha) override + Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override { Area const size = mode.area; @@ -429,6 +429,7 @@ class Gui_fader::Gui_session_component _gui.buffer(mode, true); _fb_session.dst_buffer(_gui.framebuffer()->dataspace(), size); + return Buffer_result::OK; } void focus(Genode::Capability focused) override diff --git a/repos/gems/src/server/wm/decorator_gui.h b/repos/gems/src/server/wm/decorator_gui.h index d28257d2e9..de9785aa23 100644 --- a/repos/gems/src/server/wm/decorator_gui.h +++ b/repos/gems/src/server/wm/decorator_gui.h @@ -16,8 +16,6 @@ /* Genode includes */ #include -#include -#include #include #include #include @@ -25,6 +23,7 @@ /* local includes */ #include #include +#include namespace Wm { class Main; using Genode::size_t; @@ -166,13 +165,15 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, Genode::Ram_allocator &_ram; - Gui::Connection _gui_session { _env, "decorator" }; + Real_gui _gui { _env, "decorator" }; + + Input::Session_client _input_session { _env.rm(), _gui.session.input_session() }; Genode::Signal_context_capability _mode_sigh { }; - Attached_ram_dataspace _command_ds { _ram, _env.rm(), sizeof(Command_buffer) }; + Attached_ram_dataspace _client_command_ds { _ram, _env.rm(), sizeof(Command_buffer) }; - Command_buffer &_command_buffer = *_command_ds.local_addr(); + Command_buffer &_client_command_buffer = *_client_command_ds.local_addr(); Pointer::State _pointer_state; @@ -212,7 +213,7 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, _content_callback(content_callback), _md_alloc(md_alloc) { - _gui_session.input()->sigh(_input_handler); + _input_session.sigh(_input_handler); } ~Decorator_gui_session() @@ -222,8 +223,8 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, void _handle_input() { - while (_gui_session.input()->pending()) - _gui_session.input()->for_each_event([&] (Input::Event const &ev) { + while (_input_session.pending()) + _input_session.for_each_event([&] (Input::Event const &ev) { _pointer_state.apply_event(ev); _window_layouter_input.submit(ev); }); } @@ -267,11 +268,11 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, */ View_capability view_cap = _content_callback.content_view(win_id); - _gui_session.destroy_view(view_handle); - _gui_session.view_handle(view_cap, view_handle); + _gui.session.destroy_view(view_handle); + _gui.session.view_handle(view_cap, view_handle); - _gui_session.enqueue(cmd); - _gui_session.execute(); + _gui.enqueue(cmd); + _gui.execute(); /* * Now that the physical content view exists, it is time @@ -281,7 +282,7 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, } catch (Decorator_content_registry::Lookup_failed) { - _gui_session.enqueue(cmd); + _gui.enqueue(cmd); } return; @@ -302,7 +303,7 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, catch (Decorator_content_registry::Lookup_failed) { } /* forward command */ - _gui_session.enqueue(cmd); + _gui.enqueue(cmd); return; case Command::OP_OFFSET: @@ -316,21 +317,21 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, _content_registry.lookup(cmd.geometry.view); } catch (Decorator_content_registry::Lookup_failed) { - _gui_session.enqueue(cmd); + _gui.enqueue(cmd); } return; case Command::OP_BACKGROUND: case Command::OP_NOP: - _gui_session.enqueue(cmd); + _gui.enqueue(cmd); return; } } void upgrade(const char *args) { - _gui_session.upgrade(Genode::session_resources_from_args(args)); + _gui.connection.upgrade(Genode::session_resources_from_args(args)); } Pointer::Position last_observed_pointer_pos() const @@ -345,7 +346,7 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, Framebuffer::Session_capability framebuffer_session() override { - return _gui_session.framebuffer_session(); + return _gui.session.framebuffer_session(); } Input::Session_capability input_session() override @@ -357,14 +358,14 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, return _dummy_input_component_cap; } - View_handle create_view() override + Create_view_result create_view() override { - return _gui_session.create_view(); + return _gui.session.create_view(); } - View_handle create_child_view(View_handle parent) override + Create_child_view_result create_child_view(View_handle parent) override { - return _gui_session.create_child_view(parent); + return _gui.session.create_child_view(parent); } void destroy_view(View_handle view) override @@ -374,53 +375,53 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, */ if (_content_registry.registered(view)) { Gui::Rect rect(Gui::Point(0, 0), Gui::Area(0, 0)); - _gui_session.enqueue(view, rect); - _gui_session.execute(); + _gui.enqueue(view, rect); + _gui.execute(); Window_registry::Id win_id = _content_registry.lookup(view); _content_callback.hide_content_child_views(win_id); } - _gui_session.destroy_view(view); + _gui.session.destroy_view(view); } - View_handle view_handle(View_capability view_cap, View_handle handle) override + View_handle_result view_handle(View_capability view_cap, View_handle handle) override { - return _gui_session.view_handle(view_cap, handle); + return _gui.session.view_handle(view_cap, handle); } View_capability view_capability(View_handle view) override { - return _gui_session.view_capability(view); + return _gui.session.view_capability(view); } void release_view_handle(View_handle view) override { /* XXX dealloc View_ptr */ - _gui_session.release_view_handle(view); + _gui.session.release_view_handle(view); } Genode::Dataspace_capability command_dataspace() override { - return _command_ds.cap(); + return _client_command_ds.cap(); } void execute() override { - for (unsigned i = 0; i < _command_buffer.num(); i++) { + for (unsigned i = 0; i < _client_command_buffer.num(); i++) { try { - _execute_command(_command_buffer.get(i)); + _execute_command(_client_command_buffer.get(i)); } catch (...) { Genode::warning("unhandled exception while processing command from decorator"); } } - _gui_session.execute(); + _gui.execute(); } Framebuffer::Mode mode() override { - return _gui_session.mode(); + return _gui.session.mode(); } void mode_sigh(Genode::Signal_context_capability sigh) override @@ -430,15 +431,12 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, * transitive delegations of the capability. */ _mode_sigh = sigh; - _gui_session.mode_sigh(sigh); + _gui.session.mode_sigh(sigh); } - void buffer(Framebuffer::Mode mode, bool use_alpha) override + Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override { - /* - * See comment in 'Wm::Gui::Session_component::buffer'. - */ - Gui::Session_client(_env.rm(), _gui_session.cap()).buffer(mode, use_alpha); + return _gui.session.buffer(mode, use_alpha); } void focus(Genode::Capability) override { } diff --git a/repos/gems/src/server/wm/direct_gui.h b/repos/gems/src/server/wm/direct_gui.h index 0fca287ae4..9b8026ea1f 100644 --- a/repos/gems/src/server/wm/direct_gui.h +++ b/repos/gems/src/server/wm/direct_gui.h @@ -25,24 +25,29 @@ class Wm::Direct_gui_session : public Genode::Rpc_object { private: - Genode::Session_label _session_label; - Gui::Connection _session; + Genode::Env &_env; + + Genode::Session_label _label; + + Genode::Connection _connection { + _env, _label, Genode::Ram_quota { 36*1024 }, /* Args */ { } }; + + Gui::Session_client _session { _connection.cap() }; public: /** * Constructor */ - Direct_gui_session(Genode::Env &env, Genode::Session_label const &session_label) + Direct_gui_session(Genode::Env &env, Genode::Session_label const &label) : - _session_label(session_label), - _session(env, _session_label.string()) + _env(env), _label(label) { } void upgrade(char const *args) { size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - _session.upgrade_ram(ram_quota); + _connection.upgrade_ram(ram_quota); } @@ -60,12 +65,12 @@ class Wm::Direct_gui_session : public Genode::Rpc_object return _session.input_session(); } - View_handle create_view() override + Create_view_result create_view() override { return _session.create_view(); } - View_handle create_child_view(View_handle parent) override + Create_child_view_result create_child_view(View_handle parent) override { return _session.create_child_view(parent); } @@ -75,7 +80,7 @@ class Wm::Direct_gui_session : public Genode::Rpc_object _session.destroy_view(view); } - View_handle view_handle(Gui::View_capability view_cap, View_handle handle) override + View_handle_result view_handle(Gui::View_capability view_cap, View_handle handle) override { return _session.view_handle(view_cap, handle); } @@ -110,9 +115,9 @@ class Wm::Direct_gui_session : public Genode::Rpc_object _session.mode_sigh(sigh); } - void buffer(Framebuffer::Mode mode, bool use_alpha) override + Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override { - _session.buffer(mode, use_alpha); + return _session.buffer(mode, use_alpha); } void focus(Genode::Capability session) override diff --git a/repos/gems/src/server/wm/gui.h b/repos/gems/src/server/wm/gui.h index e154288b12..2b3c2fb84e 100644 --- a/repos/gems/src/server/wm/gui.h +++ b/repos/gems/src/server/wm/gui.h @@ -116,7 +116,7 @@ class Wm::Gui::View : private Genode::Weak_object, using View_handle = Gui::Session::View_handle; Session_label _session_label; - Gui::Session_client &_real_gui; + Real_gui &_real_gui; View_handle _real_handle { }; Title _title { }; Rect _geometry { }; @@ -125,7 +125,7 @@ class Wm::Gui::View : private Genode::Weak_object, bool _neighbor_behind { }; bool _has_alpha; - View(Gui::Session_client &real_gui, + View(Real_gui &real_gui, Session_label const &session_label, bool has_alpha) : @@ -153,7 +153,10 @@ class Wm::Gui::View : private Genode::Weak_object, View_handle real_neighbor_handle; if (neighbor.valid()) - real_neighbor_handle = _real_gui.view_handle(neighbor->real_view_cap()); + _real_gui.session.view_handle(neighbor->real_view_cap()).with_result( + [&] (View_handle handle) { real_neighbor_handle = handle; }, + [&] (auto) { warning("unable to obtain real_neighbor_handle"); } + ); if (_neighbor_behind) _real_gui.enqueue(_real_handle, real_neighbor_handle); @@ -163,7 +166,7 @@ class Wm::Gui::View : private Genode::Weak_object, _real_gui.execute(); if (real_neighbor_handle.valid()) - _real_gui.release_view_handle(real_neighbor_handle); + _real_gui.session.release_view_handle(real_neighbor_handle); } void _apply_view_config() @@ -177,7 +180,7 @@ class Wm::Gui::View : private Genode::Weak_object, ~View() { if (_real_handle.valid()) - _real_gui.destroy_view(_real_handle); + _real_gui.session.destroy_view(_real_handle); } using Genode::Weak_object::weak_ptr; @@ -218,7 +221,7 @@ class Wm::Gui::View : private Genode::Weak_object, View_capability real_view_cap() { - return _real_gui.view_capability(_real_handle); + return _real_gui.session.view_capability(_real_handle); } void buffer_offset(Point buffer_offset) @@ -255,23 +258,23 @@ class Wm::Gui::Top_level_view : public View, private List::Eleme bool _resizeable = false; - Title _window_title { }; - Session_label _session_label; + Title _window_title { }; + + Session_label const _session_label; using Command = Gui::Session::Command; public: - Top_level_view(Gui::Session_client &real_gui, - Session_label const &session_label, + Top_level_view(Real_gui &real_gui, bool has_alpha, Window_registry &window_registry, Input_origin_changed_handler &input_origin_changed_handler) : - View(real_gui, session_label, has_alpha), + View(real_gui, real_gui.label, has_alpha), _window_registry(window_registry), _input_origin_changed_handler(input_origin_changed_handler), - _session_label(session_label) + _session_label(real_gui.label) { } ~Top_level_view() @@ -347,14 +350,22 @@ class Wm::Gui::Top_level_view : public View, private List::Eleme /* * Create and configure physical GUI view. */ - _real_handle = _real_gui.create_view(); + _real_gui.session.create_view().with_result( + [&] (View_handle handle) { + _real_handle = handle; + _real_gui.enqueue(_real_handle, _buffer_offset); + _real_gui.enqueue (_real_handle, _title.string()); + _real_gui.execute(); + }, + [&] (Gui::Session::Create_view_error) { } + ); - _real_gui.enqueue(_real_handle, _buffer_offset); - _real_gui.enqueue (_real_handle, _title.string()); - _real_gui.execute(); + if (!_real_handle.valid()) { + warning("failed to created content view for ", _title); + return { }; + } } - - return _real_gui.view_capability(_real_handle); + return _real_gui.session.view_capability(_real_handle); } void hidden(bool hidden) { _window_registry.hidden(_win_id, hidden); } @@ -379,12 +390,11 @@ class Wm::Gui::Child_view : public View, private List::Element public: - Child_view(Gui::Session_client &real_gui, - Session_label const &session_label, - bool has_alpha, - Weak_ptr parent) + Child_view(Real_gui &real_gui, + bool has_alpha, + Weak_ptr parent) : - View(real_gui, session_label, has_alpha), _parent(parent) + View(real_gui, real_gui.label, has_alpha), _parent(parent) { try_to_init_real_view(); } @@ -433,13 +443,26 @@ class Wm::Gui::Child_view : public View, private List::Element if (!parent.valid()) return; - View_handle parent_handle = _real_gui.view_handle(parent->real_view_cap()); - if (!parent_handle.valid()) + View_handle parent_handle { }; + _real_gui.session.view_handle(parent->real_view_cap()).with_result( + [&] (View_handle handle) { parent_handle = handle; }, + [&] (Gui::Session::View_handle_error) { } + ); + if (!parent_handle.valid()) { + warning("try_to_init_real_view failed to obtain parent handle"); return; + } - _real_handle = _real_gui.create_child_view(parent_handle); + _real_gui.session.create_child_view(parent_handle).with_result( + [&] (View_handle handle) { _real_handle = handle; }, + [&] (Gui::Session::Create_child_view_error) { } + ); + if (!_real_handle.valid()) { + warning("try_to_init_real_view failed to create child view"); + return; + } - _real_gui.release_view_handle(parent_handle); + _real_gui.session.release_view_handle(parent_handle); if (_neighbor_ptr == _parent) _unsynchronized_apply_view_config(parent); @@ -457,7 +480,7 @@ class Wm::Gui::Child_view : public View, private List::Element if (!_real_handle.valid()) return; - _real_gui.destroy_view(_real_handle); + _real_gui.session.destroy_view(_real_handle); _real_handle = { }; } }; @@ -475,10 +498,9 @@ class Wm::Gui::Session_component : public Rpc_object, Genode::Env &_env; - Session_label _session_label; - Genode::Ram_allocator &_ram; - Gui::Connection _session { _env, _session_label.string() }; - + Session_label _session_label; + Genode::Ram_allocator &_ram; + Real_gui _real_gui { _env, _session_label }; Window_registry &_window_registry; Tslab _top_level_view_alloc; Tslab _child_view_alloc; @@ -516,7 +538,7 @@ class Wm::Gui::Session_component : public Rpc_object, /* * Input */ - Input::Session_client _gui_input { _env.rm(), _session.input_session() }; + Input::Session_client _gui_input { _env.rm(), _real_gui.session.input_session() }; Attached_dataspace _gui_input_ds { _env.rm(), _gui_input.dataspace() }; Signal_handler _input_handler { @@ -661,7 +683,7 @@ class Wm::Gui::Session_component : public Rpc_object, View &_create_view_object() { Top_level_view *view = new (_top_level_view_alloc) - Top_level_view(_session, _session_label, _has_alpha, + Top_level_view(_real_gui, _has_alpha, _window_registry, *this); view->resizeable(_mode_sigh.valid()); @@ -675,7 +697,7 @@ class Wm::Gui::Session_component : public Rpc_object, Weak_ptr parent_ptr = _view_handle_registry.lookup(parent_handle); Child_view *view = new (_child_view_alloc) - Child_view(_session, _session_label, _has_alpha, parent_ptr); + Child_view(_real_gui, _has_alpha, parent_ptr); _child_views.insert(view); return *view; @@ -803,7 +825,7 @@ class Wm::Gui::Session_component : public Rpc_object, _view_handle_registry(session_alloc) { _gui_input.sigh(_input_handler); - _session.mode_sigh(_mode_handler); + _real_gui.session.mode_sigh(_mode_handler); _input_session.event_queue().enabled(true); } @@ -822,7 +844,7 @@ class Wm::Gui::Session_component : public Rpc_object, void upgrade(char const *args) { - _session.upgrade(Genode::session_resources_from_args(args)); + _real_gui.connection.upgrade(Genode::session_resources_from_args(args)); } void try_to_init_real_child_views() @@ -914,7 +936,7 @@ class Wm::Gui::Session_component : public Rpc_object, /** * Return session capability to real GUI session */ - Capability session() { return _session.rpc_cap(); } + Capability session() { return _real_gui.connection.cap(); } /*************************** @@ -923,7 +945,7 @@ class Wm::Gui::Session_component : public Rpc_object, Framebuffer::Session_capability framebuffer_session() override { - return _session.framebuffer_session(); + return _real_gui.session.framebuffer_session(); } Input::Session_capability input_session() override @@ -931,20 +953,26 @@ class Wm::Gui::Session_component : public Rpc_object, return _input_session_cap; } - View_handle create_view() override + Create_view_result create_view() override { - View &view = _create_view_object(); - _env.ep().manage(view); - return _view_handle_registry.alloc(view); + try { + View &view = _create_view_object(); + _env.ep().manage(view); + return _view_handle_registry.alloc(view); + } + catch (Out_of_ram) { return Create_view_error::OUT_OF_RAM; } + catch (Out_of_caps) { return Create_view_error::OUT_OF_CAPS; } } - View_handle create_child_view(View_handle parent) override + Create_child_view_result create_child_view(View_handle parent) override { try { View &view = _create_child_view_object(parent); _env.ep().manage(view); return _view_handle_registry.alloc(view); } + catch (Out_of_ram) { return Create_child_view_error::OUT_OF_RAM; } + catch (Out_of_caps) { return Create_child_view_error::OUT_OF_CAPS; } catch (View_handle_registry::Lookup_failed) { return View_handle(); } } @@ -972,11 +1000,15 @@ class Wm::Gui::Session_component : public Rpc_object, } catch (View_handle_registry::Lookup_failed) { } } - View_handle view_handle(View_capability view_cap, View_handle handle) override + View_handle_result view_handle(View_capability view_cap, View_handle handle) override { - return _env.ep().rpc_ep().apply(view_cap, [&] (View *view) { - return (view) ? _view_handle_registry.alloc(*view, handle) - : View_handle(); }); + try { + return _env.ep().rpc_ep().apply(view_cap, [&] (View *view) { + return (view) ? _view_handle_registry.alloc(*view, handle) + : View_handle(); }); + } + catch (Out_of_ram) { return View_handle_error::OUT_OF_RAM; } + catch (Out_of_caps) { return View_handle_error::OUT_OF_CAPS; } } View_capability view_capability(View_handle handle) override @@ -1017,7 +1049,7 @@ class Wm::Gui::Session_component : public Rpc_object, Framebuffer::Mode mode() override { - Framebuffer::Mode const real_mode = _session.mode(); + Framebuffer::Mode const real_mode = _real_gui.session.mode(); /* * While resizing the window, return requested window size as @@ -1054,7 +1086,7 @@ class Wm::Gui::Session_component : public Rpc_object, v->resizeable(resizeable); } - void buffer(Framebuffer::Mode mode, bool has_alpha) override + Buffer_result buffer(Framebuffer::Mode mode, bool has_alpha) override { /* * We must not perform the 'buffer' operation on the connection @@ -1065,8 +1097,8 @@ class Wm::Gui::Session_component : public Rpc_object, * wrapped GUI session. Otherwise, we would perform session * upgrades initiated by the wm client's buffer operation twice. */ - Gui::Session_client(_env.rm(), _session.cap()).buffer(mode, has_alpha); _has_alpha = has_alpha; + return _real_gui.session.buffer(mode, has_alpha); } void focus(Genode::Capability) override { } @@ -1139,7 +1171,7 @@ class Wm::Gui::Root : public Genode::Rpc_object /** * GUI session used to perform session-control operations */ - Gui::Session &_focus_gui_session; + Gui::Connection &_focus_gui_session; public: @@ -1150,7 +1182,7 @@ class Wm::Gui::Root : public Genode::Rpc_object Window_registry &window_registry, Allocator &md_alloc, Genode::Ram_allocator &ram, Pointer::Tracker &pointer_tracker, Reporter &focus_request_reporter, - Gui::Session &focus_gui_session) + Gui::Connection &focus_gui_session) : _env(env), _md_alloc(md_alloc), _ram(ram), diff --git a/repos/gems/src/server/wm/layouter_gui.h b/repos/gems/src/server/wm/layouter_gui.h index 4ce86502f5..7486a21d93 100644 --- a/repos/gems/src/server/wm/layouter_gui.h +++ b/repos/gems/src/server/wm/layouter_gui.h @@ -62,13 +62,13 @@ struct Wm::Layouter_gui_session : Genode::Rpc_object return _input_session_cap; } - View_handle create_view() override { return View_handle(); } + Create_view_result create_view() override { return View_handle(); } - View_handle create_child_view(View_handle) override { return View_handle(); } + Create_child_view_result create_child_view(View_handle) override { return View_handle(); } void destroy_view(View_handle) override { } - View_handle view_handle(View_capability, View_handle) override + View_handle_result view_handle(View_capability, View_handle) override { return View_handle(); } @@ -100,7 +100,7 @@ struct Wm::Layouter_gui_session : Genode::Rpc_object _mode_sigh_gui.mode_sigh(sigh); } - void buffer(Framebuffer::Mode, bool) override { } + Buffer_result buffer(Framebuffer::Mode, bool) override { return Buffer_result::OK; } void focus(Genode::Capability) override { } }; diff --git a/repos/gems/src/server/wm/real_gui.h b/repos/gems/src/server/wm/real_gui.h new file mode 100644 index 0000000000..bfbeac4f13 --- /dev/null +++ b/repos/gems/src/server/wm/real_gui.h @@ -0,0 +1,75 @@ +/* + * \brief Wrapped GUI session + * \author Norman Feske + * \date 2024-08-05 + */ + +/* + * Copyright (C) 2024 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#ifndef _REAL_GUI_H_ +#define _REAL_GUI_H_ + +/* Genode includes */ +#include +#include +#include + +namespace Wm { struct Real_gui; } + + +struct Wm::Real_gui +{ + private: + + Genode::Env &_env; + + public: + + Genode::Session_label const &label; + + using Command_buffer = Gui::Session::Command_buffer; + + public: + + Real_gui(Genode::Env &env, Genode::Session_label const &label) + : + _env(env), label(label) + { } + + Genode::Connection connection { + _env, label, Genode::Ram_quota { 36*1024 }, /* Args */ { } }; + + Gui::Session_client session { connection.cap() }; + + private: + + Genode::Attached_dataspace _command_ds { _env.rm(), session.command_dataspace() }; + + Command_buffer &_command_buffer { *_command_ds.local_addr() }; + + public: + + template + void enqueue(auto &&... args) { enqueue(Gui::Session::Command( CMD { args... } )); } + + void enqueue(Gui::Session::Command const &command) + { + if (_command_buffer.full()) + execute(); + + _command_buffer.enqueue(command); + } + + void execute() + { + session.execute(); + _command_buffer.reset(); + } +}; + +#endif /* _REAL_GUI_H_ */ diff --git a/repos/libports/include/qgenodeviewwidget/qgenodeviewwidget.h b/repos/libports/include/qgenodeviewwidget/qgenodeviewwidget.h index 15f743c9ba..5333715708 100644 --- a/repos/libports/include/qgenodeviewwidget/qgenodeviewwidget.h +++ b/repos/libports/include/qgenodeviewwidget/qgenodeviewwidget.h @@ -16,7 +16,7 @@ #include -#include +#include class QEmbeddedViewWidget : public QWidget @@ -66,7 +66,7 @@ class QGenodeViewWidget : public QEmbeddedViewWidget protected: - Gui::Session_client *gui; + Gui::Connection *gui; Gui::Session::View_handle view_handle; virtual void showEvent(QShowEvent *event); @@ -78,7 +78,7 @@ public: QGenodeViewWidget(QWidget *parent =0); ~QGenodeViewWidget(); - void setGenodeView(Gui::Session_client *gui, + void setGenodeView(Gui::Connection *gui, Gui::Session::View_handle view_handle, int buf_x, int buf_y, int w, int h); }; diff --git a/repos/libports/lib/symbols/libqgenodeviewwidget b/repos/libports/lib/symbols/libqgenodeviewwidget index 2b403b2261..274db8d141 100644 --- a/repos/libports/lib/symbols/libqgenodeviewwidget +++ b/repos/libports/lib/symbols/libqgenodeviewwidget @@ -2,7 +2,7 @@ _ZN17QGenodeViewWidget10paintEventEP11QPaintEvent T _ZN17QGenodeViewWidget11qt_metacallEN11QMetaObject4CallEiPPv T _ZN17QGenodeViewWidget11qt_metacastEPKc T _ZN17QGenodeViewWidget12focusInEventEP11QFocusEvent T -_ZN17QGenodeViewWidget13setGenodeViewEPN3Gui14Session_clientEN6Genode6HandleINS0_4ViewEEEiiii T +_ZN17QGenodeViewWidget13setGenodeViewEPN3Gui10ConnectionEN6Genode6HandleINS0_4ViewEEEiiii T _ZN17QGenodeViewWidget16staticMetaObjectE D 48 _ZN17QGenodeViewWidget9hideEventEP10QHideEvent T _ZN17QGenodeViewWidget9showEventEP10QShowEvent T diff --git a/repos/libports/src/lib/qgenodeviewwidget/qgenodeviewwidget.cpp b/repos/libports/src/lib/qgenodeviewwidget/qgenodeviewwidget.cpp index 4ba4fd9ab8..e8e81e3457 100644 --- a/repos/libports/src/lib/qgenodeviewwidget/qgenodeviewwidget.cpp +++ b/repos/libports/src/lib/qgenodeviewwidget/qgenodeviewwidget.cpp @@ -137,7 +137,7 @@ QGenodeViewWidget::QGenodeViewWidget(QWidget *parent) { } -void QGenodeViewWidget::setGenodeView(Gui::Session_client *new_gui, +void QGenodeViewWidget::setGenodeView(Gui::Connection *new_gui, Gui::Session::View_handle new_view_handle, int buf_x, int buf_y, int w, int h) { @@ -236,5 +236,5 @@ void QGenodeViewWidget::focusInEvent(QFocusEvent *) QGenodePlatformWindow *platform_window = dynamic_cast(window()->windowHandle()->handle()); - platform_window->gui_session().focus(gui->rpc_cap()); + platform_window->gui_session().focus(gui->cap()); } diff --git a/repos/os/include/gui_session/client.h b/repos/os/include/gui_session/client.h index 4d08348d4e..3404695e95 100644 --- a/repos/os/include/gui_session/client.h +++ b/repos/os/include/gui_session/client.h @@ -21,25 +21,12 @@ namespace Gui { struct Session_client; } -class Gui::Session_client : public Rpc_client +struct Gui::Session_client : Rpc_client { - private: - - Attached_dataspace _command_ds; - - Command_buffer &_command_buffer; - - public: - /** * Constructor */ - Session_client(Region_map &rm, Session_capability session) - : - Rpc_client(session), - _command_ds(rm, command_dataspace()), - _command_buffer(*_command_ds.local_addr()) - { } + Session_client(Session_capability session) : Rpc_client(session) { } Framebuffer::Session_capability framebuffer_session() override { return call(); } @@ -47,17 +34,17 @@ class Gui::Session_client : public Rpc_client Input::Session_capability input_session() override { return call(); } - View_handle create_view() override { + Create_view_result create_view() override { return call(); } - View_handle create_child_view(View_handle parent) override { + Create_child_view_result create_child_view(View_handle parent) override { return call(parent); } void destroy_view(View_handle view) override { call(view); } - View_handle view_handle(View_capability view, - View_handle handle = View_handle()) override + View_handle_result view_handle(View_capability view, + View_handle handle = View_handle()) override { return call(view, handle); } @@ -71,11 +58,7 @@ class Gui::Session_client : public Rpc_client Dataspace_capability command_dataspace() override { return call(); } - void execute() override - { - call(); - _command_buffer.reset(); - } + void execute() override { call(); } Framebuffer::Mode mode() override { return call(); } @@ -83,30 +66,12 @@ class Gui::Session_client : public Rpc_client void mode_sigh(Signal_context_capability sigh) override { call(sigh); } - void buffer(Framebuffer::Mode mode, bool alpha) override { - call(mode, alpha); } + Buffer_result buffer(Framebuffer::Mode mode, bool alpha) override { + return call(mode, alpha); } void focus(Gui::Session_capability session) override { call(session); } - /** - * Enqueue command to command buffer - * - * The submitted command is not executed immediately. To execute a - * batch of enqueued commands, the 'execute' method must be called. - * Only in the corner case when there is not space left in the command - * buffer, the 'execute' is called to make room in the buffer. - */ - template - void enqueue(auto &&... args) { enqueue(Command( CMD { args... } )); } - - void enqueue(Command const &command) - { - if (_command_buffer.full()) - execute(); - - _command_buffer.enqueue(command); - } }; #endif /* _INCLUDE__GUI_SESSION__CLIENT_H_ */ diff --git a/repos/os/include/gui_session/connection.h b/repos/os/include/gui_session/connection.h index 7e641dd53b..d563eeb91a 100644 --- a/repos/os/include/gui_session/connection.h +++ b/repos/os/include/gui_session/connection.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2008-2017 Genode Labs GmbH + * Copyright (C) 2008-2024 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. @@ -22,45 +22,43 @@ namespace Gui { class Connection; } -class Gui::Connection : public Genode::Connection, - public Session_client +class Gui::Connection : private Genode::Connection { private: - Framebuffer::Session_client _framebuffer; - Input::Session_client _input; - size_t _session_quota = 0; + Env &_env; + + Session_client _client { cap() }; + + Attached_dataspace _command_ds { _env.rm(), _client.command_dataspace() }; + + using Command_buffer = Gui::Session::Command_buffer; + + Command_buffer &_command_buffer { *_command_ds.local_addr() }; + + Framebuffer::Session_client _framebuffer { _client.framebuffer_session() }; + + Input::Session_client _input { _env.rm(), _client.input_session() }; + + Ram_quota _ram_quota { }; /* session quota donated for virtual frame buffer */ public: + using View_handle = Session::View_handle; + using Genode::Connection::cap; + using Genode::Connection::upgrade; + using Genode::Connection::upgrade_ram; + using Genode::Connection::upgrade_caps; + /** * Constructor */ - Connection(Env &env, Label const &label = Label()) + Connection(Env &env, Session_label const &label = { }) : - /* establish nitpicker session */ Genode::Connection(env, label, Ram_quota { 36*1024 }, Args()), - Session_client(env.rm(), cap()), - - /* request frame-buffer and input sub sessions */ - _framebuffer(framebuffer_session()), - _input(env.rm(), input_session()) + _env(env) { } - void buffer(Framebuffer::Mode mode, bool use_alpha) override - { - size_t const needed = ram_quota(mode, use_alpha); - size_t const upgrade = needed > _session_quota - ? needed - _session_quota - : 0; - if (upgrade > 0) { - this->upgrade_ram(upgrade); - _session_quota += upgrade; - } - - Session_client::buffer(mode, use_alpha); - } - /** * Return sub session for GUI's input service */ @@ -70,6 +68,137 @@ class Gui::Connection : public Genode::Connection, * Return sub session for session's frame buffer */ Framebuffer::Session *framebuffer() { return &_framebuffer; } + + View_handle create_view() + { + View_handle result { }; + for (bool retry = false; ; ) { + using Error = Session_client::Create_view_error; + _client.create_view().with_result( + [&] (View_handle handle) { result = handle; }, + [&] (Error e) { + switch (e) { + case Error::OUT_OF_RAM: upgrade_ram(8*1024); retry = true; return; + case Error::OUT_OF_CAPS: upgrade_caps(2); retry = true; return; + } + }); + if (!retry) + break; + } + return result; + } + + View_handle create_child_view(View_handle parent) + { + View_handle result { }; + for (bool retry = false; ; ) { + using Error = Session_client::Create_child_view_error; + _client.create_child_view(parent).with_result( + [&] (View_handle handle) { result = handle; }, + [&] (Error e) { + switch (e) { + case Error::OUT_OF_RAM: upgrade_ram(8*1024); retry = true; return; + case Error::OUT_OF_CAPS: upgrade_caps(2); retry = true; return; + case Error::INVALID: break; + } + error("failed to create child view for invalid parent view"); + }); + if (!retry) + break; + } + return result; + } + + void destroy_view(View_handle view) + { + _client.destroy_view(view); + } + + void release_view_handle(View_handle handle) + { + _client.release_view_handle(handle); + } + + View_capability view_capability(View_handle handle) + { + return _client.view_capability(handle); + } + + View_handle view_handle(View_capability view, View_handle handle = { }) + { + View_handle result { }; + for (bool retry = false; ; ) { + using Error = Session_client::View_handle_error; + _client.view_handle(view, handle).with_result( + [&] (View_handle handle) { result = handle; }, + [&] (Error e) { + switch (e) { + case Error::OUT_OF_RAM: upgrade_ram(8*1024); retry = true; return; + case Error::OUT_OF_CAPS: upgrade_caps(2); retry = true; return; + } + }); + if (!retry) + break; + } + return result; + } + + void buffer(Framebuffer::Mode mode, bool use_alpha) + { + size_t const needed = Session_client::ram_quota(mode, use_alpha); + size_t const upgrade = needed > _ram_quota.value + ? needed - _ram_quota.value : 0u; + if (upgrade > 0) { + this->upgrade_ram(upgrade); + _ram_quota.value += upgrade; + } + + for (bool retry = false; ; ) { + using Result = Session_client::Buffer_result; + auto const result = _client.buffer(mode, use_alpha); + if (result == Result::OUT_OF_RAM) { upgrade_ram(8*1024); retry = true; } + if (result == Result::OUT_OF_CAPS) { upgrade_caps(2); retry = true; } + if (!retry) + break; + } + } + + /** + * Enqueue command to command buffer + * + * The submitted command is not executed immediately. To execute a + * batch of enqueued commands, the 'execute' method must be called. + * Only in the corner case when there is not space left in the command + * buffer, the 'execute' is called to make room in the buffer. + */ + template + void enqueue(auto &&... args) { enqueue(Session::Command( CMD { args... } )); } + + void enqueue(Session::Command const &command) + { + if (_command_buffer.full()) + execute(); + + _command_buffer.enqueue(command); + } + + void execute() + { + _client.execute(); + _command_buffer.reset(); + } + + /** + * Return physical screen mode + */ + Framebuffer::Mode mode() { return _client.mode(); } + + /** + * Register signal handler to be notified about mode changes + */ + void mode_sigh(Signal_context_capability sigh) { _client.mode_sigh(sigh); } + + void focus(Capability focused) { _client.focus(focused); } }; #endif /* _INCLUDE__GUI_SESSION__CONNECTION_H_ */ diff --git a/repos/os/include/gui_session/gui_session.h b/repos/os/include/gui_session/gui_session.h index 801f35ee1c..a495eb4df6 100644 --- a/repos/os/include/gui_session/gui_session.h +++ b/repos/os/include/gui_session/gui_session.h @@ -195,32 +195,36 @@ struct Gui::Session : Genode::Session */ virtual Input::Session_capability input_session() = 0; + enum class Create_view_error { OUT_OF_RAM, OUT_OF_CAPS }; + using Create_view_result = Attempt; + /** * Create a new top-level view at the buffer - * - * \throw Invalid_handle - * \return handle for new view */ - virtual View_handle create_view() = 0; + virtual Create_view_result create_view() = 0; + + enum class Create_child_view_error { OUT_OF_RAM, OUT_OF_CAPS, INVALID }; + using Create_child_view_result = Attempt; /** * Create a new child view at the buffer * - * \param parent parent view - * - * \throw Invalid_handle + * \param parent parent view * \return handle for new view * * The 'parent' argument allows the client to use the location of an * existing view as the coordinate origin for the to-be-created view. */ - virtual View_handle create_child_view(View_handle parent) = 0; + virtual Create_child_view_result create_child_view(View_handle parent) = 0; /** * Destroy view */ virtual void destroy_view(View_handle) = 0; + enum class View_handle_error { OUT_OF_RAM, OUT_OF_CAPS }; + using View_handle_result = Attempt; + /** * Return session-local handle for the specified view * @@ -229,12 +233,9 @@ struct Gui::Session : Genode::Session * * \param handle designated view handle to be assigned to the imported * view. By default, a new handle will be allocated. - * - * \throw Out_of_ram - * \throw Out_of_caps */ - virtual View_handle view_handle(View_capability, - View_handle handle = View_handle()) = 0; + virtual View_handle_result view_handle(View_capability, + View_handle handle = View_handle()) = 0; /** * Request view capability for a given handle @@ -269,14 +270,12 @@ struct Gui::Session : Genode::Session */ virtual void mode_sigh(Signal_context_capability) = 0; + enum class Buffer_result { OK, OUT_OF_RAM, OUT_OF_CAPS }; + /** * Define dimensions of virtual framebuffer - * - * \throw Out_of_ram session quota does not suffice for specified - * buffer dimensions - * \throw Out_of_caps */ - virtual void buffer(Framebuffer::Mode mode, bool use_alpha) = 0; + virtual Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) = 0; /** * Set focused session @@ -312,13 +311,10 @@ struct Gui::Session : Genode::Session GENODE_RPC(Rpc_framebuffer_session, Framebuffer::Session_capability, framebuffer_session); GENODE_RPC(Rpc_input_session, Input::Session_capability, input_session); - GENODE_RPC_THROW(Rpc_create_view, View_handle, create_view, - GENODE_TYPE_LIST(Out_of_ram, Out_of_caps)); - GENODE_RPC_THROW(Rpc_create_child_view, View_handle, create_child_view, - GENODE_TYPE_LIST(Out_of_ram, Out_of_caps, Invalid_handle), View_handle); + GENODE_RPC(Rpc_create_view, Create_view_result, create_view); + GENODE_RPC(Rpc_create_child_view, Create_child_view_result, create_child_view, View_handle); GENODE_RPC(Rpc_destroy_view, void, destroy_view, View_handle); - GENODE_RPC_THROW(Rpc_view_handle, View_handle, view_handle, - GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), View_capability, View_handle); + GENODE_RPC(Rpc_view_handle, View_handle_result, view_handle, View_capability, View_handle); GENODE_RPC(Rpc_view_capability, View_capability, view_capability, View_handle); GENODE_RPC(Rpc_release_view_handle, void, release_view_handle, View_handle); GENODE_RPC(Rpc_command_dataspace, Dataspace_capability, command_dataspace); @@ -327,8 +323,7 @@ struct Gui::Session : Genode::Session GENODE_RPC(Rpc_mode, Framebuffer::Mode, mode); GENODE_RPC(Rpc_mode_sigh, void, mode_sigh, Signal_context_capability); GENODE_RPC(Rpc_focus, void, focus, Capability); - GENODE_RPC_THROW(Rpc_buffer, void, buffer, GENODE_TYPE_LIST(Out_of_ram, Out_of_caps), - Framebuffer::Mode, bool); + GENODE_RPC(Rpc_buffer, Buffer_result, buffer, Framebuffer::Mode, bool); GENODE_RPC_INTERFACE(Rpc_framebuffer_session, Rpc_input_session, Rpc_create_view, Rpc_create_child_view, Rpc_destroy_view, diff --git a/repos/os/src/server/nitpicker/gui_session.cc b/repos/os/src/server/nitpicker/gui_session.cc index 54aa658e26..611ab3b871 100644 --- a/repos/os/src/server/nitpicker/gui_session.cc +++ b/repos/os/src/server/nitpicker/gui_session.cc @@ -241,18 +241,22 @@ void Gui_session::_adopt_new_view(View &view) } -Gui_session::View_handle Gui_session::create_view() +Gui_session::Create_view_result Gui_session::create_view() { - View &view = *new (_view_alloc) - View(*this, _texture, { .transparent = false, .background = false }, nullptr); + try { + View &view = *new (_view_alloc) + View(*this, _texture, { .transparent = false, .background = false }, nullptr); - _adopt_new_view(view); + _adopt_new_view(view); - return _view_handle_registry.alloc(view); + return _view_handle_registry.alloc(view); + } + catch (Out_of_ram) { return Create_view_error::OUT_OF_RAM; } + catch (Out_of_caps) { return Create_view_error::OUT_OF_CAPS; } } -Gui_session::View_handle Gui_session::create_child_view(View_handle const parent_handle) +Gui_session::Create_child_view_result Gui_session::create_child_view(View_handle const parent_handle) { View *parent_view_ptr = nullptr; @@ -264,16 +268,20 @@ Gui_session::View_handle Gui_session::create_child_view(View_handle const parent catch (View_handle_registry::Lookup_failed) { } if (!parent_view_ptr) - return View_handle(); + return Create_child_view_error::INVALID; - View &view = *new (_view_alloc) - View(*this, _texture, { .transparent = false, .background = false }, parent_view_ptr); + try { + View &view = *new (_view_alloc) + View(*this, _texture, { .transparent = false, .background = false }, parent_view_ptr); - parent_view_ptr->add_child(view); + parent_view_ptr->add_child(view); - _adopt_new_view(view); + _adopt_new_view(view); - return _view_handle_registry.alloc(view); + return _view_handle_registry.alloc(view); + } + catch (Out_of_ram) { return Create_child_view_error::OUT_OF_RAM; } + catch (Out_of_caps) { return Create_child_view_error::OUT_OF_CAPS; } } @@ -341,19 +349,17 @@ void Gui_session::destroy_view(View_handle handle) } -Gui_session::View_handle +Gui_session::View_handle_result Gui_session::view_handle(View_capability view_cap, View_handle handle) { - auto lambda = [&] (View *view) - { - return (view) ? _view_handle_registry.alloc(*view, handle) - : View_handle(); - }; - try { - return _env.ep().rpc_ep().apply(view_cap, lambda); + return _env.ep().rpc_ep().apply(view_cap, [&] (View *view) { + return (view) ? _view_handle_registry.alloc(*view, handle) + : View_handle(); }); } - catch (View_handle_registry::Out_of_memory) { throw Out_of_ram(); } + catch (View_handle_registry::Out_of_memory) { return View_handle_error::OUT_OF_RAM; } + catch (Out_of_ram) { return View_handle_error::OUT_OF_RAM; } + catch (Out_of_caps) { return View_handle_error::OUT_OF_RAM; } } @@ -404,17 +410,18 @@ Framebuffer::Mode Gui_session::mode() } -void Gui_session::buffer(Framebuffer::Mode mode, bool use_alpha) +Gui_session::Buffer_result Gui_session::buffer(Framebuffer::Mode mode, bool use_alpha) { /* check if the session quota suffices for the specified mode */ if (_buffer_size + _ram_quota_guard().avail().value < ram_quota(mode, use_alpha)) - throw Out_of_ram(); + return Buffer_result::OUT_OF_RAM; /* buffer re-allocation may consume new dataspace capability if buffer is new */ if (_cap_quota_guard().avail().value < 1) - throw Out_of_caps(); + throw Buffer_result::OUT_OF_CAPS; _framebuffer_session_component.notify_mode_change(mode, use_alpha); + return Buffer_result::OK; } diff --git a/repos/os/src/server/nitpicker/gui_session.h b/repos/os/src/server/nitpicker/gui_session.h index 81ec6e65ef..bbcc3dd3f7 100644 --- a/repos/os/src/server/nitpicker/gui_session.h +++ b/repos/os/src/server/nitpicker/gui_session.h @@ -348,13 +348,13 @@ class Nitpicker::Gui_session : public Session_object, Input::Session_capability input_session() override { return _input_session_cap; } - View_handle create_view() override; + Create_view_result create_view() override; - View_handle create_child_view(View_handle parent_handle) override; + Create_child_view_result create_child_view(View_handle parent_handle) override; void destroy_view(View_handle handle) override; - View_handle view_handle(View_capability view_cap, View_handle handle) override; + View_handle_result view_handle(View_capability view_cap, View_handle handle) override; View_capability view_capability(View_handle handle) override; @@ -368,7 +368,7 @@ class Nitpicker::Gui_session : public Session_object, void mode_sigh(Signal_context_capability sigh) override { _mode_sigh = sigh; } - void buffer(Framebuffer::Mode mode, bool use_alpha) override; + Buffer_result buffer(Framebuffer::Mode mode, bool use_alpha) override; void focus(Capability session_cap) override;