nitpicker: Support pointer as coordinate origin

This commit is contained in:
Norman Feske 2014-07-02 17:37:02 +02:00
parent 1ac343fabd
commit 6c4c4e5528
6 changed files with 104 additions and 18 deletions

View File

@ -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:

View File

@ -400,6 +400,8 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
Mode &_mode;
View &_pointer_origin;
List<Session_view_list_elem> _view_list;
Genode::Tslab<View, 4000> _view_alloc { &_session_alloc };
@ -631,6 +633,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
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<Session>,
_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<Session>,
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<Session_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<Session_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<Session_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_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<PT> 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();
}

View File

@ -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; }

View File

@ -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
*/

View File

@ -96,6 +96,27 @@ class View : public Same_buffer_list_elem,
Genode::List<View_parent_elem> _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; }

View File

@ -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