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 <pointer.h>
#include <real_gui.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 { namespace Wm {
class Main;
struct Decorator_gui_session; struct Decorator_gui_session;
struct Decorator_content_callback; struct Decorator_content_callback;
struct Decorator_content_registry; 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 List<Decorator_gui_session>::Element,
private Upgradeable private Upgradeable
{ {
@ -81,11 +70,11 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
Gui::View_ids _content_view_ids { }; 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 }; 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() }; 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) }; 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> Signal_handler<Decorator_gui_session>
_input_handler { _env.ep(), *this, &Decorator_gui_session::_handle_input }; _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; unsigned value = 0;
Genode::ascii_to(title.string(), value); if (ascii_to(title.string(), value))
return { value }; fn(Window_registry::Id { value });
} }
Decorator_gui_session(Genode::Env &env, Decorator_gui_session(Env &env,
Resources const &resources, Resources const &resources,
Label const &label, Label const &label,
Diag const &diag, 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 * as view title. For such views, we import the view from the
* corresponding GUI cient instead of creating a new view. * corresponding GUI cient instead of creating a new view.
*/ */
Window_registry::Id const win_id = _win_id_from_title(attr.title); bool out_of_ram = false, out_of_caps = false, associated = false;
if (win_id.valid()) { _with_win_id_from_title(attr.title, [&] (Window_registry::Id win_id) {
try { try {
Content_view_ref &view_ref_ptr = *new (_content_view_ref_alloc) Content_view_ref &view_ref_ptr = *new (_content_view_ref_alloc)
Content_view_ref(Window_registry::Id(win_id), _content_view_ids, id); 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); destroy(_content_view_ref_alloc, &view_ref_ptr);
switch (result) { switch (result) {
case Associate_result::OUT_OF_RAM: return View_result::OUT_OF_RAM; case Associate_result::OUT_OF_RAM: out_of_ram = true; break;
case Associate_result::OUT_OF_CAPS: return View_result::OUT_OF_CAPS; case Associate_result::OUT_OF_CAPS: out_of_caps = true; break;
case Associate_result::OK: return View_result::OK; case Associate_result::OK: associated = true; break;
case Associate_result::INVALID: break; /* fall back to regular view */ case Associate_result::INVALID: break; /* fall back to regular view */
}; };
} }
catch (Genode::Out_of_ram) { catch (Out_of_ram) { _starved_for_ram = out_of_ram = true; }
_starved_for_ram = true; catch (Out_of_caps) { _starved_for_caps = out_of_caps = true; }
return View_result::OUT_OF_RAM; });
}
catch (Genode::Out_of_caps) { if (out_of_ram) return View_result::OUT_OF_RAM;
_starved_for_caps = true; if (out_of_caps) return View_result::OUT_OF_CAPS;
return View_result::OUT_OF_CAPS; if (associated) return View_result::OK;
}
}
return _real_gui.session.view(id, attr); 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); _real_gui.session.release_view_id(view);
} }
Genode::Dataspace_capability command_dataspace() override Dataspace_capability command_dataspace() override
{ {
return _client_command_ds.cap(); return _client_command_ds.cap();
} }
@ -332,7 +320,7 @@ struct Wm::Decorator_gui_session : Genode::Session_object<Gui::Session>,
return _real_gui.session.mode(); 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 * 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); 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_ */ #endif /* _DECORATOR_GUI_H_ */

View File

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

View File

@ -15,14 +15,6 @@
#define _GUI_H_ #define _GUI_H_
/* Genode includes */ /* 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 <root/component.h>
#include <gui_session/connection.h> #include <gui_session/connection.h>
#include <input_session/capability.h> #include <input_session/capability.h>
@ -34,26 +26,6 @@
#include <layouter_gui.h> #include <layouter_gui.h>
#include <direct_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 { namespace Wm { namespace Gui {
using namespace ::Gui; using namespace ::Gui;
@ -66,10 +38,6 @@ namespace Wm { namespace Gui {
class Session_control_fn; class Session_control_fn;
class Session_component; class Session_component;
class Root; 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>, class Wm::Gui::View : private Weak_object<View>, public Rpc_object< ::Gui::View>
public Genode::Rpc_object< ::Gui::View>
{ {
private: private:
friend class Genode::Weak_ptr<View>; friend class Weak_ptr<View>;
friend class Genode::Locked_ptr<View>; friend class Locked_ptr<View>;
protected: protected:
@ -197,8 +164,8 @@ class Wm::Gui::View : private Genode::Weak_object<View>,
_real_gui.session.destroy_view(_real_view.id()); _real_gui.session.destroy_view(_real_view.id());
} }
using Genode::Weak_object<View>::weak_ptr; using Weak_object<View>::weak_ptr;
using Genode::Weak_object<View>::lock_for_destruction; using Weak_object<View>::lock_for_destruction;
Point virtual_position() const { return _geometry.at; } 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>; 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; 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; 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: public:
Top_level_view(Real_gui &real_gui, 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() ~Top_level_view()
{ {
if (_win_id.valid()) _with_optional_win_id([&] (Window_registry::Id id) {
_window_registry.destroy(_win_id); _window_registry.destroy(id); });
View::lock_for_destruction(); 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 * defer the creation of the window ID until the time when the
* initial geometry is known. * initial geometry is known.
*/ */
if (!_win_id.valid()) { if (!_win_id.ok()) {
_win_id = _window_registry.create(); _win_id = _window_registry.create({
_window_registry.title(_win_id, _window_title); .title = _window_title,
_window_registry.label(_win_id, _session_label); .label = _session_label,
_window_registry.has_alpha(_win_id, View::has_alpha()); .area = geometry.area,
_window_registry.resizeable(_win_id, _resizeable); .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); View::geometry(geometry);
} }
@ -338,11 +315,17 @@ class Wm::Gui::Top_level_view : public View, private List<Top_level_view>::Eleme
_window_title = title; _window_title = title;
if (_win_id.valid()) _with_optional_win_id([&] (Window_registry::Id id) {
_window_registry.title(_win_id, _window_title); _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 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(); } 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) void resizeable(bool resizeable)
{ {
_resizeable = resizeable; _resizeable = resizeable;
if (_win_id.valid()) _with_optional_win_id([&] (Window_registry::Id id) {
_window_registry.resizeable(_win_id, resizeable); _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() }; _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 }; Real_gui _real_gui { _env, _label };
Window_registry &_window_registry; Window_registry &_window_registry;
Slab<Top_level_view, 8000> _top_level_view_alloc { _session_alloc }; 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); _top_level_views.remove(&view);
_dissolve_view_from_ep(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) void _destroy_child_view(Child_view &view)
{ {
_child_views.remove(&view); _child_views.remove(&view);
_dissolve_view_from_ep(view); _dissolve_view_from_ep(view);
Genode::destroy(&_child_view_alloc, &view); destroy(&_child_view_alloc, &view);
} }
void _execute_command(Command const &command) 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()]; char sanitized_title[args.title.capacity()];
Genode::copy_cstring(sanitized_title, command.title.title.string(), copy_cstring(sanitized_title, command.title.title.string(),
sizeof(sanitized_title)); sizeof(sanitized_title));
for (char *c = sanitized_title; *c; c++) for (char *c = sanitized_title; *c; c++)
if (*c == '"') if (*c == '"')
@ -825,7 +812,7 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
public: public:
Session_component(Genode::Env &env, Session_component(Env &env,
Resources const &resources, Resources const &resources,
Label const &label, Label const &label,
Diag const diag, 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) View_capability content_view(Window_registry::Id id)
{ {
for (Top_level_view *v = _top_level_views.first(); v; v = v->next()) 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 v->content_view();
return View_capability(); 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()) for (Top_level_view const *v = _top_level_views.first(); v; v = v->next())
if (v->has_win_id(id)) 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(); return _command_ds.cap();
} }
@ -1185,7 +1172,7 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
return real_mode; return real_mode;
} }
void mode_sigh(Genode::Signal_context_capability sigh) override void mode_sigh(Signal_context_capability sigh) override
{ {
_mode_sigh = sigh; _mode_sigh = sigh;
@ -1218,11 +1205,11 @@ class Wm::Gui::Session_component : public Session_object<Gui::Session>,
return result; 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 public Decorator_content_callback
{ {
private: private:
@ -1233,9 +1220,9 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
Root(Root const &); Root(Root const &);
Root &operator = (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() }; 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; Pointer::Tracker &_pointer_tracker;
Reporter &_focus_request_reporter;
unsigned _focus_request_cnt = 0;
Window_registry &_window_registry; Window_registry &_window_registry;
Input::Session_component _window_layouter_input { _env, _env.ram() }; 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 * Constructor
*/ */
Root(Genode::Env &env, Window_registry &window_registry, Root(Env &env, Window_registry &window_registry,
Pointer::Tracker &pointer_tracker, Reporter &focus_request_reporter, Pointer::Tracker &pointer_tracker,
Gui::Connection &focus_gui_session) Gui::Connection &focus_gui_session)
: :
_env(env), _env(env),
_pointer_tracker(pointer_tracker), _pointer_tracker(pointer_tracker),
_focus_request_reporter(focus_request_reporter),
_window_registry(window_registry), _window_registry(window_registry),
_focus_gui_session(focus_gui_session) _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, Genode::Session_capability session(Session_args const &args,
Affinity const &) override Affinity const &) override
{ {
Genode::Session::Label label = Genode::label_from_args(args.string()); using Session = Genode::Session;
Genode::Session::Resources resources = Genode::session_resources_from_args(args.string());
Genode::Session::Diag diag = Genode::session_diag_from_args(args.string()); 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 }; enum Role { ROLE_DECORATOR, ROLE_LAYOUTER, ROLE_REGULAR, ROLE_DIRECT };
Role role = ROLE_REGULAR; Role role = ROLE_REGULAR;
@ -1347,8 +1331,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
* Determine session policy * Determine session policy
*/ */
try { try {
Genode::Xml_node policy = Xml_node policy = Session_policy(label, _config.xml());
Genode::Session_policy(label, _config.xml());
auto const value = policy.attribute_value("role", String<16>()); 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) { auto lambda = [&] (Rpc_object_base *session) {
if (!session) { if (!session) {
Genode::warning("session lookup failed"); warning("session lookup failed");
return; 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 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 = Session_component *regular_session =
ep.apply(session_cap, [this] (Session_component *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; return session;
}); });
if (regular_session) { if (regular_session) {
Genode::destroy(_sliced_heap, regular_session); destroy(_sliced_heap, regular_session);
return; return;
} }
@ -1486,7 +1469,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
return session; return session;
}); });
if (direct_session) { if (direct_session) {
Genode::destroy(_sliced_heap, direct_session); destroy(_sliced_heap, direct_session);
return; return;
} }
@ -1497,7 +1480,7 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
return session; return session;
}); });
if (decorator_session) { if (decorator_session) {
Genode::destroy(_sliced_heap, decorator_session); destroy(_sliced_heap, decorator_session);
return; 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) { if (ep.apply(session_cap, layouter_lambda) == _layouter_session) {
Genode::destroy(_sliced_heap, _layouter_session); destroy(_sliced_heap, _layouter_session);
return; return;
} }
} }
@ -1530,8 +1513,8 @@ class Wm::Gui::Root : public Genode::Rpc_object<Genode::Typed_root<Gui::Session>
* calling 's->content_view'. * calling 's->content_view'.
*/ */
for (Session_component *s = _sessions.first(); s; s = s->next()) for (Session_component *s = _sessions.first(); s; s = s->next())
if (s->has_win_id(id.value)) if (s->has_win_id(id))
return s->content_view(id.value); return s->content_view(id);
return View_capability(); 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); 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()) for (Session_component *s = _sessions.first(); s; s = s->next())
if (s->has_win_id(win_id)) if (s->has_win_id(id)) {
return s->session(); fn(s->session());
return;
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()) for (Session_component *s = _sessions.first(); s; s = s->next())
if (s->has_win_id(win_id)) 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; 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; Gui::Connection _mode_sigh_gui;
Genode::Signal_context_capability _mode_sigh { }; Signal_context_capability _mode_sigh { };
Attached_ram_dataspace _command_ds; Attached_ram_dataspace _command_ds;
Layouter_gui_session(Genode::Env &env, Layouter_gui_session(Env &env,
Resources const &resources, Resources const &resources,
Label const &label, Label const &label,
Diag const &diag, Diag const &diag,
@ -66,31 +63,31 @@ struct Wm::Layouter_gui_session : Genode::Session_object<Gui::Session>
return _input_session_cap; 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; 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; 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; 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(); 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(); } 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 * 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; } 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_ */ #endif /* _LAYOUTER_GUI_H_ */

View File

@ -15,104 +15,79 @@
#include <gui_session/client.h> #include <gui_session/client.h>
#include <framebuffer_session/client.h> #include <framebuffer_session/client.h>
#include <base/component.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 */ /* local includes */
#include <gui.h> #include <gui.h>
#include <report_forwarder.h> #include <report_forwarder.h>
#include <rom_forwarder.h> #include <rom_forwarder.h>
namespace Wm { namespace Wm { class Main; }
class Main;
}
struct Wm::Main : Pointer::Tracker 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 */ /* 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 */ /* 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 */ /* 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 */ /* 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 */ Window_registry _window_registry { _heap, _window_list_reporter };
Reporter focus_request_reporter = { env, "focus_request" };
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, static void _with_win_id_from_xml(Xml_node const &window, auto const &fn)
*this, focus_request_reporter,
focus_gui_session };
void handle_focus_update()
{ {
focus_rom.update(); if (window.has_attribute("id"))
fn(Window_registry::Id { window.attribute_value("id", 0u) });
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 (...) { }
}
});
} }
Genode::Signal_handler<Main> focus_handler = { void _handle_focus_update()
env.ep(), *this, &Main::handle_focus_update };
void handle_resize_request_update()
{ {
resize_request_rom.update(); _focus_rom.update();
_focus_rom.xml().with_optional_sub_node("window", [&] (Xml_node const &window) {
resize_request_rom.xml().for_each_sub_node("window", [&] (Xml_node window) { _with_win_id_from_xml(window, [&] (Window_registry::Id id) {
_gui_root.with_gui_session(id, [&] (Capability<Gui::Session> cap) {
unsigned const _focus_gui_session.focus(cap); }); }); });
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));
});
} }
Genode::Signal_handler<Main> resize_request_handler = Signal_handler<Main> _focus_handler {
{ env.ep(), *this, &Main::handle_resize_request_update }; _env.ep(), *this, &Main::_handle_focus_update };
Report_forwarder _report_forwarder { env, heap }; void _handle_resize_request_update()
Rom_forwarder _rom_forwarder { env, heap }; {
_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 = Signal_handler<Main> _resize_request_handler {
{ env.ep(), *this, &Main::_handle_update_pointer_report }; _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() 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) { if (pos.valid) {
xml.attribute("xpos", pos.value.x); xml.attribute("xpos", pos.value.x);
xml.attribute("ypos", pos.value.y); xml.attribute("ypos", pos.value.y);
@ -135,28 +110,15 @@ struct Wm::Main : Pointer::Tracker
_update_pointer_report_handler.local_submit(); _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 */ /* initially report an empty window list */
window_list_reporter.enabled(true); _window_list_reporter.generate([&] (Xml_generator &) { });
Genode::Reporter::Xml_generator xml(window_list_reporter, [&] () { });
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);
} }
}; };
/*************** void Component::construct(Genode::Env &env) { static Wm::Main desktop(env); }
** Component **
***************/
Genode::size_t Component::stack_size() {
return 16*1024*sizeof(long); }
void Component::construct(Genode::Env &env) {
static Wm::Main desktop(env); }

View File

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

View File

@ -17,7 +17,6 @@
/* Genode includes */ /* Genode includes */
#include <base/connection.h> #include <base/connection.h>
#include <base/attached_dataspace.h> #include <base/attached_dataspace.h>
#include <gui_session/client.h>
namespace Wm { struct Real_gui; } namespace Wm { struct Real_gui; }
@ -26,31 +25,31 @@ struct Wm::Real_gui
{ {
private: private:
Genode::Env &_env; Env &_env;
public: public:
Genode::Session_label const &label; Session_label const &label;
using Command_buffer = Gui::Session::Command_buffer; 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: public:
Real_gui(Genode::Env &env, Genode::Session_label const &label) Real_gui(Env &env, Session_label const &label)
: :
_env(env), label(label) _env(env), label(label)
{ } { }
Genode::Connection<Gui::Session> connection { Connection<Gui::Session> connection {
_env, label, Genode::Ram_quota { RAM_QUOTA }, /* Args */ { } }; _env, label, Genode::Ram_quota { RAM_QUOTA }, /* Args */ { } };
Gui::Session_client session { connection.cap() }; Gui::Session_client session { connection.cap() };
private: 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>() }; 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 Wm::Report_forwarder
{ {
struct Session : Genode::Rpc_object<Report::Session> struct Session : Session_object<Report::Session>
{ {
Genode::Env &_env;
Report::Connection _connection; Report::Connection _connection;
Session(Genode::Env &env, Genode::Session_label const &label, Session(Env &env, size_t buffer_size, auto &&... args)
size_t buffer_size) :
: _env(env), _connection(env, label.string(), buffer_size) Session_object<Report::Session>(env.ep(), args...),
{ _env.ep().manage(*this); } _connection(env, label(), buffer_size)
{ }
~Session() { _env.ep().dissolve(*this); } void upgrade(Session::Resources const &resources)
void upgrade(Genode::Session::Resources const &resources)
{ {
_connection.upgrade(resources); _connection.upgrade(resources);
} }
@ -54,47 +52,49 @@ struct Wm::Report_forwarder
** Report::Session interface ** ** Report::Session interface **
*******************************/ *******************************/
Genode::Dataspace_capability dataspace() override Dataspace_capability dataspace() override
{ {
return _connection.dataspace(); return _connection.dataspace();
} }
void submit(Genode::size_t length) override void submit(size_t length) override
{ {
_connection.submit(length); _connection.submit(length);
} }
void response_sigh(Genode::Signal_context_capability sigh) override void response_sigh(Signal_context_capability sigh) override
{ {
_connection.response_sigh(sigh); _connection.response_sigh(sigh);
} }
Genode::size_t obtain_response() override size_t obtain_response() override
{ {
return _connection.obtain_response(); return _connection.obtain_response();
} }
}; };
struct Root : Genode::Root_component<Session> struct Root : Root_component<Session>
{ {
Genode::Env &_env; Env &_env;
Genode::Allocator &_alloc; Allocator &_alloc;
Session *_create_session(char const *args) override Session *_create_session(char const *args) override
{ {
return new (md_alloc()) return new (md_alloc())
Session(_env, Genode::label_from_args(args), Session(_env, Arg_string::find_arg(args, "buffer_size").ulong_value(0),
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 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(env), _alloc(alloc)
{ {
_env.parent().announce(env.ep().manage(*this)); _env.parent().announce(env.ep().manage(*this));
@ -102,8 +102,7 @@ struct Wm::Report_forwarder
} _root; } _root;
Report_forwarder(Genode::Env &env, Genode::Allocator &alloc) Report_forwarder(Env &env, Allocator &alloc) : _root(env, alloc) { }
: _root(env, alloc) { }
}; };
#endif /* _REPORT_FORWARDER_H_ */ #endif /* _REPORT_FORWARDER_H_ */

View File

@ -27,18 +27,17 @@ namespace Wm { struct Rom_forwarder; }
struct Wm::Rom_forwarder struct Wm::Rom_forwarder
{ {
struct Session : Genode::Rpc_object<Genode::Rom_session> struct Session : Session_object<Rom_session>
{ {
Genode::Env &_env; Rom_connection _connection;
Genode::Rom_connection _connection;
Session(Genode::Env &env, Genode::Session_label const &label) Session(Env &env, auto &&... args)
: _env(env), _connection(env, label.string()) :
{ _env.ep().manage(*this); } Session_object<Rom_session>(env.ep(), args...),
_connection(env, label())
{ }
~Session() { _env.ep().dissolve(*this); } void upgrade(Session::Resources const &resources)
void upgrade(Genode::Session::Resources const &resources)
{ {
_connection.upgrade(resources); _connection.upgrade(resources);
} }
@ -48,7 +47,7 @@ struct Wm::Rom_forwarder
** Rom_session interface ** ** Rom_session interface **
***************************/ ***************************/
Genode::Rom_dataspace_capability dataspace() override Rom_dataspace_capability dataspace() override
{ {
return _connection.dataspace(); 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; Env &_env;
Genode::Allocator &_alloc; Allocator &_alloc;
Session *_create_session(char const *args) override 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 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(env), _alloc(alloc)
{ {
_env.parent().announce(env.ep().manage(*this)); _env.parent().announce(env.ep().manage(*this));
@ -89,8 +90,7 @@ struct Wm::Rom_forwarder
} _root; } _root;
Rom_forwarder(Genode::Env &env, Genode::Allocator &alloc) Rom_forwarder(Env &env, Allocator &alloc) : _root(env, alloc) { }
: _root(env, alloc) { }
}; };
#endif /* _ROM_FORWARDER_H_ */ #endif /* _ROM_FORWARDER_H_ */

View File

@ -15,19 +15,25 @@
#define _TYPES_H_ #define _TYPES_H_
/* Genode includes */ /* Genode includes */
#include <util/reconstructible.h>
#include <util/list.h>
#include <base/tslab.h> #include <base/tslab.h>
#include <base/attached_rom_dataspace.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 { namespace Wm {
using Genode::uint8_t; using namespace Genode;
using Genode::size_t;
using Genode::Rom_connection; using Area = Surface_base::Area;
using Genode::Xml_node; using Point = Surface_base::Point;
using Genode::Attached_rom_dataspace; using Rect = Surface_base::Rect;
using Genode::Tslab;
using Genode::Cap_quota;
using Genode::Ram_quota;
/* /*
* Slab allocator that includes an initial block as member * 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) { }; : 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; bool _starved_for_ram = false, _starved_for_caps = false;

View File

@ -16,102 +16,89 @@
/* Genode includes */ /* Genode includes */
#include <util/bit_allocator.h> #include <util/bit_allocator.h>
#include <util/list.h> #include <base/id_space.h>
#include <base/allocator.h>
#include <os/surface.h>
#include <os/reporter.h>
#include <os/session_policy.h>
/* gems includes */ /* gems includes */
#include <gems/local_reporter.h> #include <gems/local_reporter.h>
/* local includes */
#include <types.h>
namespace Wm { class Window_registry; } 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 class Wm::Window_registry
{ {
public: public:
struct Id class Window;
{
unsigned value;
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; } class Window : Noncopyable
bool valid() const { return value != 0; }
};
class Window : public List<Window>::Element
{ {
public: 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 struct Attr
{ {
Title title { }; Gui::Title title;
Session_label label { }; Session_label label;
Area size { }; Area area;
Has_alpha has_alpha = HAS_NO_ALPHA; Alpha alpha;
Hidden hidden = NOT_HIDDEN; Hidden hidden;
Resizeable resizeable = NOT_RESIZEABLE; Resizeable resizeable;
bool operator == (Attr const &other) const bool operator == (Attr const &other) const
{ {
return title == other.title return title == other.title
&& label == other.label && label == other.label
&& size == other.size && area == other.area
&& has_alpha == other.has_alpha && alpha.value == other.alpha.value
&& hidden == other.hidden && hidden.value == other.hidden.value
&& resizeable == other.resizeable; && 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 { }; Attr mutable _flushed_attr { };
friend class Window_registry; friend class Window_registry;
Window(Id id) : _id(id) { } Window(Windows &windows, Id id, Attr const &attr)
: _id(*this, windows, id), _attr(attr) { }
public: public:
Id id() const { return _id; } Id id() const { return _id.id(); }
/* /*
* Accessors for setting attributes * 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(Session_label const &label) { _attr.label = label; }
void attr(Area size) { _attr.size = size; } void attr(Area area) { _attr.area = area; }
void attr(Has_alpha has_alpha) { _attr.has_alpha = has_alpha; } void attr(Alpha alpha) { _attr.alpha = alpha; }
void attr(Hidden hidden) { _attr.hidden = hidden; } void attr(Hidden hidden) { _attr.hidden = hidden; }
void attr(Resizeable resizeable) { _attr.resizeable = resizeable; } 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 void generate_window_list_entry_xml(Xml_generator &xml) const
{ {
/* /*
* Skip windows that have no defined size, which happens * Skip windows that have no defined size, which may happen
* between the creation of a new window and the first * between the creation of a new window for a view w/o size
* time when the window's properties are assigned. * and the first time when the top-level view's size is
* assigned.
*/ */
if (!_attr.size.valid()) if (!_attr.area.valid())
return; return;
xml.node("window", [&] () { xml.node("window", [&] () {
xml.attribute("id", _id.value); xml.attribute("id", id().value);
xml.attribute("label", _attr.label.string()); _attr.gen_window_attr(xml);
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");
}); });
} }
@ -151,61 +127,49 @@ class Wm::Window_registry
bool _flushed() const bool _flushed() const
{ {
bool result = true; bool result = true;
for (Window const *w = _windows.first(); w; w = w->next()) _windows.for_each<Window const>([&] (Window const &w) {
result &= w->flushed(); result &= w.flushed(); });
return result; return result;
} }
private: private:
Allocator &_alloc; Allocator &_alloc;
Reporter &_window_list_reporter; Expanding_reporter &_window_list_reporter;
static constexpr unsigned MAX_WINDOWS = 1024; 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 */ 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()) _windows.apply<Window>(id, fn, missing_fn);
if (w->id() == id)
return w;
return 0;
} }
void _report_updated_window_list_model() const void _report_updated_window_list_model() const
{ {
Reporter::Xml_generator xml(_window_list_reporter, [&] () _window_list_reporter.generate([&] (Xml_generator &xml) {
{ _windows.for_each<Window>([&] (Window const &w) {
for (Window const *w = _windows.first(); w; w = w->next()) { w.generate_window_list_entry_xml(xml);
w->generate_window_list_entry_xml(xml); w.mark_as_flushed();
w->mark_as_flushed(); });
}
}); });
} }
template <typename ATTR> void _set_attr(Id const id, auto const &value)
void _set_attr(Id const id, ATTR const &value)
{ {
Window * const win = _lookup(id); _with_window(id,
[&] (Window &window) { window.attr(value); },
if (!win) { [&] { warning("lookup for window ID ", id.value, " failed"); });
Genode::warning("lookup for window ID ", id.value, " failed");
return;
}
win->attr(value);
} }
public: 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) _alloc(alloc), _window_list_reporter(window_list_reporter)
{ {
@ -213,72 +177,60 @@ class Wm::Window_registry
_window_ids.alloc(); _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; unsigned try_id = _next_id;
_next_id = (_next_id + 1) % MAX_WINDOWS; _next_id = (_next_id + 1) % MAX_WINDOWS;
try { try {
_window_ids.alloc_addr(try_id); _window_ids.alloc_addr(try_id);
return try_id; return Id { try_id };
} }
catch (...) { } 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) { }
);
/* return result;
* 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();
} }
void destroy(Id id) void destroy(Id id)
{ {
Window * const win = _lookup(id); Window *win_ptr = nullptr;
if (!win) _with_window(id, [&] (Window &window) { win_ptr = &window; }, [&] { });
if (!win_ptr)
return; return;
_windows.remove(win); _window_ids.free(win_ptr->id().value);
_window_ids.free(win->id().value); Genode::destroy(&_alloc, win_ptr);
Genode::destroy(&_alloc, win);
_report_updated_window_list_model(); _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 alpha (Id id, bool value) { _set_attr(id, Alpha { value }); }
void hidden (Id id, bool value) { _set_attr(id, Hidden { value }); }
void label(Id id, Window::Session_label const &label) { _set_attr(id, label); } void resizeable(Id id, bool value) { _set_attr(id, Resizeable { value }); }
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 flush() void flush()
{ {