nitpicker: Dynamic config of session policies

This commit is contained in:
Norman Feske
2013-09-09 22:39:54 +02:00
parent 6575856624
commit 6cd5407ed9
8 changed files with 93 additions and 100 deletions

View File

@ -28,7 +28,7 @@ struct Background : private Texture, Session, View
*/ */
Background(Area size) Background(Area size)
: :
Texture(Area(0, 0)), Session("", *this, 0, BLACK), Texture(Area(0, 0)), Session(Genode::Session_label(""), *this, 0),
View(*this, View::NOT_STAY_TOP, View::NOT_TRANSPARENT, View(*this, View::NOT_STAY_TOP, View::NOT_TRANSPARENT,
View::BACKGROUND, Rect(Point(0, 0), size)), View::BACKGROUND, Rect(Point(0, 0), size)),
color(25, 37, 50) color(25, 37, 50)

View File

@ -29,7 +29,8 @@ class Chunky_menubar : public Chunky_texture<PT>,
Chunky_menubar(PT *pixels, Area size) Chunky_menubar(PT *pixels, Area size)
: :
Chunky_texture<PT>(pixels, 0, size), Session("", *this, 0, BLACK), Chunky_texture<PT>(pixels, 0, size),
Session(Genode::Session_label(""), *this, 0),
Menubar(_chunky_canvas, size, *this), _chunky_canvas(pixels, size) Menubar(_chunky_canvas, size, *this), _chunky_canvas(pixels, size)
{ } { }

View File

@ -81,7 +81,7 @@ void Global_keys::apply_config(Session_list &session_list)
/* assign policy to matching client session */ /* assign policy to matching client session */
for (Session *s = session_list.first(); s; s = s->next()) for (Session *s = session_list.first(); s; s = s->next())
if (node.attribute("label").has_value(s->label())) if (node.attribute("label").has_value(s->label().string()))
policy->client(s); policy->client(s);
} }

View File

@ -56,31 +56,6 @@ namespace Nitpicker {
** Utilities ** ** Utilities **
***************/ ***************/
/**
* Determine session color 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.
*/
static Color session_color(char const *session_args)
{
using namespace Genode;
/* use white by default */
Color color = WHITE;
try {
Session_label label(session_args);
Session_policy policy(label);
/* read color attribute */
policy.attribute("color").value(&color);
} catch (...) { }
return color;
}
/* /*
* Font initialization * Font initialization
*/ */
@ -93,15 +68,13 @@ class Flush_merger
{ {
private: private:
Rect _to_be_flushed; Rect _to_be_flushed = { Point(), Area(-1, -1) };
public: public:
bool defer; bool defer = false;
Flush_merger() : _to_be_flushed(Point(), Area(-1, -1)), defer(false) { } Rect to_be_flushed() const { return _to_be_flushed; }
Rect to_be_flushed() { return _to_be_flushed; }
void merge(Rect rect) void merge(Rect rect)
{ {
@ -127,8 +100,7 @@ class Screen : public Chunky_canvas<PT>, public Flush_merger
/** /**
* Constructor * Constructor
*/ */
Screen(PT *scr_base, Area scr_size): Screen(PT *base, Area size) : Chunky_canvas<PT>(base, size) { }
Chunky_canvas<PT>(scr_base, scr_size) { }
}; };
@ -148,7 +120,8 @@ class Buffer
* \throw Ram_session::Alloc_failed * \throw Ram_session::Alloc_failed
* \throw Rm_session::Attach_failed * \throw Rm_session::Attach_failed
*/ */
Buffer(Area size, Framebuffer::Mode::Format format, Genode::size_t bytes): Buffer(Area size, Framebuffer::Mode::Format format, Genode::size_t bytes)
:
_size(size), _format(format), _size(size), _format(format),
_ram_ds(Genode::env()->ram_session(), bytes) _ram_ds(Genode::env()->ram_session(), bytes)
{ } { }
@ -156,10 +129,10 @@ class Buffer
/** /**
* Accessors * Accessors
*/ */
Genode::Ram_dataspace_capability ds_cap() { return _ram_ds.cap(); } Genode::Ram_dataspace_capability ds_cap() const { return _ram_ds.cap(); }
Area size() { return _size; } Area size() const { return _size; }
Framebuffer::Mode::Format format() { return _format; } Framebuffer::Mode::Format format() const { return _format; }
void *local_addr() { return _ram_ds.local_addr<void>(); } void *local_addr() const { return _ram_ds.local_addr<void>(); }
}; };
@ -187,7 +160,8 @@ class Chunky_dataspace_texture : public Buffer, public Chunky_texture<PT>
/** /**
* Constructor * Constructor
*/ */
Chunky_dataspace_texture(Area size, bool use_alpha): Chunky_dataspace_texture(Area size, bool use_alpha)
:
Buffer(size, _format(), calc_num_bytes(size, use_alpha)), Buffer(size, _format(), calc_num_bytes(size, use_alpha)),
Chunky_texture<PT>((PT *)local_addr(), Chunky_texture<PT>((PT *)local_addr(),
_alpha_base(size, use_alpha), size) { } _alpha_base(size, use_alpha), size) { }
@ -225,12 +199,15 @@ class Input::Session_component : public Genode::Rpc_object<Session>
enum { MAX_EVENTS = 200 }; enum { MAX_EVENTS = 200 };
static size_t ev_ds_size() {
return align_addr(MAX_EVENTS*sizeof(Event), 12); }
private: private:
/* /*
* Exported event buffer dataspace * Exported event buffer dataspace
*/ */
Attached_ram_dataspace _ev_ram_ds; Attached_ram_dataspace _ev_ram_ds = { env()->ram_session(), ev_ds_size() };
/* /*
* Local event buffer that is copied * Local event buffer that is copied
@ -238,20 +215,10 @@ class Input::Session_component : public Genode::Rpc_object<Session>
* flush() gets called. * flush() gets called.
*/ */
Event _ev_buf[MAX_EVENTS]; Event _ev_buf[MAX_EVENTS];
unsigned _num_ev; unsigned _num_ev = 0;
public: public:
static size_t ev_ds_size() {
return align_addr(MAX_EVENTS*sizeof(Event), 12); }
/**
* Constructor
*/
Session_component():
_ev_ram_ds(env()->ram_session(), ev_ds_size()),
_num_ev(0) { }
/** /**
* Enqueue event into local event buffer of the input session * Enqueue event into local event buffer of the input session
*/ */
@ -419,7 +386,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
Framebuffer::Session_component _framebuffer_session_component; Framebuffer::Session_component _framebuffer_session_component;
/* Input_session_component */ /* Input_session_component */
Input::Session_component _input_session_component; Input::Session_component _input_session_component;
/* /*
* Entrypoint that is used for the views, input session, * Entrypoint that is used for the views, input session,
@ -435,14 +402,14 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
Framebuffer::Session_capability _framebuffer_session_cap; Framebuffer::Session_capability _framebuffer_session_cap;
Input::Session_capability _input_session_cap; Input::Session_capability _input_session_cap;
bool _provides_default_bg; bool const _provides_default_bg;
public: public:
/** /**
* Constructor * Constructor
*/ */
Session_component(char const *name, Session_component(Session_label const &label,
::Buffer &buffer, ::Buffer &buffer,
Texture const &texture, Texture const &texture,
View_stack &view_stack, View_stack &view_stack,
@ -452,10 +419,9 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
int v_offset, int v_offset,
unsigned char const *input_mask, unsigned char const *input_mask,
bool provides_default_bg, bool provides_default_bg,
Color color,
bool stay_top) bool stay_top)
: :
::Session(name, texture, v_offset, color, input_mask, stay_top), ::Session(label, texture, v_offset, input_mask, stay_top),
_framebuffer_session_component(buffer, view_stack, *this, flush_merger, framebuffer), _framebuffer_session_component(buffer, view_stack, *this, flush_merger, framebuffer),
_ep(ep), _view_stack(view_stack), _ep(ep), _view_stack(view_stack),
_framebuffer_session_cap(_ep.manage(&_framebuffer_session_component)), _framebuffer_session_cap(_ep.manage(&_framebuffer_session_component)),
@ -572,24 +538,21 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
Session_component *_create_session(const char *args) Session_component *_create_session(const char *args)
{ {
PINF("create session with args: %s\n", args); PINF("create session with args: %s\n", args);
size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
int v_offset = _default_v_offset; int const v_offset = _default_v_offset;
/* determine buffer size of the session */ /* determine buffer size of the session */
Area size(Arg_string::find_arg(args, "fb_width" ).long_value(_scr_size.w()), Area const size(Arg_string::find_arg(args, "fb_width" ).long_value(_scr_size.w()),
Arg_string::find_arg(args, "fb_height").long_value(_scr_size.h() - v_offset)); Arg_string::find_arg(args, "fb_height").long_value(_scr_size.h() - v_offset));
char label_buf[::Session::LABEL_LEN]; bool const use_alpha = Arg_string::find_arg(args, "alpha").bool_value(false);
Arg_string::find_arg(args, "label").string(label_buf, sizeof(label_buf), "<unlabeled>"); bool const stay_top = Arg_string::find_arg(args, "stay_top").bool_value(false);
bool use_alpha = Arg_string::find_arg(args, "alpha").bool_value(false); size_t const texture_num_bytes = Chunky_dataspace_texture<PT>::calc_num_bytes(size, use_alpha);
bool stay_top = Arg_string::find_arg(args, "stay_top").bool_value(false);
size_t texture_num_bytes = Chunky_dataspace_texture<PT>::calc_num_bytes(size, use_alpha); size_t const required_quota = texture_num_bytes
+ Input::Session_component::ev_ds_size();
size_t required_quota = texture_num_bytes
+ Input::Session_component::ev_ds_size();
if (ram_quota < required_quota) { if (ram_quota < required_quota) {
PWRN("Insufficient dontated ram_quota (%zd bytes), require %zd bytes", PWRN("Insufficient dontated ram_quota (%zd bytes), require %zd bytes",
@ -598,18 +561,20 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
} }
/* allocate texture */ /* allocate texture */
Chunky_dataspace_texture<PT> *cdt; Chunky_dataspace_texture<PT> * const cdt =
cdt = new (md_alloc()) Chunky_dataspace_texture<PT>(size, use_alpha); new (md_alloc()) Chunky_dataspace_texture<PT>(size, use_alpha);
bool provides_default_bg = (strcmp(label_buf, "backdrop") == 0); Session_label const label(args);
bool const provides_default_bg = (strcmp(label.string(), "backdrop") == 0);
Session_component *session = new (md_alloc()) Session_component *session = new (md_alloc())
Session_component(label_buf, *cdt, *cdt, _view_stack, *ep(), Session_component(Session_label(args), *cdt, *cdt,
_flush_merger, _framebuffer, v_offset, _view_stack, *ep(), _flush_merger,
_framebuffer, v_offset,
cdt->input_mask_buffer(), cdt->input_mask_buffer(),
provides_default_bg, session_color(args), provides_default_bg, stay_top);
stay_top);
session->apply_session_color();
_session_list.insert(session); _session_list.insert(session);
_global_keys.apply_config(_session_list); _global_keys.apply_config(_session_list);
@ -808,11 +773,21 @@ void Nitpicker::Main::handle_input(unsigned)
void Nitpicker::Main::handle_config(unsigned) void Nitpicker::Main::handle_config(unsigned)
{ {
config()->reload(); config()->reload();
/* update global keys policy */
global_keys.apply_config(session_list); global_keys.apply_config(session_list);
/* update background color */
try { try {
config()->xml_node().sub_node("background") config()->xml_node().sub_node("background")
.attribute("color").value(&background.color); .attribute("color").value(&background.color);
} catch (...) { } } catch (...) { }
/* update session policies */
for (::Session *s = session_list.first(); s; s = s->next())
s->apply_session_color();
/* redraw */
user_state.update_all_views(); user_state.update_all_views();
} }

View File

@ -37,7 +37,7 @@ class Mouse_cursor : public Chunky_texture<PT>, public Session, public View
Mouse_cursor(PT const *pixels, Area size, View_stack const &view_stack) Mouse_cursor(PT const *pixels, Area size, View_stack const &view_stack)
: :
Chunky_texture<PT>(pixels, 0, size), Chunky_texture<PT>(pixels, 0, size),
Session("", *this, 0, BLACK), Session(Genode::Session_label(""), *this, 0),
View(*this, View::STAY_TOP, View::TRANSPARENT, View::NOT_BACKGROUND, View(*this, View::STAY_TOP, View::TRANSPARENT, View::NOT_BACKGROUND,
Rect()), Rect()),
_view_stack(view_stack) _view_stack(view_stack)

View File

@ -20,6 +20,8 @@
#include <nitpicker_gfx/color.h> #include <nitpicker_gfx/color.h>
#include <nitpicker_gfx/geometry.h> #include <nitpicker_gfx/geometry.h>
#include <nitpicker_gfx/canvas.h> #include <nitpicker_gfx/canvas.h>
#include <nitpicker_gfx/string.h>
#include <os/session_policy.h>
class Texture; class Texture;
class View; class View;
@ -31,27 +33,22 @@ typedef Genode::List<Session> Session_list;
class Session : public Session_list::Element class Session : public Session_list::Element
{ {
public:
enum { LABEL_LEN = 64 }; /* max. length of session label */
private: private:
char _label[LABEL_LEN]; Genode::Session_label const _label;
Color _color; Color _color;
Texture const &_texture; Texture const &_texture;
View *_background; View *_background = 0;
int _v_offset; int _v_offset;
unsigned char const *_input_mask; unsigned char const *_input_mask;
bool const _stay_top; bool const _stay_top;
public: public:
/** /**
* Constructor * Constructor
* *
* \param label textual session label as null-terminated * \param label session label
* ASCII string
* \param texture texture containing the session's pixel * \param texture texture containing the session's pixel
* representation * representation
* \param v_offset vertical screen offset of session * \param v_offset vertical screen offset of session
@ -65,19 +62,19 @@ class Session : public Session_list::Element
* 'input_mask' is a null pointer, user input is * 'input_mask' is a null pointer, user input is
* unconditionally consumed by the view. * unconditionally consumed by the view.
*/ */
Session(char const *label, Texture const &texture, int v_offset, Session(Genode::Session_label const &label, Texture const &texture,
Color color, unsigned char const *input_mask = 0, int v_offset, unsigned char const *input_mask = 0,
bool stay_top = false) bool stay_top = false)
: :
_color(color), _texture(texture), _background(0), _label(label), _texture(texture), _v_offset(v_offset),
_v_offset(v_offset), _input_mask(input_mask), _stay_top(stay_top) { _input_mask(input_mask), _stay_top(stay_top)
Genode::strncpy(_label, label, sizeof(_label)); } { }
virtual ~Session() { } virtual ~Session() { }
virtual void submit_input_event(Input::Event ev) = 0; virtual void submit_input_event(Input::Event ev) = 0;
char const *label() const { return _label; } Genode::Session_label const &label() const { return _label; }
Texture const &texture() const { return _texture; } Texture const &texture() const { return _texture; }
@ -113,6 +110,26 @@ class Session : public Session_list::Element
return _input_mask[p.y()*_texture.w() + p.x()]; return _input_mask[p.y()*_texture.w() + p.x()];
} }
/**
* Set session color 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()
{
/* use white by default */
_color = WHITE;
try {
Genode::Session_policy policy(_label);
/* read color attribute */
policy.attribute("color").value(&_color);
} catch (...) { }
}
}; };
#endif #endif

View File

@ -114,7 +114,7 @@ void User_state::handle_event(Input::Event ev)
if (user_state._input_receiver) if (user_state._input_receiver)
user_state._menubar.state(user_state, user_state._menubar.state(user_state,
user_state._input_receiver->label(), user_state._input_receiver->label().string(),
menu_title, menu_title,
user_state._input_receiver->color()); user_state._input_receiver->color());
else else

View File

@ -58,7 +58,7 @@ void View::title(const char *title)
Genode::strncpy(_title, title, TITLE_LEN); Genode::strncpy(_title, title, TITLE_LEN);
/* calculate label size, the position is defined by the view stack */ /* calculate label size, the position is defined by the view stack */
_label_rect = Rect(Point(0, 0), label_size(_session.label(), _title)); _label_rect = Rect(Point(0, 0), label_size(_session.label().string(), _title));
} }
@ -115,5 +115,5 @@ void View::draw(Canvas &canvas, Mode const &mode) const
if (mode.flat()) return; if (mode.flat()) return;
/* draw label */ /* draw label */
draw_label(canvas, _label_rect.p1(), _session.label(), WHITE, _title, frame_color); draw_label(canvas, _label_rect.p1(), _session.label().string(), WHITE, _title, frame_color);
} }