mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
gui_session: split alloc_view_handle, view_handle
Express the allocation of a new view handle by a dedicated RPC function instead of passing an invalid view handle to the existing 'view_handle' function. This eliminates the notion of invalid view handles at the GUI session interface, clearing the way for managing view handles via an Id_space. Issue #5242
This commit is contained in:
parent
f274ed549e
commit
4e711d4738
@ -130,6 +130,9 @@ struct Gui::Session_component : Rpc_object<Gui::Session>
|
||||
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); }
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,6 +134,9 @@ struct Sandboxed_runtime::Gui_session : Session_object<Gui::Session>
|
||||
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); }
|
||||
|
||||
|
@ -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
|
||||
|
@ -386,6 +386,11 @@ struct Wm::Decorator_gui_session : Genode::Rpc_object<Gui::Session>,
|
||||
_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);
|
||||
|
@ -80,6 +80,11 @@ class Wm::Direct_gui_session : public Genode::Rpc_object<Gui::Session>
|
||||
_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);
|
||||
|
@ -153,7 +153,7 @@ class Wm::Gui::View : private Genode::Weak_object<View>,
|
||||
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<Child_view>::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<Gui::Session>,
|
||||
} 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
|
||||
|
@ -68,11 +68,16 @@ struct Wm::Layouter_gui_session : Genode::Rpc_object<Gui::Session>
|
||||
|
||||
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();
|
||||
|
@ -222,7 +222,7 @@ void QGenodeViewWidget::paintEvent(QPaintEvent *event)
|
||||
dynamic_cast<QGenodePlatformWindow*>(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<Command::Front_of>(view_handle, neighbor_handle);
|
||||
gui->execute();
|
||||
|
@ -39,8 +39,12 @@ struct Gui::Session_client : Rpc_client<Session>
|
||||
void destroy_view(View_handle view) override {
|
||||
call<Rpc_destroy_view>(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<Rpc_alloc_view_handle>(view);
|
||||
}
|
||||
|
||||
View_handle_result view_handle(View_capability view, View_handle handle) override
|
||||
{
|
||||
return call<Rpc_view_handle>(view, handle);
|
||||
}
|
||||
|
@ -120,18 +120,20 @@ class Gui::Connection : private Genode::Connection<Session>
|
||||
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<Session>
|
||||
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);
|
||||
|
@ -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<View_handle, View_handle_error>;
|
||||
enum class Alloc_view_handle_error { OUT_OF_RAM, OUT_OF_CAPS, INVALID };
|
||||
using Alloc_view_handle_result = Attempt<View_handle, Alloc_view_handle_error>;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
@ -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; }
|
||||
}
|
||||
|
||||
|
||||
|
@ -354,6 +354,8 @@ class Nitpicker::Gui_session : public Session_object<Gui::Session>,
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user