wm: update coding style

Use Genode namespace, indicate 'Main' members as being private,
use Session_object, remove unused '_focus_request_reporter',
use Id_space for Window_registry, replace lookup by with pattern.
This commit is contained in:
Norman Feske 2024-09-09 17:30:48 +02:00
parent e83ace4242
commit 9cd87a8495
11 changed files with 336 additions and 449 deletions

View File

@ -26,20 +26,9 @@
#include <pointer.h>
#include <real_gui.h>
namespace Wm { class Main;
using Genode::Allocator;
using Genode::Arg_string;
using Genode::Object_pool;
using Genode::Attached_dataspace;
using Genode::Attached_ram_dataspace;
using Genode::Signal_handler;
using Genode::Reporter;
using Genode::Interface;
}
namespace Wm {
class Main;
struct Decorator_gui_session;
struct Decorator_content_callback;
struct Decorator_content_registry;
@ -58,7 +47,7 @@ struct Wm::Decorator_content_callback : Interface
};
struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
struct Wm::Decorator_gui_session : Session_object<Gui::Session>,
private List<Decorator_gui_session>::Element,
private Upgradeable
{
@ -81,11 +70,11 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
Gui::View_ids _content_view_ids { };
Genode::Env &_env;
Env &_env;
Genode::Constrained_ram_allocator _ram { _env.ram(), _ram_quota_guard(), _cap_quota_guard() };
Constrained_ram_allocator _ram { _env.ram(), _ram_quota_guard(), _cap_quota_guard() };
Genode::Sliced_heap _session_alloc { _ram, _env.rm() };
Sliced_heap _session_alloc { _ram, _env.rm() };
Slab<Content_view_ref, 4000> _content_view_ref_alloc { _session_alloc };
@ -93,7 +82,7 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
Input::Session_client _input_session { _env.rm(), _real_gui.session.input() };
Genode::Signal_context_capability _mode_sigh { };
Signal_context_capability _mode_sigh { };
Attached_ram_dataspace _client_command_ds { _ram, _env.rm(), sizeof(Command_buffer) };
@ -113,14 +102,14 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
Signal_handler<Decorator_gui_session>
_input_handler { _env.ep(), *this, &Decorator_gui_session::_handle_input };
Window_registry::Id _win_id_from_title(Gui::Title const &title)
void _with_win_id_from_title(Gui::Title const &title, auto const &fn)
{
unsigned value = 0;
Genode::ascii_to(title.string(), value);
return { value };
if (ascii_to(title.string(), value))
fn(Window_registry::Id { value });
}
Decorator_gui_session(Genode::Env &env,
Decorator_gui_session(Env &env,
Resources const &resources,
Label const &label,
Diag const &diag,
@ -239,8 +228,8 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
* as view title. For such views, we import the view from the
* corresponding GUI cient instead of creating a new view.
*/
Window_registry::Id const win_id = _win_id_from_title(attr.title);
if (win_id.valid()) {
bool out_of_ram = false, out_of_caps = false, associated = false;
_with_win_id_from_title(attr.title, [&] (Window_registry::Id win_id) {
try {
Content_view_ref &view_ref_ptr = *new (_content_view_ref_alloc)
Content_view_ref(Window_registry::Id(win_id), _content_view_ids, id);
@ -251,21 +240,20 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
destroy(_content_view_ref_alloc, &view_ref_ptr);
switch (result) {
case Associate_result::OUT_OF_RAM: return View_result::OUT_OF_RAM;
case Associate_result::OUT_OF_CAPS: return View_result::OUT_OF_CAPS;
case Associate_result::OK: return View_result::OK;
case Associate_result::OUT_OF_RAM: out_of_ram = true; break;
case Associate_result::OUT_OF_CAPS: out_of_caps = true; break;
case Associate_result::OK: associated = true; break;
case Associate_result::INVALID: break; /* fall back to regular view */
};
}
catch (Genode::Out_of_ram) {
_starved_for_ram = true;
return View_result::OUT_OF_RAM;
}
catch (Genode::Out_of_caps) {
_starved_for_caps = true;
return View_result::OUT_OF_CAPS;
}
}
catch (Out_of_ram) { _starved_for_ram = out_of_ram = true; }
catch (Out_of_caps) { _starved_for_caps = out_of_caps = true; }
});
if (out_of_ram) return View_result::OUT_OF_RAM;
if (out_of_caps) return View_result::OUT_OF_CAPS;
if (associated) return View_result::OK;
return _real_gui.session.view(id, attr);
}
@ -314,7 +302,7 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
_real_gui.session.release_view_id(view);
}
Genode::Dataspace_capability command_dataspace() override
Dataspace_capability command_dataspace() override
{
return _client_command_ds.cap();
}
@ -332,7 +320,7 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
return _real_gui.session.mode();
}
void mode_sigh(Genode::Signal_context_capability sigh) override
void mode_sigh(Signal_context_capability sigh) override
{
/*
* Remember signal-context capability to keep NOVA from revoking
@ -347,7 +335,7 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
return _real_gui.session.buffer(mode, use_alpha);
}
void focus(Genode::Capability<Gui::Session>) override { }
void focus(Capability<Gui::Session>) override { }
};
#endif /* _DECORATOR_GUI_H_ */

View File

@ -21,14 +21,14 @@
namespace Wm { class Direct_gui_session; }
class Wm::Direct_gui_session : public Genode::Session_object<Gui::Session>
class Wm::Direct_gui_session : public Session_object<Gui::Session>
{
private:
Genode::Env &_env;
Env &_env;
Genode::Connection<Gui::Session> _connection {
_env, _label, Genode::Ram_quota { 36*1024 }, /* Args */ { } };
Connection<Gui::Session> _connection {
_env, _label, Ram_quota { 36*1024 }, /* Args */ { } };
Gui::Session_client _session { _connection.cap() };
@ -37,7 +37,7 @@ class Wm::Direct_gui_session : public Genode::Session_object<Gui::Session>
public:
Direct_gui_session(Genode::Env &env, auto &&... args)
Direct_gui_session(Env &env, auto &&... args)
:
Session_object<Gui::Session>(env.ep(), args...),
_env(env)
@ -94,7 +94,7 @@ class Wm::Direct_gui_session : public Genode::Session_object<Gui::Session>
_session.release_view_id(view);
}
Genode::Dataspace_capability command_dataspace() override
Dataspace_capability command_dataspace() override
{
return _session.command_dataspace();
}
@ -109,7 +109,7 @@ class Wm::Direct_gui_session : public Genode::Session_object<Gui::Session>
return _session.mode();
}
void mode_sigh(Genode::Signal_context_capability sigh) override
void mode_sigh(Signal_context_capability sigh) override
{
_session.mode_sigh(sigh);
}
@ -119,7 +119,7 @@ class Wm::Direct_gui_session : public Genode::Session_object<Gui::Session>
return _session.buffer(mode, use_alpha);
}
void focus(Genode::Capability<Gui::Session> session) override
void focus(Capability<Gui::Session> session) override
{
_session.focus(session);
}

View File

@ -15,14 +15,6 @@
#define _GUI_H_
/* Genode includes */
#include <util/list.h>
#include <base/tslab.h>
#include <base/session_object.h>
#include <os/surface.h>
#include <base/attached_ram_dataspace.h>
#include <os/session_policy.h>
#include <os/reporter.h>
#include <os/session_policy.h>
#include <root/component.h>
#include <gui_session/connection.h>
#include <input_session/capability.h>
@ -34,26 +26,6 @@
#include <layouter_gui.h>
#include <direct_gui.h>
namespace Wm {
using Genode::Rpc_object;
using Genode::List;
using Genode::Allocator;
using Genode::Affinity;
using Genode::static_cap_cast;
using Genode::Signal_handler;
using Genode::Weak_ptr;
using Genode::Locked_ptr;
using Genode::Tslab;
using Genode::Attached_ram_dataspace;
using Genode::Signal_context_capability;
using Genode::Signal_transmitter;
using Genode::Reporter;
using Genode::Capability;
using Genode::Interface;
}
namespace Wm { namespace Gui {
using namespace ::Gui;
@ -66,10 +38,6 @@ namespace Wm { namespace Gui {
class Session_control_fn;
class Session_component;
class Root;
using Rect = Genode::Surface_base::Rect;
using Point = Genode::Surface_base::Point;
using Session_label = Genode::Session_label;
} }
@ -98,13 +66,12 @@ struct Wm::Gui::Input_origin_changed_handler : Interface
};
class Wm::Gui::View : private Genode::Weak_object<View>,
public Genode::Rpc_object< ::Gui::View>
class Wm::Gui::View : private Weak_object<View>, public Rpc_object< ::Gui::View>
{
private:
friend class Genode::Weak_ptr<View>;
friend class Genode::Locked_ptr<View>;
friend class Weak_ptr<View>;
friend class Locked_ptr<View>;
protected:
@ -197,8 +164,8 @@ class Wm::Gui::View : private Genode::Weak_object<View>,
_real_gui.session.destroy_view(_real_view.id());
}
using Genode::Weak_object<View>::weak_ptr;
using Genode::Weak_object<View>::lock_for_destruction;
using Weak_object<View>::weak_ptr;
using Weak_object<View>::lock_for_destruction;
Point virtual_position() const { return _geometry.at; }
@ -254,7 +221,7 @@ class Wm::Gui::Top_level_view : public View, private List<Top_level_view>::Eleme
friend class List<Top_level_view>;
Window_registry::Id _win_id { };
Window_registry::Create_result _win_id = Window_registry::Create_error::IDS_EXHAUSTED;
Window_registry &_window_registry;
@ -283,6 +250,12 @@ class Wm::Gui::Top_level_view : public View, private List<Top_level_view>::Eleme
using Command = Gui::Session::Command;
void _with_optional_win_id(auto const &fn) const
{
_win_id.with_result([&] (Window_registry::Id id) { fn(id); },
[&] (Window_registry::Create_error) { });
}
public:
Top_level_view(Real_gui &real_gui,
@ -298,8 +271,8 @@ class Wm::Gui::Top_level_view : public View, private List<Top_level_view>::Eleme
~Top_level_view()
{
if (_win_id.valid())
_window_registry.destroy(_win_id);
_with_optional_win_id([&] (Window_registry::Id id) {
_window_registry.destroy(id); });
View::lock_for_destruction();
}
@ -317,16 +290,20 @@ class Wm::Gui::Top_level_view : public View, private List<Top_level_view>::Eleme
* defer the creation of the window ID until the time when the
* initial geometry is known.
*/
if (!_win_id.valid()) {
_win_id = _window_registry.create();
_window_registry.title(_win_id, _window_title);
_window_registry.label(_win_id, _session_label);
_window_registry.has_alpha(_win_id, View::has_alpha());
_window_registry.resizeable(_win_id, _resizeable);
if (!_win_id.ok()) {
_win_id = _window_registry.create({
.title = _window_title,
.label = _session_label,
.area = geometry.area,
.alpha = { View::has_alpha() },
.hidden = { },
.resizeable = { _resizeable }
});
} else {
_with_optional_win_id([&] (Window_registry::Id id) {
_window_registry.area(id, geometry.area); });
}
_window_registry.size(_win_id, geometry.area);
View::geometry(geometry);
}
@ -338,11 +315,17 @@ class Wm::Gui::Top_level_view : public View, private List<Top_level_view>::Eleme
_window_title = title;
if (_win_id.valid())
_window_registry.title(_win_id, _window_title);
_with_optional_win_id([&] (Window_registry::Id id) {
_window_registry.title(id, _window_title); });
}
bool has_win_id(Window_registry::Id id) const { return id == _win_id; }
bool has_win_id(Window_registry::Id id) const
{
bool result = false;
_with_optional_win_id([&] (Window_registry::Id this_id) {
result = (this_id == id); });
return result;
}
bool belongs_to_win_id(Window_registry::Id id) const override
{
@ -366,14 +349,18 @@ class Wm::Gui::Top_level_view : public View, private List<Top_level_view>::Eleme
View_capability content_view() { return real_view_cap(); }
void hidden(bool hidden) { _window_registry.hidden(_win_id, hidden); }
void hidden(bool hidden)
{
_with_optional_win_id([&] (Window_registry::Id id) {
_window_registry.hidden(id, hidden); });
}
void resizeable(bool resizeable)
{
_resizeable = resizeable;
if (_win_id.valid())
_window_registry.resizeable(_win_id, resizeable);
_with_optional_win_id([&] (Window_registry::Id id) {
_window_registry.resizeable(id, resizeable); });
}
};
@ -530,12 +517,12 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
}
};
Genode::Env &_env;
Env &_env;
Genode::Constrained_ram_allocator _ram {
Constrained_ram_allocator _ram {
_env.ram(), _ram_quota_guard(), _cap_quota_guard() };
Genode::Sliced_heap _session_alloc { _ram, _env.rm() };
Sliced_heap _session_alloc { _ram, _env.rm() };
Real_gui _real_gui { _env, _label };
Window_registry &_window_registry;
Slab<Top_level_view, 8000> _top_level_view_alloc { _session_alloc };
@ -748,14 +735,14 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
{
_top_level_views.remove(&view);
_dissolve_view_from_ep(view);
Genode::destroy(&_top_level_view_alloc, &view);
destroy(&_top_level_view_alloc, &view);
}
void _destroy_child_view(Child_view &view)
{
_child_views.remove(&view);
_dissolve_view_from_ep(view);
Genode::destroy(&_child_view_alloc, &view);
destroy(&_child_view_alloc, &view);
}
void _execute_command(Command const &command)
@ -804,8 +791,8 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
char sanitized_title[args.title.capacity()];
Genode::copy_cstring(sanitized_title, command.title.title.string(),
sizeof(sanitized_title));
copy_cstring(sanitized_title, command.title.title.string(),
sizeof(sanitized_title));
for (char *c = sanitized_title; *c; c++)
if (*c == '"')
@ -825,7 +812,7 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
public:
Session_component(Genode::Env &env,
Session_component(Env &env,
Resources const &resources,
Label const &label,
Diag const diag,
@ -897,13 +884,13 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
View_capability content_view(Window_registry::Id id)
{
for (Top_level_view *v = _top_level_views.first(); v; v = v->next())
if (v->has_win_id(id.value))
if (v->has_win_id(id))
return v->content_view();
return View_capability();
}
bool has_win_id(unsigned id) const
bool has_win_id(Window_registry::Id id) const
{
for (Top_level_view const *v = _top_level_views.first(); v; v = v->next())
if (v->has_win_id(id))
@ -1146,7 +1133,7 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
[&] { });
}
Genode::Dataspace_capability command_dataspace() override
Dataspace_capability command_dataspace() override
{
return _command_ds.cap();
}
@ -1185,7 +1172,7 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
return real_mode;
}
void mode_sigh(Genode::Signal_context_capability sigh) override
void mode_sigh(Signal_context_capability sigh) override
{
_mode_sigh = sigh;
@ -1218,11 +1205,11 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
return result;
}
void focus(Genode::Capability<Gui::Session>) override { }
void focus(Capability<Gui::Session>) override { }
};
class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session> >,
class Wm::Gui::Root : public Rpc_object<Typed_root<Gui::Session> >,
public Decorator_content_callback
{
private:
@ -1233,9 +1220,9 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
Root(Root const &);
Root &operator = (Root const &);
Genode::Env &_env;
Env &_env;
Genode::Attached_rom_dataspace _config { _env, "config" };
Attached_rom_dataspace _config { _env, "config" };
Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
@ -1243,10 +1230,6 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
Pointer::Tracker &_pointer_tracker;
Reporter &_focus_request_reporter;
unsigned _focus_request_cnt = 0;
Window_registry &_window_registry;
Input::Session_component _window_layouter_input { _env, _env.ram() };
@ -1293,13 +1276,12 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
/**
* Constructor
*/
Root(Genode::Env &env, Window_registry &window_registry,
Pointer::Tracker &pointer_tracker, Reporter &focus_request_reporter,
Root(Env &env, Window_registry &window_registry,
Pointer::Tracker &pointer_tracker,
Gui::Connection &focus_gui_session)
:
_env(env),
_pointer_tracker(pointer_tracker),
_focus_request_reporter(focus_request_reporter),
_window_registry(window_registry),
_focus_gui_session(focus_gui_session)
{
@ -1336,9 +1318,11 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
Genode::Session_capability session(Session_args const &args,
Affinity const &) override
{
Genode::Session::Label label = Genode::label_from_args(args.string());
Genode::Session::Resources resources = Genode::session_resources_from_args(args.string());
Genode::Session::Diag diag = Genode::session_diag_from_args(args.string());
using Session = Genode::Session;
Session::Label label = label_from_args(args.string());
Session::Resources resources = session_resources_from_args(args.string());
Session::Diag diag = session_diag_from_args(args.string());
enum Role { ROLE_DECORATOR, ROLE_LAYOUTER, ROLE_REGULAR, ROLE_DIRECT };
Role role = ROLE_REGULAR;
@ -1347,8 +1331,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
* Determine session policy
*/
try {
Genode::Xml_node policy =
Genode::Session_policy(label, _config.xml());
Xml_node policy = Session_policy(label, _config.xml());
auto const value = policy.attribute_value("role", String<16>());
@ -1441,7 +1424,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
auto lambda = [&] (Rpc_object_base *session) {
if (!session) {
Genode::warning("session lookup failed");
warning("session lookup failed");
return;
}
@ -1468,7 +1451,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
void close(Genode::Session_capability session_cap) override
{
Genode::Rpc_entrypoint &ep = _env.ep().rpc_ep();
Rpc_entrypoint &ep = _env.ep().rpc_ep();
Session_component *regular_session =
ep.apply(session_cap, [this] (Session_component *session) {
@ -1477,7 +1460,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
return session;
});
if (regular_session) {
Genode::destroy(_sliced_heap, regular_session);
destroy(_sliced_heap, regular_session);
return;
}
@ -1486,7 +1469,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
return session;
});
if (direct_session) {
Genode::destroy(_sliced_heap, direct_session);
destroy(_sliced_heap, direct_session);
return;
}
@ -1497,7 +1480,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
return session;
});
if (decorator_session) {
Genode::destroy(_sliced_heap, decorator_session);
destroy(_sliced_heap, decorator_session);
return;
}
@ -1507,7 +1490,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
};
if (ep.apply(session_cap, layouter_lambda) == _layouter_session) {
Genode::destroy(_sliced_heap, _layouter_session);
destroy(_sliced_heap, _layouter_session);
return;
}
}
@ -1530,8 +1513,8 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
* calling 's->content_view'.
*/
for (Session_component *s = _sessions.first(); s; s = s->next())
if (s->has_win_id(id.value))
return s->content_view(id.value);
if (s->has_win_id(id))
return s->content_view(id);
return View_capability();
}
@ -1572,16 +1555,16 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
s->content_geometry(id, rect);
}
Capability<Gui::Session> lookup_gui_session(unsigned win_id)
void with_gui_session(Window_registry::Id id, auto const &fn)
{
for (Session_component *s = _sessions.first(); s; s = s->next())
if (s->has_win_id(win_id))
return s->session();
return { };
if (s->has_win_id(id)) {
fn(s->session());
return;
}
}
void request_resize(unsigned win_id, Area size)
void request_resize(Window_registry::Id win_id, Area size)
{
for (Session_component *s = _sessions.first(); s; s = s->next())
if (s->has_win_id(win_id))

View File

@ -24,11 +24,8 @@ namespace Wm {
}
struct Wm::Layouter_gui_session : Genode::Session_object<Gui::Session>
struct Wm::Layouter_gui_session : Session_object<Gui::Session>
{
using View_capability = Gui::View_capability;
using View_id = Gui::View_id;
Input::Session_capability _input_session_cap;
/*
@ -36,11 +33,11 @@ struct Wm::Layouter_gui_session : Genode::Session_object<Gui::Session>
*/
Gui::Connection _mode_sigh_gui;
Genode::Signal_context_capability _mode_sigh { };
Signal_context_capability _mode_sigh { };
Attached_ram_dataspace _command_ds;
Layouter_gui_session(Genode::Env &env,
Layouter_gui_session(Env &env,
Resources const &resources,
Label const &label,
Diag const &diag,
@ -66,31 +63,31 @@ struct Wm::Layouter_gui_session : Genode::Session_object<Gui::Session>
return _input_session_cap;
}
View_result view(View_id, View_attr const &) override
View_result view(Gui::View_id, View_attr const &) override
{
return View_result::OK;
}
Child_view_result child_view(View_id, View_id, View_attr const &) override
Child_view_result child_view(Gui::View_id, Gui::View_id, View_attr const &) override
{
return Child_view_result::OK;
}
void destroy_view(View_id) override { }
void destroy_view(Gui::View_id) override { }
Associate_result associate(View_id, View_capability) override
Associate_result associate(Gui::View_id, Gui::View_capability) override
{
return Associate_result::OK;
}
View_capability_result view_capability(View_id) override
View_capability_result view_capability(Gui::View_id) override
{
return View_capability();
return Gui::View_capability();
}
void release_view_id(View_id) override { }
void release_view_id(Gui::View_id) override { }
Genode::Dataspace_capability command_dataspace() override
Dataspace_capability command_dataspace() override
{
return _command_ds.cap();
}
@ -99,7 +96,7 @@ struct Wm::Layouter_gui_session : Genode::Session_object<Gui::Session>
Framebuffer::Mode mode() override { return _mode_sigh_gui.mode(); }
void mode_sigh(Genode::Signal_context_capability sigh) override
void mode_sigh(Signal_context_capability sigh) override
{
/*
* Remember signal-context capability to keep NOVA from revoking
@ -112,7 +109,7 @@ struct Wm::Layouter_gui_session : Genode::Session_object<Gui::Session>
Buffer_result buffer(Framebuffer::Mode, bool) override { return Buffer_result::OK; }
void focus(Genode::Capability<Gui::Session>) override { }
void focus(Capability<Gui::Session>) override { }
};
#endif /* _LAYOUTER_GUI_H_ */

View File

@ -15,104 +15,79 @@
#include <gui_session/client.h>
#include <framebuffer_session/client.h>
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <base/heap.h>
#include <util/reconstructible.h>
#include <util/xml_node.h>
/* local includes */
#include <gui.h>
#include <report_forwarder.h>
#include <rom_forwarder.h>
namespace Wm {
class Main;
}
namespace Wm { class Main; }
struct Wm::Main : Pointer::Tracker
{
Genode::Env &env;
Env &_env;
Genode::Heap heap { env.ram(), env.rm() };
Heap _heap { _env.ram(), _env.rm() };
/* currently focused window, reported by the layouter */
Attached_rom_dataspace focus_rom { env, "focus" };
Attached_rom_dataspace _focus_rom { _env, "focus" };
/* resize requests, issued by the layouter */
Attached_rom_dataspace resize_request_rom { env, "resize_request" };
Attached_rom_dataspace _resize_request_rom { _env, "resize_request" };
/* pointer position to be consumed by the layouter */
Reporter pointer_reporter = { env, "pointer" };
Expanding_reporter _pointer_reporter { _env, "pointer", "pointer" };
/* list of present windows, to be consumed by the layouter */
Reporter window_list_reporter = { env, "window_list" };
Expanding_reporter _window_list_reporter { _env, "window_list", "window_list" };
/* request to the layouter to set the focus */
Reporter focus_request_reporter = { env, "focus_request" };
Window_registry _window_registry { _heap, _window_list_reporter };
Window_registry window_registry { heap, window_list_reporter };
Gui::Connection _focus_gui_session { _env };
Gui::Connection focus_gui_session { env };
Gui::Root _gui_root { _env, _window_registry, *this, _focus_gui_session };
Gui::Root gui_root { env, window_registry,
*this, focus_request_reporter,
focus_gui_session };
void handle_focus_update()
static void _with_win_id_from_xml(Xml_node const &window, auto const &fn)
{
focus_rom.update();
focus_rom.xml().with_optional_sub_node("window", [&] (Xml_node const &window) {
unsigned const win_id = window.attribute_value("id", 0u);
if (win_id) {
try {
Gui::Session_capability session_cap =
gui_root.lookup_gui_session(win_id);
focus_gui_session.focus(session_cap);
} catch (...) { }
}
});
if (window.has_attribute("id"))
fn(Window_registry::Id { window.attribute_value("id", 0u) });
}
Genode::Signal_handler<Main> focus_handler = {
env.ep(), *this, &Main::handle_focus_update };
void handle_resize_request_update()
void _handle_focus_update()
{
resize_request_rom.update();
resize_request_rom.xml().for_each_sub_node("window", [&] (Xml_node window) {
unsigned const
win_id = window.attribute_value("id", 0U),
width = window.attribute_value("width", 0U),
height = window.attribute_value("height", 0U);
gui_root.request_resize(win_id, Area(width, height));
});
_focus_rom.update();
_focus_rom.xml().with_optional_sub_node("window", [&] (Xml_node const &window) {
_with_win_id_from_xml(window, [&] (Window_registry::Id id) {
_gui_root.with_gui_session(id, [&] (Capability<Gui::Session> cap) {
_focus_gui_session.focus(cap); }); }); });
}
Genode::Signal_handler<Main> resize_request_handler =
{ env.ep(), *this, &Main::handle_resize_request_update };
Signal_handler<Main> _focus_handler {
_env.ep(), *this, &Main::_handle_focus_update };
Report_forwarder _report_forwarder { env, heap };
Rom_forwarder _rom_forwarder { env, heap };
void _handle_resize_request_update()
{
_resize_request_rom.update();
_resize_request_rom.xml().for_each_sub_node("window", [&] (Xml_node const &window) {
_with_win_id_from_xml(window, [&] (Window_registry::Id id) {
_gui_root.request_resize(id, Area::from_xml(window)); }); });
}
Genode::Signal_handler<Main> _update_pointer_report_handler =
{ env.ep(), *this, &Main::_handle_update_pointer_report };
Signal_handler<Main> _resize_request_handler {
_env.ep(), *this, &Main::_handle_resize_request_update };
Report_forwarder _report_forwarder { _env, _heap };
Rom_forwarder _rom_forwarder { _env, _heap };
Signal_handler<Main> _update_pointer_report_handler {
_env.ep(), *this, &Main::_handle_update_pointer_report };
void _handle_update_pointer_report()
{
Pointer::Position pos = gui_root.last_observed_pointer_pos();
Pointer::Position const pos = _gui_root.last_observed_pointer_pos();
Reporter::Xml_generator xml(pointer_reporter, [&] ()
{
_pointer_reporter.generate([&] (Xml_generator &xml) {
if (pos.valid) {
xml.attribute("xpos", pos.value.x);
xml.attribute("ypos", pos.value.y);
@ -135,28 +110,15 @@ struct Wm::Main : Pointer::Tracker
_update_pointer_report_handler.local_submit();
}
Main(Genode::Env &env) : env(env)
Main(Env &env) : _env(env)
{
pointer_reporter.enabled(true);
/* initially report an empty window list */
window_list_reporter.enabled(true);
Genode::Reporter::Xml_generator xml(window_list_reporter, [&] () { });
_window_list_reporter.generate([&] (Xml_generator &) { });
focus_request_reporter.enabled(true);
focus_rom.sigh(focus_handler);
resize_request_rom.sigh(resize_request_handler);
_focus_rom.sigh(_focus_handler);
_resize_request_rom.sigh(_resize_request_handler);
}
};
/***************
** Component **
***************/
Genode::size_t Component::stack_size() {
return 16*1024*sizeof(long); }
void Component::construct(Genode::Env &env) {
static Wm::Main desktop(env); }
void Component::construct(Genode::Env &env) { static Wm::Main desktop(env); }

View File

@ -14,7 +14,8 @@
#ifndef _POINTER_H_
#define _POINTER_H_
#include <util/noncopyable.h>
/* local includes */
#include <types.h>
namespace Wm { struct Pointer; }
@ -28,13 +29,13 @@ struct Wm::Pointer
};
struct Tracker : Genode::Interface, Genode::Noncopyable
struct Tracker : Interface, Noncopyable
{
virtual void update_pointer_report() = 0;
};
class State : Genode::Noncopyable
class State : Noncopyable
{
private:

View File

@ -17,7 +17,6 @@
/* Genode includes */
#include <base/connection.h>
#include <base/attached_dataspace.h>
#include <gui_session/client.h>
namespace Wm { struct Real_gui; }
@ -26,31 +25,31 @@ struct Wm::Real_gui
{
private:
Genode::Env &_env;
Env &_env;
public:
Genode::Session_label const &label;
Session_label const &label;
using Command_buffer = Gui::Session::Command_buffer;
static constexpr Genode::size_t RAM_QUOTA = 36*1024;
static constexpr size_t RAM_QUOTA = 36*1024;
public:
Real_gui(Genode::Env &env, Genode::Session_label const &label)
Real_gui(Env &env, Session_label const &label)
:
_env(env), label(label)
{ }
Genode::Connection<Gui::Session> connection {
Connection<Gui::Session> connection {
_env, label, Genode::Ram_quota { RAM_QUOTA }, /* Args */ { } };
Gui::Session_client session { connection.cap() };
private:
Genode::Attached_dataspace _command_ds { _env.rm(), session.command_dataspace() };
Attached_dataspace _command_ds { _env.rm(), session.command_dataspace() };
Command_buffer &_command_buffer { *_command_ds.local_addr<Command_buffer>() };

View File

@ -32,19 +32,17 @@ namespace Wm { struct Report_forwarder; }
struct Wm::Report_forwarder
{
struct Session : Genode::Rpc_object<Report::Session>
struct Session : Session_object<Report::Session>
{
Genode::Env &_env;
Report::Connection _connection;
Session(Genode::Env &env, Genode::Session_label const &label,
size_t buffer_size)
: _env(env), _connection(env, label.string(), buffer_size)
{ _env.ep().manage(*this); }
Session(Env &env, size_t buffer_size, auto &&... args)
:
Session_object<Report::Session>(env.ep(), args...),
_connection(env, label(), buffer_size)
{ }
~Session() { _env.ep().dissolve(*this); }
void upgrade(Genode::Session::Resources const &resources)
void upgrade(Session::Resources const &resources)
{
_connection.upgrade(resources);
}
@ -54,47 +52,49 @@ struct Wm::Report_forwarder
** Report::Session interface **
*******************************/
Genode::Dataspace_capability dataspace() override
Dataspace_capability dataspace() override
{
return _connection.dataspace();
}
void submit(Genode::size_t length) override
void submit(size_t length) override
{
_connection.submit(length);
}
void response_sigh(Genode::Signal_context_capability sigh) override
void response_sigh(Signal_context_capability sigh) override
{
_connection.response_sigh(sigh);
}
Genode::size_t obtain_response() override
size_t obtain_response() override
{
return _connection.obtain_response();
}
};
struct Root : Genode::Root_component<Session>
struct Root : Root_component<Session>
{
Genode::Env &_env;
Genode::Allocator &_alloc;
Env &_env;
Allocator &_alloc;
Session *_create_session(char const *args) override
{
return new (md_alloc())
Session(_env, Genode::label_from_args(args),
Arg_string::find_arg(args, "buffer_size").ulong_value(0));
Session(_env, Arg_string::find_arg(args, "buffer_size").ulong_value(0),
session_resources_from_args(args),
session_label_from_args(args),
session_diag_from_args(args));
}
void _upgrade_session(Session *session, const char *args) override
{
session->upgrade(Genode::session_resources_from_args(args));
session->upgrade(session_resources_from_args(args));
}
Root(Genode::Env &env, Genode::Allocator &alloc)
Root(Env &env, Allocator &alloc)
:
Genode::Root_component<Session>(env.ep(), alloc),
Root_component<Session>(env.ep(), alloc),
_env(env), _alloc(alloc)
{
_env.parent().announce(env.ep().manage(*this));
@ -102,8 +102,7 @@ struct Wm::Report_forwarder
} _root;
Report_forwarder(Genode::Env &env, Genode::Allocator &alloc)
: _root(env, alloc) { }
Report_forwarder(Env &env, Allocator &alloc) : _root(env, alloc) { }
};
#endif /* _REPORT_FORWARDER_H_ */

View File

@ -27,18 +27,17 @@ namespace Wm { struct Rom_forwarder; }
struct Wm::Rom_forwarder
{
struct Session : Genode::Rpc_object<Genode::Rom_session>
struct Session : Session_object<Rom_session>
{
Genode::Env &_env;
Genode::Rom_connection _connection;
Rom_connection _connection;
Session(Genode::Env &env, Genode::Session_label const &label)
: _env(env), _connection(env, label.string())
{ _env.ep().manage(*this); }
Session(Env &env, auto &&... args)
:
Session_object<Rom_session>(env.ep(), args...),
_connection(env, label())
{ }
~Session() { _env.ep().dissolve(*this); }
void upgrade(Genode::Session::Resources const &resources)
void upgrade(Session::Resources const &resources)
{
_connection.upgrade(resources);
}
@ -48,7 +47,7 @@ struct Wm::Rom_forwarder
** Rom_session interface **
***************************/
Genode::Rom_dataspace_capability dataspace() override
Rom_dataspace_capability dataspace() override
{
return _connection.dataspace();
}
@ -64,24 +63,26 @@ struct Wm::Rom_forwarder
}
};
struct Root : Genode::Root_component<Session>
struct Root : Root_component<Session>
{
Genode::Env &_env;
Genode::Allocator &_alloc;
Env &_env;
Allocator &_alloc;
Session *_create_session(char const *args) override
{
return new (md_alloc()) Session(_env, Genode::label_from_args(args));
return new (md_alloc()) Session(_env, session_resources_from_args(args),
session_label_from_args(args),
session_diag_from_args(args));
}
void _upgrade_session(Session *session, const char *args) override
{
session->upgrade(Genode::session_resources_from_args(args));
session->upgrade(session_resources_from_args(args));
}
Root(Genode::Env &env, Genode::Allocator &alloc)
Root(Env &env, Allocator &alloc)
:
Genode::Root_component<Session>(env.ep(), alloc),
Root_component<Session>(env.ep(), alloc),
_env(env), _alloc(alloc)
{
_env.parent().announce(env.ep().manage(*this));
@ -89,8 +90,7 @@ struct Wm::Rom_forwarder
} _root;
Rom_forwarder(Genode::Env &env, Genode::Allocator &alloc)
: _root(env, alloc) { }
Rom_forwarder(Env &env, Allocator &alloc) : _root(env, alloc) { }
};
#endif /* _ROM_FORWARDER_H_ */

View File

@ -15,19 +15,25 @@
#define _TYPES_H_
/* Genode includes */
#include <util/reconstructible.h>
#include <util/list.h>
#include <base/tslab.h>
#include <base/attached_rom_dataspace.h>
#include <base/attached_ram_dataspace.h>
#include <base/heap.h>
#include <base/session_object.h>
#include <os/surface.h>
#include <os/reporter.h>
#include <os/session_policy.h>
#include <gui_session/gui_session.h>
namespace Wm {
using Genode::uint8_t;
using Genode::size_t;
using Genode::Rom_connection;
using Genode::Xml_node;
using Genode::Attached_rom_dataspace;
using Genode::Tslab;
using Genode::Cap_quota;
using Genode::Ram_quota;
using namespace Genode;
using Area = Surface_base::Area;
using Point = Surface_base::Point;
using Rect = Surface_base::Rect;
/*
* Slab allocator that includes an initial block as member
@ -41,7 +47,7 @@ namespace Wm {
: Tslab<T, BLOCK_SIZE>(block_alloc, Initial_slab_block<BLOCK_SIZE>::buf) { };
};
struct Upgradeable : Genode::Noncopyable
struct Upgradeable : Noncopyable
{
bool _starved_for_ram = false, _starved_for_caps = false;

View File

@ -16,102 +16,89 @@
/* Genode includes */
#include <util/bit_allocator.h>
#include <util/list.h>
#include <base/allocator.h>
#include <os/surface.h>
#include <os/reporter.h>
#include <os/session_policy.h>
#include <base/id_space.h>
/* gems includes */
#include <gems/local_reporter.h>
/* local includes */
#include <types.h>
namespace Wm { class Window_registry; }
namespace Wm {
using Genode::Allocator;
using Genode::List;
using Genode::Xml_generator;
using Genode::Reporter;
using Area = Genode::Surface_base::Area;
using Point = Genode::Surface_base::Point;
using Rect = Genode::Surface_base::Rect;
}
class Wm::Window_registry
{
public:
struct Id
{
unsigned value;
class Window;
Id(unsigned value) : value(value) { }
using Windows = Id_space<Window>;
using Id = Windows::Id;
Id() /* invalid */ : value(0) { }
struct Alpha { bool value; };
struct Hidden { bool value; };
struct Resizeable { bool value; };
bool operator == (Id const &other) const { return value == other.value; }
bool valid() const { return value != 0; }
};
class Window : public List<Window>::Element
class Window : Noncopyable
{
public:
using Title = Gui::Title;
using Session_label = Genode::Session_label;
enum Has_alpha { HAS_ALPHA, HAS_NO_ALPHA };
enum Hidden { HIDDEN, NOT_HIDDEN };
enum Resizeable { RESIZEABLE, NOT_RESIZEABLE };
private:
Id const _id;
struct Attr
{
Title title { };
Session_label label { };
Area size { };
Has_alpha has_alpha = HAS_NO_ALPHA;
Hidden hidden = NOT_HIDDEN;
Resizeable resizeable = NOT_RESIZEABLE;
Gui::Title title;
Session_label label;
Area area;
Alpha alpha;
Hidden hidden;
Resizeable resizeable;
bool operator == (Attr const &other) const
{
return title == other.title
&& label == other.label
&& size == other.size
&& has_alpha == other.has_alpha
&& hidden == other.hidden
&& resizeable == other.resizeable;
return title == other.title
&& label == other.label
&& area == other.area
&& alpha.value == other.alpha.value
&& hidden.value == other.hidden.value
&& resizeable.value == other.resizeable.value;
}
void gen_window_attr(Xml_generator &xml) const
{
xml.attribute("label", label);
xml.attribute("title", title);
xml.attribute("width", area.w);
xml.attribute("height", area.h);
if (alpha.value) xml.attribute("has_alpha", "yes");
if (hidden.value) xml.attribute("hidden", "yes");
if (resizeable.value) xml.attribute("resizeable", "yes");
}
};
Attr _attr { };
private:
Windows::Element _id;
Attr _attr;
Attr mutable _flushed_attr { };
friend class Window_registry;
Window(Id id) : _id(id) { }
Window(Windows &windows, Id id, Attr const &attr)
: _id(*this, windows, id), _attr(attr) { }
public:
Id id() const { return _id; }
Id id() const { return _id.id(); }
/*
* Accessors for setting attributes
*/
void attr(Title const &title) { _attr.title = title; }
void attr(Gui::Title const &title) { _attr.title = title; }
void attr(Session_label const &label) { _attr.label = label; }
void attr(Area size) { _attr.size = size; }
void attr(Has_alpha has_alpha) { _attr.has_alpha = has_alpha; }
void attr(Area area) { _attr.area = area; }
void attr(Alpha alpha) { _attr.alpha = alpha; }
void attr(Hidden hidden) { _attr.hidden = hidden; }
void attr(Resizeable resizeable) { _attr.resizeable = resizeable; }
@ -120,28 +107,17 @@ class Wm::Window_registry
void generate_window_list_entry_xml(Xml_generator &xml) const
{
/*
* Skip windows that have no defined size, which happens
* between the creation of a new window and the first
* time when the window's properties are assigned.
* Skip windows that have no defined size, which may happen
* between the creation of a new window for a view w/o size
* and the first time when the top-level view's size is
* assigned.
*/
if (!_attr.size.valid())
if (!_attr.area.valid())
return;
xml.node("window", [&] () {
xml.attribute("id", _id.value);
xml.attribute("label", _attr.label.string());
xml.attribute("title", _attr.title.string());
xml.attribute("width", _attr.size.w);
xml.attribute("height", _attr.size.h);
if (_attr.has_alpha == HAS_ALPHA)
xml.attribute("has_alpha", "yes");
if (_attr.hidden == HIDDEN)
xml.attribute("hidden", "yes");
if (_attr.resizeable == RESIZEABLE)
xml.attribute("resizeable", "yes");
xml.attribute("id", id().value);
_attr.gen_window_attr(xml);
});
}
@ -151,61 +127,49 @@ class Wm::Window_registry
bool _flushed() const
{
bool result = true;
for (Window const *w = _windows.first(); w; w = w->next())
result &= w->flushed();
_windows.for_each<Window const>([&] (Window const &w) {
result &= w.flushed(); });
return result;
}
private:
Allocator &_alloc;
Reporter &_window_list_reporter;
Allocator &_alloc;
Expanding_reporter &_window_list_reporter;
static constexpr unsigned MAX_WINDOWS = 1024;
Genode::Bit_allocator<MAX_WINDOWS> _window_ids { };
Bit_allocator<MAX_WINDOWS> _window_ids { };
unsigned _next_id = 0; /* used to alloc subsequent numbers */
List<Window> _windows { };
Windows _windows { };
Window *_lookup(Id id)
void _with_window(Id id, auto const &fn, auto const &missing_fn)
{
for (Window *w = _windows.first(); w; w = w->next())
if (w->id() == id)
return w;
return 0;
_windows.apply<Window>(id, fn, missing_fn);
}
void _report_updated_window_list_model() const
{
Reporter::Xml_generator xml(_window_list_reporter, [&] ()
{
for (Window const *w = _windows.first(); w; w = w->next()) {
w->generate_window_list_entry_xml(xml);
w->mark_as_flushed();
}
_window_list_reporter.generate([&] (Xml_generator &xml) {
_windows.for_each<Window>([&] (Window const &w) {
w.generate_window_list_entry_xml(xml);
w.mark_as_flushed();
});
});
}
template <typename ATTR>
void _set_attr(Id const id, ATTR const &value)
void _set_attr(Id const id, auto const &value)
{
Window * const win = _lookup(id);
if (!win) {
Genode::warning("lookup for window ID ", id.value, " failed");
return;
}
win->attr(value);
_with_window(id,
[&] (Window &window) { window.attr(value); },
[&] { warning("lookup for window ID ", id.value, " failed"); });
}
public:
Window_registry(Allocator &alloc, Reporter &window_list_reporter)
Window_registry(Allocator &alloc, Expanding_reporter &window_list_reporter)
:
_alloc(alloc), _window_list_reporter(window_list_reporter)
{
@ -213,72 +177,60 @@ class Wm::Window_registry
_window_ids.alloc();
}
Id create()
enum class Create_error { IDS_EXHAUSTED };
using Create_result = Attempt<Id, Create_error>;
Create_result create(Window::Attr const &attr)
{
auto alloc_id = [&]
auto alloc_id = [&] () -> Create_result
{
for (;;) {
for (unsigned i = 0; i < MAX_WINDOWS; i++) {
unsigned try_id = _next_id;
_next_id = (_next_id + 1) % MAX_WINDOWS;
try {
_window_ids.alloc_addr(try_id);
return try_id;
return Id { try_id };
}
catch (...) { }
}
return Create_error::IDS_EXHAUSTED;
};
Window * const win = new (_alloc) Window(alloc_id());
Create_result const result = alloc_id();
_windows.insert(win);
result.with_result(
[&] (Id id) {
new (_alloc) Window(_windows, id, attr);
_report_updated_window_list_model();
},
[&] (Create_error) { }
);
/*
* Even though we change the window-list model by adding a
* window, we don't call '_report_updated_window_list_model' here
* because the window does not have any useful properties before
* the 'size' function has been called.
*
* XXX should we pass the initial size as argument to this function?
*/
return win->id();
return result;
}
void destroy(Id id)
{
Window * const win = _lookup(id);
if (!win)
Window *win_ptr = nullptr;
_with_window(id, [&] (Window &window) { win_ptr = &window; }, [&] { });
if (!win_ptr)
return;
_windows.remove(win);
_window_ids.free(win_ptr->id().value);
_window_ids.free(win->id().value);
Genode::destroy(&_alloc, win);
Genode::destroy(&_alloc, win_ptr);
_report_updated_window_list_model();
}
void size(Id id, Area size) { _set_attr(id, size); }
void area (Id id, Area const area) { _set_attr(id, area); }
void title(Id id, Gui::Title const &title) { _set_attr(id, title); }
void label(Id id, Session_label const &label) { _set_attr(id, label); }
void title(Id id, Window::Title const &title) { _set_attr(id, title); }
void label(Id id, Window::Session_label const &label) { _set_attr(id, label); }
void has_alpha(Id id, bool has_alpha)
{
_set_attr(id, has_alpha ? Window::HAS_ALPHA : Window::HAS_NO_ALPHA);
}
void hidden(Id id, bool hidden)
{
_set_attr(id, hidden ? Window::HIDDEN : Window::NOT_HIDDEN);
}
void resizeable(Id id, bool resizeable)
{
_set_attr(id, resizeable ? Window::RESIZEABLE : Window::NOT_RESIZEABLE);
}
void alpha (Id id, bool value) { _set_attr(id, Alpha { value }); }
void hidden (Id id, bool value) { _set_attr(id, Hidden { value }); }
void resizeable(Id id, bool value) { _set_attr(id, Resizeable { value }); }
void flush()
{