diff --git a/repos/gems/src/app/sculpt_manager/gui.cc b/repos/gems/src/app/sculpt_manager/gui.cc index 0d92433ade..394cf084b6 100644 --- a/repos/gems/src/app/sculpt_manager/gui.cc +++ b/repos/gems/src/app/sculpt_manager/gui.cc @@ -130,6 +130,9 @@ struct Gui::Session_component : Rpc_object void destroy_view(View_handle view) override { _gui_session.destroy_view(view); } + Alloc_view_handle_result alloc_view_handle(View_capability view_cap) override { + return _gui_session.alloc_view_handle(view_cap); } + View_handle_result view_handle(View_capability view_cap, View_handle handle) override { return _gui_session.view_handle(view_cap, handle); } diff --git a/repos/gems/src/app/themed_decorator/window.h b/repos/gems/src/app/themed_decorator/window.h index 8675c59f9e..91ef4df78d 100644 --- a/repos/gems/src/app/themed_decorator/window.h +++ b/repos/gems/src/app/themed_decorator/window.h @@ -172,7 +172,7 @@ class Decorator::Window : public Window_base, public Animator::Item Gui::View_capability view_cap = remote_gui.view_capability(handle); /* import remote view into local GUI session */ - return _gui.view_handle(view_cap); + return _gui.alloc_view_handle(view_cap); } /** diff --git a/repos/gems/src/lib/dialog/sandboxed_runtime.cc b/repos/gems/src/lib/dialog/sandboxed_runtime.cc index 5a834c0533..0a0c1acf48 100644 --- a/repos/gems/src/lib/dialog/sandboxed_runtime.cc +++ b/repos/gems/src/lib/dialog/sandboxed_runtime.cc @@ -134,6 +134,9 @@ struct Sandboxed_runtime::Gui_session : Session_object void destroy_view(View_handle view) override { _gui_session.destroy_view(view); } + Alloc_view_handle_result alloc_view_handle(View_capability view_cap) override { + return _gui_session.alloc_view_handle(view_cap); } + View_handle_result view_handle(View_capability view_cap, View_handle handle) override { return _gui_session.view_handle(view_cap, handle); } diff --git a/repos/gems/src/server/gui_fader/main.cc b/repos/gems/src/server/gui_fader/main.cc index b57fb231d7..f839f7169b 100644 --- a/repos/gems/src/server/gui_fader/main.cc +++ b/repos/gems/src/server/gui_fader/main.cc @@ -364,10 +364,16 @@ class Gui_fader::Gui_session_component return _gui.destroy_view(handle); } + Alloc_view_handle_result alloc_view_handle(View_capability view_cap) override + { + return _gui.alloc_view_handle(view_cap); + } + View_handle_result view_handle(View_capability view_cap, View_handle handle) override { - return _gui.view_handle(view_cap, handle); + _gui.view_handle(view_cap, handle); + return View_handle_result::OK; } View_capability view_capability(View_handle handle) override diff --git a/repos/gems/src/server/wm/decorator_gui.h b/repos/gems/src/server/wm/decorator_gui.h index df4e9a1fab..aca42a93ff 100644 --- a/repos/gems/src/server/wm/decorator_gui.h +++ b/repos/gems/src/server/wm/decorator_gui.h @@ -386,6 +386,11 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object, _gui.session.destroy_view(view); } + Alloc_view_handle_result alloc_view_handle(View_capability view_cap) override + { + return _gui.session.alloc_view_handle(view_cap); + } + View_handle_result view_handle(View_capability view_cap, View_handle handle) override { return _gui.session.view_handle(view_cap, handle); diff --git a/repos/gems/src/server/wm/direct_gui.h b/repos/gems/src/server/wm/direct_gui.h index 2bd175716e..229d71c02b 100644 --- a/repos/gems/src/server/wm/direct_gui.h +++ b/repos/gems/src/server/wm/direct_gui.h @@ -80,6 +80,11 @@ class Wm::Direct_gui_session : public Genode::Rpc_object _session.destroy_view(view); } + Alloc_view_handle_result alloc_view_handle(Gui::View_capability view_cap) override + { + return _session.alloc_view_handle(view_cap); + } + View_handle_result view_handle(Gui::View_capability view_cap, View_handle handle) override { return _session.view_handle(view_cap, handle); diff --git a/repos/gems/src/server/wm/gui.h b/repos/gems/src/server/wm/gui.h index e73548c97e..d9205e161e 100644 --- a/repos/gems/src/server/wm/gui.h +++ b/repos/gems/src/server/wm/gui.h @@ -153,7 +153,7 @@ class Wm::Gui::View : private Genode::Weak_object, View_handle real_neighbor_handle; if (neighbor.valid()) - _real_gui.session.view_handle(neighbor->real_view_cap()).with_result( + _real_gui.session.alloc_view_handle(neighbor->real_view_cap()).with_result( [&] (View_handle handle) { real_neighbor_handle = handle; }, [&] (auto) { warning("unable to obtain real_neighbor_handle"); } ); @@ -451,9 +451,9 @@ class Wm::Gui::Child_view : public View, private List::Element return; View_handle parent_handle { }; - _real_gui.session.view_handle(parent->real_view_cap()).with_result( + _real_gui.session.alloc_view_handle(parent->real_view_cap()).with_result( [&] (View_handle handle) { parent_handle = handle; }, - [&] (Gui::Session::View_handle_error) { } + [&] (Gui::Session::Alloc_view_handle_error) { } ); if (!parent_handle.valid()) { warning("try_to_init_real_view failed to obtain parent handle"); @@ -1005,15 +1005,27 @@ class Wm::Gui::Session_component : public Rpc_object, } catch (View_handle_registry::Lookup_failed) { } } - View_handle_result view_handle(View_capability view_cap, View_handle handle) override + Alloc_view_handle_result alloc_view_handle(View_capability view_cap) override { try { return _env.ep().rpc_ep().apply(view_cap, [&] (View *view) { - return (view) ? _view_handle_registry.alloc(*view, handle) + return (view) ? _view_handle_registry.alloc(*view) : View_handle(); }); } - catch (Out_of_ram) { return View_handle_error::OUT_OF_RAM; } - catch (Out_of_caps) { return View_handle_error::OUT_OF_CAPS; } + catch (Out_of_ram) { return Alloc_view_handle_error::OUT_OF_RAM; } + catch (Out_of_caps) { return Alloc_view_handle_error::OUT_OF_CAPS; } + } + + View_handle_result view_handle(View_capability view_cap, View_handle handle) override + { + try { + _env.ep().rpc_ep().apply(view_cap, [&] (View *view) { + if (view) + _view_handle_registry.alloc(*view, handle); }); + return View_handle_result::OK; + } + catch (Out_of_ram) { return View_handle_result::OUT_OF_RAM; } + catch (Out_of_caps) { return View_handle_result::OUT_OF_CAPS; } } View_capability view_capability(View_handle handle) override diff --git a/repos/gems/src/server/wm/layouter_gui.h b/repos/gems/src/server/wm/layouter_gui.h index e3f3ddfeb2..7da6bd16f8 100644 --- a/repos/gems/src/server/wm/layouter_gui.h +++ b/repos/gems/src/server/wm/layouter_gui.h @@ -68,11 +68,16 @@ struct Wm::Layouter_gui_session : Genode::Rpc_object void destroy_view(View_handle) override { } - View_handle_result view_handle(View_capability, View_handle) override + Alloc_view_handle_result alloc_view_handle(View_capability) override { return View_handle(); } + View_handle_result view_handle(View_capability, View_handle) override + { + return View_handle_result::OK; + } + View_capability view_capability(View_handle) override { return View_capability(); diff --git a/repos/libports/src/lib/qgenodeviewwidget/qgenodeviewwidget.cpp b/repos/libports/src/lib/qgenodeviewwidget/qgenodeviewwidget.cpp index f5d27e16e1..1aa12b4359 100644 --- a/repos/libports/src/lib/qgenodeviewwidget/qgenodeviewwidget.cpp +++ b/repos/libports/src/lib/qgenodeviewwidget/qgenodeviewwidget.cpp @@ -222,7 +222,7 @@ void QGenodeViewWidget::paintEvent(QPaintEvent *event) dynamic_cast(window()->windowHandle()->handle()); Gui::Session::View_handle const neighbor_handle = - gui->view_handle(platform_window->view_cap()); + gui->alloc_view_handle(platform_window->view_cap()); gui->enqueue(view_handle, neighbor_handle); gui->execute(); diff --git a/repos/os/include/gui_session/client.h b/repos/os/include/gui_session/client.h index ef5091acf9..13d1398288 100644 --- a/repos/os/include/gui_session/client.h +++ b/repos/os/include/gui_session/client.h @@ -39,8 +39,12 @@ struct Gui::Session_client : Rpc_client void destroy_view(View_handle view) override { call(view); } - View_handle_result view_handle(View_capability view, - View_handle handle = View_handle()) override + Alloc_view_handle_result alloc_view_handle(View_capability view) override + { + return call(view); + } + + View_handle_result view_handle(View_capability view, View_handle handle) override { return call(view, handle); } diff --git a/repos/os/include/gui_session/connection.h b/repos/os/include/gui_session/connection.h index 14007b6060..3ef2514e9d 100644 --- a/repos/os/include/gui_session/connection.h +++ b/repos/os/include/gui_session/connection.h @@ -120,18 +120,20 @@ class Gui::Connection : private Genode::Connection return _client.view_capability(handle); } - View_handle view_handle(View_capability view, View_handle handle = { }) + View_handle alloc_view_handle(View_capability view) { View_handle result { }; for (bool retry = false; ; ) { - using Error = Session_client::View_handle_error; - _client.view_handle(view, handle).with_result( + using Error = Session_client::Alloc_view_handle_error; + _client.alloc_view_handle(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; + case Error::INVALID: break; } + warning("attempt to alloc handle for invalid view"); }); if (!retry) break; @@ -139,6 +141,21 @@ class Gui::Connection : private Genode::Connection return result; } + void view_handle(View_capability view, View_handle handle) + { + using Result = Session::View_handle_result; + for (;;) { + switch (_client.view_handle(view, handle)) { + case Result::OUT_OF_RAM: upgrade_ram(8*1024); break; + case Result::OUT_OF_CAPS: upgrade_caps(2); break; + case Result::OK: return; + case Result::INVALID: + warning("attempt to create handle for invalid view"); + return; + } + } + } + void buffer(Framebuffer::Mode mode, bool use_alpha) { size_t const needed = Session_client::ram_quota(mode, use_alpha); diff --git a/repos/os/include/gui_session/gui_session.h b/repos/os/include/gui_session/gui_session.h index 38708d4da6..a298493f21 100644 --- a/repos/os/include/gui_session/gui_session.h +++ b/repos/os/include/gui_session/gui_session.h @@ -201,20 +201,23 @@ struct Gui::Session : Genode::Session */ virtual void destroy_view(View_handle) = 0; - enum class View_handle_error { OUT_OF_RAM, OUT_OF_CAPS }; - using View_handle_result = Attempt; + enum class Alloc_view_handle_error { OUT_OF_RAM, OUT_OF_CAPS, INVALID }; + using Alloc_view_handle_result = Attempt; /** * Return session-local handle for the specified view * * The handle returned by this method can be used to issue commands * via the 'execute' method. - * - * \param handle designated view handle to be assigned to the imported - * view. By default, a new handle will be allocated. */ - virtual View_handle_result view_handle(View_capability, - View_handle handle = View_handle()) = 0; + virtual Alloc_view_handle_result alloc_view_handle(View_capability) = 0; + + enum class View_handle_result { OK, OUT_OF_RAM, OUT_OF_CAPS, INVALID }; + + /** + * Associate view with the specified handle + */ + virtual View_handle_result view_handle(View_capability, View_handle) = 0; /** * Request view capability for a given handle @@ -293,6 +296,7 @@ struct Gui::Session : Genode::Session 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(Rpc_alloc_view_handle, Alloc_view_handle_result, alloc_view_handle, View_capability); 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); @@ -306,7 +310,8 @@ struct Gui::Session : Genode::Session GENODE_RPC_INTERFACE(Rpc_framebuffer, Rpc_input, Rpc_create_view, Rpc_create_child_view, Rpc_destroy_view, - Rpc_view_handle, Rpc_view_capability, Rpc_release_view_handle, + Rpc_alloc_view_handle, Rpc_view_handle, + Rpc_view_capability, Rpc_release_view_handle, Rpc_command_dataspace, Rpc_execute, Rpc_mode, Rpc_mode_sigh, Rpc_buffer, Rpc_focus); }; diff --git a/repos/os/src/server/nitpicker/gui_session.cc b/repos/os/src/server/nitpicker/gui_session.cc index 5464314692..7843d3db94 100644 --- a/repos/os/src/server/nitpicker/gui_session.cc +++ b/repos/os/src/server/nitpicker/gui_session.cc @@ -355,17 +355,35 @@ void Gui_session::destroy_view(View_handle handle) } +Gui_session::Alloc_view_handle_result +Gui_session::alloc_view_handle(View_capability view_cap) +{ + try { + return _env.ep().rpc_ep().apply(view_cap, [&] (View *view_ptr) -> Alloc_view_handle_result { + if (!view_ptr) + return Alloc_view_handle_error::INVALID; + return _view_handle_registry.alloc(*view_ptr); }); + } + catch (View_handle_registry::Out_of_memory) { return Alloc_view_handle_error::OUT_OF_RAM; } + catch (Out_of_ram) { return Alloc_view_handle_error::OUT_OF_RAM; } + catch (Out_of_caps) { return Alloc_view_handle_error::OUT_OF_RAM; } +} + + Gui_session::View_handle_result Gui_session::view_handle(View_capability view_cap, View_handle handle) { try { - return _env.ep().rpc_ep().apply(view_cap, [&] (View *view) { - return (view) ? _view_handle_registry.alloc(*view, handle) - : View_handle(); }); + return _env.ep().rpc_ep().apply(view_cap, [&] (View *view_ptr) -> View_handle_result { + if (!view_ptr) + return View_handle_result::INVALID; + _view_handle_registry.alloc(*view_ptr, handle); + return View_handle_result::OK; + }); } - 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; } + catch (View_handle_registry::Out_of_memory) { return View_handle_result::OUT_OF_RAM; } + catch (Out_of_ram) { return View_handle_result::OUT_OF_RAM; } + catch (Out_of_caps) { return View_handle_result::OUT_OF_RAM; } } diff --git a/repos/os/src/server/nitpicker/gui_session.h b/repos/os/src/server/nitpicker/gui_session.h index 99fe8f29a5..8800127684 100644 --- a/repos/os/src/server/nitpicker/gui_session.h +++ b/repos/os/src/server/nitpicker/gui_session.h @@ -354,6 +354,8 @@ class Nitpicker::Gui_session : public Session_object, void destroy_view(View_handle handle) override; + Alloc_view_handle_result alloc_view_handle(View_capability view_cap) override; + View_handle_result view_handle(View_capability view_cap, View_handle handle) override; View_capability view_capability(View_handle handle) override; diff --git a/repos/os/src/test/nitpicker/main.cc b/repos/os/src/test/nitpicker/main.cc index 1b7ad8d54d..04e8a2adcc 100644 --- a/repos/os/src/test/nitpicker/main.cc +++ b/repos/os/src/test/nitpicker/main.cc @@ -114,7 +114,7 @@ struct Test::Child_view : View View(gui, attr, [&] /* create_fn */ { using View_handle = Gui::Session::View_handle; - View_handle const parent_handle = gui.view_handle(parent.view_cap()); + View_handle const parent_handle = gui.alloc_view_handle(parent.view_cap()); View_handle const handle = gui.create_child_view(parent_handle); gui.release_view_handle(parent_handle); return handle;