diff --git a/repos/os/run/demo.run b/repos/os/run/demo.run
index 20784afe7e..5c2145f0e7 100644
--- a/repos/os/run/demo.run
+++ b/repos/os/run/demo.run
@@ -119,6 +119,9 @@ append config {
+
+
+
diff --git a/repos/os/src/server/nitpicker/domain_registry.h b/repos/os/src/server/nitpicker/domain_registry.h
new file mode 100644
index 0000000000..9321a20d1f
--- /dev/null
+++ b/repos/os/src/server/nitpicker/domain_registry.h
@@ -0,0 +1,119 @@
+/*
+ * \brief Domain registry
+ * \author Norman Feske
+ * \date 2014-06-12
+ */
+
+/*
+ * Copyright (C) 2014 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU General Public License version 2.
+ */
+
+#ifndef _DOMAIN_REGISTRY_
+#define _DOMAIN_REGISTRY_
+
+#include
+#include
+
+class Domain_registry
+{
+ public:
+
+ class Entry : public Genode::List::Element
+ {
+ public:
+
+ typedef Genode::String<64> Name;
+ typedef Genode::Color Color;
+
+ private:
+
+ Name _name;
+ Color _color;
+
+ friend class Domain_registry;
+
+ Entry(Name const &name, Color color)
+ :
+ _name(name), _color(color)
+ { }
+
+ public:
+
+ bool has_name(Name const &name) const { return name == _name; }
+
+ Color color() const { return _color; }
+ };
+
+ void _insert(Genode::Xml_node domain)
+ {
+ char buf[sizeof(Entry::Name)];
+ buf[0] = 0;
+ bool name_defined = false;
+ try {
+ domain.attribute("name").value(buf, sizeof(buf));
+ name_defined = true;
+ } catch (...) { }
+
+ if (!name_defined) {
+ PERR("no valid domain name specified");
+ return;
+ }
+
+ Entry::Name const name(buf);
+
+ if (lookup(name)) {
+ PERR("domain name \"%s\" is not unique", name.string());
+ return;
+ }
+
+ Entry::Color const color = domain.attribute_value("color", Entry::Color());
+
+ _entries.insert(new (_alloc) Entry(name, color));
+ }
+
+ private:
+
+ Genode::List _entries;
+ Genode::Allocator &_alloc;
+
+ public:
+
+ Domain_registry(Genode::Allocator &alloc, Genode::Xml_node config)
+ :
+ _alloc(alloc)
+ {
+ char const *type = "domain";
+
+ if (!config.has_sub_node(type))
+ return;
+
+ Genode::Xml_node domain = config.sub_node(type);
+
+ for (;; domain = domain.next(type)) {
+
+ _insert(domain);
+
+ if (domain.is_last(type))
+ break;
+ }
+ }
+
+ ~Domain_registry()
+ {
+ while (Entry *e = _entries.first())
+ Genode::destroy(_alloc, e);
+ }
+
+ Entry const *lookup(Entry::Name const &name) const
+ {
+ for (Entry const *e = _entries.first(); e; e = e->next())
+ if (e->has_name(name))
+ return e;
+ return 0;
+ }
+};
+
+#endif /* _DOMAIN_REGISTRY_ */
diff --git a/repos/os/src/server/nitpicker/main.cc b/repos/os/src/server/nitpicker/main.cc
index ef1d97e4dd..e10e7c8378 100644
--- a/repos/os/src/server/nitpicker/main.cc
+++ b/repos/os/src/server/nitpicker/main.cc
@@ -39,6 +39,7 @@
#include "clip_guard.h"
#include "mouse_cursor.h"
#include "chunky_menubar.h"
+#include "domain_registry.h"
namespace Input { class Session_component; }
namespace Framebuffer { class Session_component; }
@@ -895,13 +896,14 @@ class Nitpicker::Root : public Genode::Root_component
{
private:
- Session_list &_session_list;
- Global_keys &_global_keys;
- Framebuffer::Mode _scr_mode;
- View_stack &_view_stack;
- Mode &_mode;
- Framebuffer::Session &_framebuffer;
- int _default_v_offset;
+ Session_list &_session_list;
+ Domain_registry const &_domain_registry;
+ Global_keys &_global_keys;
+ Framebuffer::Mode _scr_mode;
+ View_stack &_view_stack;
+ Mode &_mode;
+ Framebuffer::Session &_framebuffer;
+ int _default_v_offset;
protected:
@@ -933,7 +935,7 @@ class Nitpicker::Root : public Genode::Root_component
_framebuffer, v_offset, provides_default_bg,
stay_top, *md_alloc(), unused_quota);
- session->apply_session_color();
+ session->apply_session_policy(_domain_registry);
_session_list.insert(session);
_global_keys.apply_config(_session_list);
@@ -962,17 +964,16 @@ class Nitpicker::Root : public Genode::Root_component
/**
* Constructor
*/
- Root(Session_list &session_list, Global_keys &global_keys,
- Rpc_entrypoint &session_ep, View_stack &view_stack,
- Mode &mode, Allocator &md_alloc,
- Framebuffer::Session &framebuffer,
+ Root(Session_list &session_list,
+ Domain_registry const &domain_registry, Global_keys &global_keys,
+ Rpc_entrypoint &session_ep, View_stack &view_stack, Mode &mode,
+ Allocator &md_alloc, Framebuffer::Session &framebuffer,
int default_v_offset)
:
Root_component(&session_ep, &md_alloc),
- _session_list(session_list), _global_keys(global_keys),
- _view_stack(view_stack), _mode(mode),
- _framebuffer(framebuffer),
- _default_v_offset(default_v_offset)
+ _session_list(session_list), _domain_registry(domain_registry),
+ _global_keys(global_keys), _view_stack(view_stack), _mode(mode),
+ _framebuffer(framebuffer), _default_v_offset(default_v_offset)
{ }
};
@@ -1046,6 +1047,13 @@ struct Nitpicker::Main
Session_list session_list;
+ /*
+ * Construct empty domain registry. The initial version will be replaced
+ * on the first call of 'handle_config'.
+ */
+ Genode::Volatile_object domain_registry {
+ *env()->heap(), Genode::Xml_node("") };
+
User_state user_state = { global_keys, fb_screen->screen.size(), fb_screen->menubar };
/*
@@ -1062,9 +1070,9 @@ struct Nitpicker::Main
*/
Genode::Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() };
- Root np_root = { session_list, global_keys, ep.rpc_ep(), user_state,
- user_state, sliced_heap, framebuffer,
- Framebuffer_screen::MENUBAR_HEIGHT };
+ Root np_root = { session_list, *domain_registry, global_keys,
+ ep.rpc_ep(), user_state, user_state, sliced_heap,
+ framebuffer, Framebuffer_screen::MENUBAR_HEIGHT };
Genode::Reporter pointer_reporter = { "pointer" };
@@ -1196,9 +1204,16 @@ void Nitpicker::Main::handle_config(unsigned)
.has_value("yes"));
} catch (...) { }
- /* update session policies */
+ /* update domain registry and session policies */
for (::Session *s = session_list.first(); s; s = s->next())
- s->apply_session_color();
+ s->reset_domain();
+
+ try {
+ domain_registry.construct(*env()->heap(), config()->xml_node()); }
+ catch (...) { }
+
+ for (::Session *s = session_list.first(); s; s = s->next())
+ s->apply_session_policy(*domain_registry);
/* redraw */
user_state.update_all_views();
diff --git a/repos/os/src/server/nitpicker/mode.h b/repos/os/src/server/nitpicker/mode.h
index c41c8b5044..cc73a62673 100644
--- a/repos/os/src/server/nitpicker/mode.h
+++ b/repos/os/src/server/nitpicker/mode.h
@@ -53,7 +53,8 @@ class Mode
bool has_key_cnt(unsigned cnt) const { return cnt == _key_cnt; }
- Session *focused_session() { return _focused_session; }
+ Session *focused_session() { return _focused_session; }
+ Session const *focused_session() const { return _focused_session; }
virtual void focused_session(Session *session) { _focused_session = session; }
diff --git a/repos/os/src/server/nitpicker/session.h b/repos/os/src/server/nitpicker/session.h
index 1f797ea8cc..8dff028d58 100644
--- a/repos/os/src/server/nitpicker/session.h
+++ b/repos/os/src/server/nitpicker/session.h
@@ -22,6 +22,7 @@
/* local includes */
#include "color.h"
#include "canvas.h"
+#include "domain_registry.h"
class View;
class Session;
@@ -34,14 +35,14 @@ class Session : public Session_list::Element
{
private:
- Genode::Session_label const _label;
- Color _color;
- Texture_base const *_texture = { 0 };
- bool _uses_alpha = { false };
- View *_background = 0;
- int _v_offset;
- unsigned char const *_input_mask = { 0 };
- bool const _stay_top;
+ Genode::Session_label const _label;
+ Domain_registry::Entry const *_domain;
+ Texture_base const *_texture = { 0 };
+ bool _uses_alpha = { false };
+ View *_background = 0;
+ int _v_offset;
+ unsigned char const *_input_mask = { 0 };
+ bool const _stay_top;
public:
@@ -87,7 +88,7 @@ class Session : public Session_list::Element
*/
void input_mask(unsigned char const *mask) { _input_mask = mask; }
- Color color() const { return _color; }
+ Color color() const { return _domain ? _domain->color() : WHITE; }
View *background() const { return _background; }
@@ -120,22 +121,51 @@ class Session : public Session_list::Element
return _input_mask[p.y()*_texture->size().w() + p.x()];
}
+ bool has_same_domain(Session const *s) const
+ {
+ return s && (s->_domain == _domain);
+ }
+
+ bool has_valid_domain() const
+ {
+ return _domain;
+ }
+
+ void reset_domain()
+ {
+ _domain = nullptr;
+ }
+
/**
- * Set session color according to the list of configured policies
+ * Set session domain according to the list of configured policies
*
* Select the policy that matches the label. If multiple policies
* match, select the one with the largest number of characters.
*/
- void apply_session_color()
+ void apply_session_policy(Domain_registry const &domain_registry)
{
- /* use white by default */
- _color = WHITE;
+ reset_domain();
try {
Genode::Session_policy policy(_label);
- /* read color attribute */
- policy.attribute("color").value(&_color);
+ /* read domain attribute */
+ if (!policy.has_attribute("domain")) {
+ PERR("policy for label \"%s\" lacks domain declaration",
+ _label.string());
+ return;
+ }
+
+ typedef Domain_registry::Entry::Name Domain_name;
+ char buf[sizeof(Domain_name)];
+ buf[0] = 0;
+ try {
+ policy.attribute("domain").value(buf, sizeof(buf)); }
+ catch (...) { }
+
+ Domain_name name(buf);
+ _domain = domain_registry.lookup(name);
+
} catch (...) { }
}
};
diff --git a/repos/os/src/server/nitpicker/view.cc b/repos/os/src/server/nitpicker/view.cc
index b07ddb89df..4025491690 100644
--- a/repos/os/src/server/nitpicker/view.cc
+++ b/repos/os/src/server/nitpicker/view.cc
@@ -79,8 +79,7 @@ void View::frame(Canvas_base &canvas, Mode const &mode) const
void View::draw(Canvas_base &canvas, Mode const &mode) const
{
- /* is this the currently focused view? */
- bool const session_is_focused = mode.is_focused(_session);
+ bool const is_focused = _session.has_same_domain(mode.focused_session());
Color const frame_color = _session.color();
@@ -88,7 +87,7 @@ void View::draw(Canvas_base &canvas, Mode const &mode) const
* Use dimming in x-ray and kill mode, but do not dim the focused view in
* x-ray mode.
*/
- Texture_painter::Mode const op = mode.flat() || (mode.xray() && session_is_focused)
+ Texture_painter::Mode const op = mode.flat() || (mode.xray() && is_focused)
? Texture_painter::SOLID : Texture_painter::MIXED;
Rect const view_rect = abs_geometry();