mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 07:08:18 +00:00
nitpicker: Dynamic config of session policies
This commit is contained in:
@ -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)
|
||||||
|
@ -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)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
@ -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,23 +538,20 @@ 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
|
||||||
|
|
||||||
size_t required_quota = texture_num_bytes
|
|
||||||
+ Input::Session_component::ev_ds_size();
|
+ Input::Session_component::ev_ds_size();
|
||||||
|
|
||||||
if (ram_quota < required_quota) {
|
if (ram_quota < required_quota) {
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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,16 +33,12 @@ 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;
|
||||||
@ -50,8 +48,7 @@ class Session : public Session_list::Element
|
|||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user