From 6c4c4e5528d1370f6f4ad62597190377da1e7347 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 2 Jul 2014 17:37:02 +0200 Subject: [PATCH] nitpicker: Support pointer as coordinate origin --- .../os/src/server/nitpicker/domain_registry.h | 42 +++++++++++++++---- repos/os/src/server/nitpicker/main.cc | 27 ++++++++---- repos/os/src/server/nitpicker/session.h | 7 +++- repos/os/src/server/nitpicker/user_state.h | 8 ++++ repos/os/src/server/nitpicker/view.h | 32 ++++++++++++++ repos/os/src/server/nitpicker/view_stack.h | 6 +++ 6 files changed, 104 insertions(+), 18 deletions(-) diff --git a/repos/os/src/server/nitpicker/domain_registry.h b/repos/os/src/server/nitpicker/domain_registry.h index 45420d09b..fe9e5758f 100644 --- a/repos/os/src/server/nitpicker/domain_registry.h +++ b/repos/os/src/server/nitpicker/domain_registry.h @@ -37,17 +37,23 @@ class Domain_registry XRAY_OPAQUE, /* views are replaced by opaque domain color */ }; + /** + * Origin of the domain's coordiate system + */ + enum Origin { ORIGIN_POINTER, ORIGIN_SCREEN }; + private: - Name _name; - Color _color; - Xray _xray; + Name _name; + Color _color; + Xray _xray; + Origin _origin; friend class Domain_registry; - Entry(Name const &name, Color color, Xray xray) + Entry(Name const &name, Color color, Xray xray, Origin origin) : - _name(name), _color(color), _xray(xray) + _name(name), _color(color), _xray(xray), _origin(origin) { } public: @@ -56,8 +62,9 @@ class Domain_registry Color color() const { return _color; } - bool xray_opaque() const { return _xray == XRAY_OPAQUE; } - bool xray_no() const { return _xray == XRAY_NO; } + bool xray_opaque() const { return _xray == XRAY_OPAQUE; } + bool xray_no() const { return _xray == XRAY_NO; } + bool origin_pointer() const { return _origin == ORIGIN_POINTER; } }; static Entry::Xray _xray(Genode::Xml_node domain) @@ -79,6 +86,24 @@ class Domain_registry return default_xray; } + Entry::Origin _origin(Genode::Xml_node domain) + { + char const * const attr_name = "origin"; + + Entry::Origin const default_origin = Entry::ORIGIN_SCREEN; + + if (!domain.has_attribute(attr_name)) + return default_origin; + + Genode::Xml_node::Attribute const attr = domain.attribute(attr_name); + + if (attr.has_value("screen")) return Entry::ORIGIN_SCREEN; + if (attr.has_value("pointer")) return Entry::ORIGIN_POINTER; + + PWRN("invalid value of origin attribute"); + return default_origin; + } + void _insert(Genode::Xml_node domain) { char buf[sizeof(Entry::Name)]; @@ -103,7 +128,8 @@ class Domain_registry Entry::Color const color = domain.attribute_value("color", WHITE); - _entries.insert(new (_alloc) Entry(name, color, _xray(domain))); + _entries.insert(new (_alloc) Entry(name, color, _xray(domain), + _origin(domain))); } private: diff --git a/repos/os/src/server/nitpicker/main.cc b/repos/os/src/server/nitpicker/main.cc index 0a313d9ea..793a2d64c 100644 --- a/repos/os/src/server/nitpicker/main.cc +++ b/repos/os/src/server/nitpicker/main.cc @@ -400,6 +400,8 @@ class Nitpicker::Session_component : public Genode::Rpc_object, Mode &_mode; + View &_pointer_origin; + List _view_list; Genode::Tslab _view_alloc { &_session_alloc }; @@ -631,6 +633,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object, Session_component(Session_label const &label, View_stack &view_stack, Mode &mode, + View &pointer_origin, Rpc_entrypoint &ep, Framebuffer::Session &framebuffer, int v_offset, @@ -644,6 +647,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object, _framebuffer(framebuffer), _framebuffer_session_component(view_stack, *this, framebuffer, *this), _ep(ep), _view_stack(view_stack), _mode(mode), + _pointer_origin(pointer_origin), _framebuffer_session_cap(_ep.manage(&_framebuffer_session_component)), _input_session_cap(_ep.manage(&_input_session_component)), _provides_default_bg(provides_default_bg), @@ -752,6 +756,8 @@ class Nitpicker::Session_component : public Genode::Rpc_object, throw Nitpicker::Session::Out_of_metadata(); } } + view->apply_origin_policy(_pointer_origin); + _view_list.insert(view); _ep.manage(view); @@ -902,6 +908,7 @@ class Nitpicker::Root : public Genode::Root_component Framebuffer::Mode _scr_mode; View_stack &_view_stack; Mode &_mode; + ::View &_pointer_origin; Framebuffer::Session &_framebuffer; int _default_v_offset; @@ -931,9 +938,10 @@ class Nitpicker::Root : public Genode::Root_component bool const provides_default_bg = (strcmp(label.string(), "backdrop") == 0); Session_component *session = new (md_alloc()) - Session_component(Session_label(args), _view_stack, _mode, *ep(), - _framebuffer, v_offset, provides_default_bg, - stay_top, *md_alloc(), unused_quota); + Session_component(Session_label(args), _view_stack, _mode, + _pointer_origin, *ep(), _framebuffer, + v_offset, provides_default_bg, stay_top, + *md_alloc(), unused_quota); session->apply_session_policy(_domain_registry); _session_list.insert(session); @@ -967,13 +975,14 @@ class Nitpicker::Root : public Genode::Root_component 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) + ::View &pointer_origin, Allocator &md_alloc, + Framebuffer::Session &framebuffer, int default_v_offset) : Root_component(&session_ep, &md_alloc), _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) + _pointer_origin(pointer_origin), _framebuffer(framebuffer), + _default_v_offset(default_v_offset) { } }; @@ -1071,8 +1080,8 @@ struct Nitpicker::Main Genode::Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() }; Root np_root = { session_list, *domain_registry, global_keys, - ep.rpc_ep(), user_state, user_state, sliced_heap, - framebuffer, Framebuffer_screen::MENUBAR_HEIGHT }; + ep.rpc_ep(), user_state, user_state, mouse_cursor, + sliced_heap, framebuffer, Framebuffer_screen::MENUBAR_HEIGHT }; Genode::Reporter pointer_reporter = { "pointer" }; @@ -1217,6 +1226,8 @@ void Nitpicker::Main::handle_config(unsigned) for (::Session *s = session_list.first(); s; s = s->next()) s->apply_session_policy(*domain_registry); + user_state.apply_origin_policy(mouse_cursor); + /* redraw */ user_state.update_all_views(); } diff --git a/repos/os/src/server/nitpicker/session.h b/repos/os/src/server/nitpicker/session.h index bd266068e..1a0d955ae 100644 --- a/repos/os/src/server/nitpicker/session.h +++ b/repos/os/src/server/nitpicker/session.h @@ -66,8 +66,11 @@ class Session : public Session_list::Element Genode::Session_label const &label() const { return _label; } - bool xray_opaque() const { return _domain ? _domain->xray_opaque() : false; } - bool xray_no() const { return _domain ? _domain->xray_no() : false; } + bool xray_opaque() const { return _domain && _domain->xray_opaque(); } + + bool xray_no() const { return _domain && _domain->xray_no(); } + + bool origin_pointer() const { return _domain && _domain->origin_pointer(); } Texture_base const *texture() const { return _texture; } diff --git a/repos/os/src/server/nitpicker/user_state.h b/repos/os/src/server/nitpicker/user_state.h index c875a11c1..7c93b8bc3 100644 --- a/repos/os/src/server/nitpicker/user_state.h +++ b/repos/os/src/server/nitpicker/user_state.h @@ -82,6 +82,14 @@ class User_state : public Mode, public View_stack */ Point mouse_pos() { return _mouse_pos; } + /** + * (Re-)apply origin policy to all views + */ + void apply_origin_policy(View &pointer_origin) + { + View_stack::apply_origin_policy(pointer_origin); + } + /** * Mode interface */ diff --git a/repos/os/src/server/nitpicker/view.h b/repos/os/src/server/nitpicker/view.h index 53099a458..27aaf82c5 100644 --- a/repos/os/src/server/nitpicker/view.h +++ b/repos/os/src/server/nitpicker/view.h @@ -96,6 +96,27 @@ class View : public Same_buffer_list_elem, Genode::List _children; + /** + * Assign new parent + * + * Normally, the parent of a view is defined at the construction time + * of the view. However, if the domain origin changes at runtime, we + * need to dynamically re-assign the pointer origin as the parent. + */ + void _assign_parent(View *parent) + { + if (_parent == parent) + return; + + if (_parent) + _parent->remove_child(*this); + + _parent = parent; + + if (_parent) + _parent->add_child(*this); + } + public: View(Session &session, Stay_top stay_top, Transparent transparent, @@ -146,6 +167,17 @@ class View : public Same_buffer_list_elem, _geometry = Rect(); } + bool has_parent(View const &parent) const { return &parent == _parent; } + + void apply_origin_policy(View &pointer_origin) + { + if (session().origin_pointer() && !has_parent(pointer_origin)) + _assign_parent(&pointer_origin); + + if (!session().origin_pointer() && has_parent(pointer_origin)) + _assign_parent(0); + } + Rect geometry() const { return _geometry; } void geometry(Rect geometry) { _geometry = geometry; } diff --git a/repos/os/src/server/nitpicker/view_stack.h b/repos/os/src/server/nitpicker/view_stack.h index bba89a5f0..e079ef53e 100644 --- a/repos/os/src/server/nitpicker/view_stack.h +++ b/repos/os/src/server/nitpicker/view_stack.h @@ -256,6 +256,12 @@ class View_stack next_view = view ? view->view_stack_next() : 0; } } + + void apply_origin_policy(View &pointer_origin) + { + for (View *v = _first_view(); v; v = v->view_stack_next()) + v->apply_origin_policy(pointer_origin); + } }; #endif