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();