nitpicker: Support for dynamic screen resizing

Fixes #1056
This commit is contained in:
Norman Feske 2014-02-11 15:11:31 +01:00
parent 0056167157
commit 14718401ea
10 changed files with 252 additions and 125 deletions

View File

@ -148,6 +148,7 @@ puts $launchpad_config_fd {<config>
</launcher>
<launcher name="nitlog" ram_quota="1M" />
<launcher name="liquid_fb" ram_quota="7M" />
<config resize_handle="on" />
<launcher name="nitpicker" ram_quota="1M" />
</config>}
close $launchpad_config_fd

View File

@ -19,6 +19,7 @@
#include "menubar.h"
template <typename PT>
class Chunky_menubar : public Texture<PT>,
public Session,
@ -69,9 +70,10 @@ class Chunky_menubar : public Texture<PT>,
** Menubar interface **
***********************/
void state(Mode const &mode, char const *session_label,
char const *view_title, Color session_color)
void state(Menubar_state const state)
{
*static_cast<Menubar_state *>(this) = state;
/* choose base color dependent on the Nitpicker state */
int r = (mode.kill()) ? 200 : (mode.xray()) ? session_color.r : (session_color.r + 100) >> 1;
int g = (mode.kill()) ? 70 : (mode.xray()) ? session_color.g : (session_color.g + 100) >> 1;
@ -94,9 +96,11 @@ class Chunky_menubar : public Texture<PT>,
Color(r / 4, g / 4, b / 4));
/* draw label */
draw_label(_canvas, center(label_size(session_label, view_title)),
session_label, WHITE, view_title, session_color);
draw_label(_canvas, center(label_size(session_label.string(), view_title.string())),
session_label.string(), WHITE, view_title.string(), session_color);
}
using Menubar::state;
};
#endif

View File

@ -63,7 +63,7 @@ static Input::Event merge_motion_events(Input::Event const *ev, unsigned n)
static void import_input_events(Input::Event *ev_buf, unsigned num_ev,
User_state &user_state)
User_state &user_state, Canvas_base &canvas)
{
/*
* Take events from input event buffer, merge consecutive motion
@ -91,7 +91,7 @@ static void import_input_events(Input::Event *ev_buf, unsigned num_ev,
continue;
/* pass event to user state */
user_state.handle_event(curr);
user_state.handle_event(curr, canvas);
}
}

View File

@ -65,6 +65,7 @@ using Genode::Signal_transmitter;
using Genode::Signal_context_capability;
using Genode::Signal_rpc_member;
using Genode::Attached_ram_dataspace;
using Genode::Attached_dataspace;
/***************
@ -166,6 +167,12 @@ struct Buffer_provider
};
struct Canvas_accessor
{
virtual Canvas_base &canvas() = 0;
};
template <typename PT>
class Chunky_dataspace_texture : public Buffer,
public Texture<PT>
@ -301,11 +308,14 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
::Session &_session;
Flush_merger &_flush_merger;
Framebuffer::Session &_framebuffer;
Canvas_accessor &_canvas_accessor;
Buffer_provider &_buffer_provider;
Signal_context_capability _mode_sigh;
Framebuffer::Mode _mode;
bool _alpha = false;
Canvas_base &_canvas() { return _canvas_accessor.canvas(); }
public:
/**
@ -315,16 +325,17 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
::Session &session,
Flush_merger &flush_merger,
Framebuffer::Session &framebuffer,
Canvas_accessor &canvas_accessor,
Buffer_provider &buffer_provider)
:
_view_stack(view_stack),
_session(session),
_flush_merger(flush_merger),
_framebuffer(framebuffer),
_canvas_accessor(canvas_accessor),
_buffer_provider(buffer_provider)
{ }
/**
* Change virtual framebuffer mode
*
@ -372,7 +383,7 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
void refresh(int x, int y, int w, int h)
{
_view_stack.update_session_views(_session,
_view_stack.update_session_views(_canvas(), _session,
Rect(Point(x, y), Area(w, h)));
/* flush dirty pixels to physical frame buffer */
@ -393,9 +404,12 @@ class View_component : public Genode::List<View_component>::Element,
typedef Genode::Rpc_entrypoint Rpc_entrypoint;
View_stack &_view_stack;
::View _view;
Rpc_entrypoint &_ep;
View_stack &_view_stack;
::View _view;
Canvas_accessor &_canvas_accessor;
Rpc_entrypoint &_ep;
Canvas_base &_canvas() { return _canvas_accessor.canvas(); }
public:
@ -403,12 +417,15 @@ class View_component : public Genode::List<View_component>::Element,
* Constructor
*/
View_component(::Session &session, View_stack &view_stack,
Canvas_accessor &canvas_accessor,
Rpc_entrypoint &ep):
_view_stack(view_stack),
_view(session,
session.stay_top() ? ::View::STAY_TOP : ::View::NOT_STAY_TOP,
::View::NOT_TRANSPARENT, ::View::NOT_BACKGROUND, Rect()),
_ep(ep) { }
_canvas_accessor(canvas_accessor),
_ep(ep)
{ }
::View &view() { return _view; }
@ -423,8 +440,9 @@ class View_component : public Genode::List<View_component>::Element,
/* transpose y position by vertical session offset */
y += _view.session().v_offset();
_view_stack.viewport(_view, Rect(Point(x, y), Area(w, h)),
Point(buf_x, buf_y), redraw);
_view_stack.viewport(_canvas(), _view,
Rect(Point(x, y), Area(w, h)),
Point(buf_x, buf_y), redraw);
return 0;
}
@ -434,13 +452,13 @@ class View_component : public Genode::List<View_component>::Element,
::View *neighbor_view = nvc ? &nvc->view() : 0;
_view_stack.stack(_view, neighbor_view, behind, redraw);
_view_stack.stack(_canvas(), _view, neighbor_view, behind, redraw);
return 0;
}
int title(Title const &title)
{
_view_stack.title(_view, title.string());
_view_stack.title(_canvas(), _view, title.string());
return 0;
}
};
@ -463,6 +481,8 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
/* Framebuffer_session_component */
Framebuffer::Session_component _framebuffer_session_component;
Canvas_accessor &_canvas_accessor;
/* Input_session_component */
Input::Session_component _input_session_component;
@ -505,6 +525,8 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
_buffer_size = 0;
}
Canvas_base &_canvas() { return _canvas_accessor.canvas(); }
public:
/**
@ -515,6 +537,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
Rpc_entrypoint &ep,
Flush_merger &flush_merger,
Framebuffer::Session &framebuffer,
Canvas_accessor &canvas_accessor,
int v_offset,
bool provides_default_bg,
bool stay_top,
@ -525,7 +548,8 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
_buffer_alloc(&buffer_alloc, ram_quota),
_framebuffer(framebuffer),
_framebuffer_session_component(view_stack, *this, flush_merger,
framebuffer, *this),
framebuffer, canvas_accessor, *this),
_canvas_accessor(canvas_accessor),
_ep(ep), _view_stack(view_stack),
_framebuffer_session_cap(_ep.manage(&_framebuffer_session_component)),
_input_session_cap(_ep.manage(&_input_session_component)),
@ -588,7 +612,8 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
* Use a heap partition!
*/
View_component *view = new (env()->heap())
View_component(*this, _view_stack, _ep);
View_component(*this, _view_stack,
_canvas_accessor, _ep);
_view_list.insert(view);
return _ep.manage(view);
@ -599,7 +624,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object<Session>,
View_component *vc = dynamic_cast<View_component *>(_ep.lookup_and_lock(view_cap));
if (!vc) return;
_view_stack.remove_view(vc->view());
_view_stack.remove_view(_canvas(), vc->view());
_ep.dissolve(vc);
_view_list.remove(vc);
destroy(env()->heap(), vc);
@ -690,6 +715,7 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
View_stack &_view_stack;
Flush_merger &_flush_merger;
Framebuffer::Session &_framebuffer;
Canvas_accessor &_canvas_accessor;
int _default_v_offset;
protected:
@ -718,8 +744,8 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
Session_component *session = new (md_alloc())
Session_component(Session_label(args), _view_stack, *ep(),
_flush_merger, _framebuffer, v_offset,
provides_default_bg, stay_top,
_flush_merger, _framebuffer, _canvas_accessor,
v_offset, provides_default_bg, stay_top,
*md_alloc(), unused_quota);
session->apply_session_color();
@ -751,12 +777,14 @@ class Nitpicker::Root : public Genode::Root_component<Session_component>
Root(Session_list &session_list, Global_keys &global_keys,
Rpc_entrypoint &session_ep, View_stack &view_stack,
Allocator &md_alloc, Flush_merger &flush_merger,
Framebuffer::Session &framebuffer, int default_v_offset)
Framebuffer::Session &framebuffer, Canvas_accessor &canvas_accessor,
int default_v_offset)
:
Root_component<Session_component>(&session_ep, &md_alloc),
_session_list(session_list), _global_keys(global_keys),
_view_stack(view_stack), _flush_merger(flush_merger),
_framebuffer(framebuffer), _default_v_offset(default_v_offset)
_framebuffer(framebuffer), _canvas_accessor(canvas_accessor),
_default_v_offset(default_v_offset)
{ }
};
@ -774,27 +802,65 @@ struct Nitpicker::Main
Input::Event * const ev_buf =
env()->rm_session()->attach(input.dataspace());
/*
* Initialize framebuffer
*/
Framebuffer::Mode const mode = framebuffer.mode();
Dataspace_capability fb_ds_cap = framebuffer.dataspace();
typedef Pixel_rgb565 PT; /* physical pixel type */
void *fb_base = env()->rm_session()->attach(fb_ds_cap);
Screen<PT> screen = { (PT *)fb_base, Area(mode.width(), mode.height()) };
/*
* Menu bar
* Initialize framebuffer and menu bar
*
* The framebuffer and menubar are encapsulated in a volatile object to
* allow their reconstruction at runtime as a response to resolution
* changes.
*/
enum { MENUBAR_HEIGHT = 16 };
struct Framebuffer_screen
{
Framebuffer::Session &framebuffer;
PT *menubar_pixels = (PT *)env()->heap()->alloc(sizeof(PT)*mode.width()*16);
Framebuffer::Mode const mode = framebuffer.mode();
Chunky_menubar<PT> menubar = { menubar_pixels, Area(mode.width(), MENUBAR_HEIGHT) };
Attached_dataspace fb_ds = { framebuffer.dataspace() };
Screen<PT> screen = { fb_ds.local_addr<PT>(), Area(mode.width(), mode.height()) };
enum { MENUBAR_HEIGHT = 16 };
/**
* Size of menubar pixel buffer in bytes
*/
size_t const menubar_size = sizeof(PT)*mode.width()*MENUBAR_HEIGHT;
PT *menubar_pixels =
(PT *)env()->heap()->alloc(menubar_size);
Chunky_menubar<PT> menubar =
{ menubar_pixels, Area(mode.width(), MENUBAR_HEIGHT) };
/**
* Constructor
*/
Framebuffer_screen(Framebuffer::Session &fb) : framebuffer(fb) { }
/**
* Destructor
*/
~Framebuffer_screen() { env()->heap()->free(menubar_pixels, menubar_size); }
};
Genode::Volatile_object<Framebuffer_screen> fb_screen = { framebuffer };
struct Canvas_accessor : ::Canvas_accessor
{
Genode::Volatile_object<Framebuffer_screen> &fb_screen;
Canvas_accessor(Genode::Volatile_object<Framebuffer_screen> &fb_screen)
: fb_screen(fb_screen) { }
Canvas_base &canvas() override { return fb_screen->screen; }
} canvas_accessor = { fb_screen };
void handle_fb_mode(unsigned);
Signal_rpc_member<Main> fb_mode_dispatcher = { ep, *this, &Main::handle_fb_mode };
/*
* User-input policy
@ -803,7 +869,7 @@ struct Nitpicker::Main
Session_list session_list;
User_state user_state = { global_keys, screen, menubar };
User_state user_state = { global_keys, fb_screen->screen.size(), fb_screen->menubar };
/*
* Create view stack with default elements
@ -812,7 +878,7 @@ struct Nitpicker::Main
Mouse_cursor<PT const> mouse_cursor { (PT const *)&big_mouse.pixels[0][0],
mouse_size, user_state };
Background background = { screen.size() };
Background background = { Area(99999, 99999) };
/*
* Initialize Nitpicker root interface
@ -820,8 +886,9 @@ struct Nitpicker::Main
Genode::Sliced_heap sliced_heap = { env()->ram_session(), env()->rm_session() };
Root<PT> np_root = { session_list, global_keys, ep.rpc_ep(),
user_state, sliced_heap, screen,
framebuffer, MENUBAR_HEIGHT };
user_state, sliced_heap, fb_screen->screen,
framebuffer, canvas_accessor,
Framebuffer_screen::MENUBAR_HEIGHT };
Genode::Reporter pointer_reporter = { "pointer" };
@ -850,12 +917,12 @@ struct Nitpicker::Main
Main(Server::Entrypoint &ep) : ep(ep)
{
menubar.state(user_state, "", "", BLACK);
fb_screen->menubar.state(Menubar_state(user_state, "", "", BLACK));
user_state.default_background(background);
user_state.stack(mouse_cursor);
user_state.stack(menubar);
user_state.stack(background);
user_state.stack(canvas_accessor.canvas(), mouse_cursor);
user_state.stack(canvas_accessor.canvas(), fb_screen->menubar);
user_state.stack(canvas_accessor.canvas(), background);
config()->sigh(config_dispatcher);
Signal_transmitter(config_dispatcher).submit();
@ -863,6 +930,8 @@ struct Nitpicker::Main
timer.sigh(input_dispatcher);
timer.trigger_periodic(10*1000);
framebuffer.mode_sigh(fb_mode_dispatcher);
env()->parent()->announce(ep.manage(np_root));
}
};
@ -884,7 +953,8 @@ void Nitpicker::Main::handle_input(unsigned)
/* handle batch of pending events */
if (input.is_pending())
import_input_events(ev_buf, input.flush(), user_state);
import_input_events(ev_buf, input.flush(), user_state,
canvas_accessor.canvas());
Point const new_mouse_pos = user_state.mouse_pos();
@ -898,18 +968,18 @@ void Nitpicker::Main::handle_input(unsigned)
/* update mouse cursor */
if (old_mouse_pos != new_mouse_pos)
user_state.viewport(mouse_cursor,
user_state.viewport(canvas_accessor.canvas(), mouse_cursor,
Rect(new_mouse_pos, mouse_size),
Point(), true);
/* flush dirty pixels to physical frame buffer */
if (screen.defer == false) {
Rect const r = screen.to_be_flushed();
if (fb_screen->screen.defer == false) {
Rect const r = fb_screen->screen.to_be_flushed();
if (r.valid())
framebuffer.refresh(r.x1(), r.y1(), r.w(), r.h());
screen.reset();
fb_screen->screen.reset();
}
screen.defer = false;
fb_screen->screen.defer = false;
/*
* In kill mode, we do not leave the dispatch function in order to
@ -950,7 +1020,32 @@ void Nitpicker::Main::handle_config(unsigned)
s->apply_session_color();
/* redraw */
user_state.update_all_views();
user_state.update_all_views(canvas_accessor.canvas());
}
void Nitpicker::Main::handle_fb_mode(unsigned)
{
/* save state of menu bar */
Menubar_state menubar_state = fb_screen->menubar.state();
/* remove old version of menu bar from view stack */
user_state.remove_view(canvas_accessor.canvas(), fb_screen->menubar, false);
/* reconstruct framebuffer screen and menu bar */
fb_screen.construct(framebuffer);
/* let the view stack use the new size */
user_state.size(Area(fb_screen->mode.width(), fb_screen->mode.height()));
/* load original state into new menu bar */
fb_screen->menubar.state(menubar_state);
/* re-insert menu bar behind mouse cursor */
user_state.stack(canvas_accessor.canvas(), fb_screen->menubar, &mouse_cursor);
/* redraw */
user_state.update_all_views(canvas_accessor.canvas());
}

View File

@ -18,16 +18,34 @@
#include "draw_label.h"
#include "mode.h"
struct Menubar_state
{
Genode::String<128> session_label;
Genode::String<128> view_title;
Mode mode;
Color session_color;
struct Menubar
Menubar_state(Mode mode, char const *session_label,
char const *view_title, Color session_color)
:
session_label(session_label), view_title(view_title),
mode(mode), session_color(session_color)
{ }
Menubar_state() : session_color(BLACK) { }
};
struct Menubar : Menubar_state
{
virtual ~Menubar() { }
/**
* Set state that is displayed in the trusted menubar
*/
virtual void state(Mode const &mode, char const *session_label,
char const *view_title, Genode::Color session_color) = 0;
virtual void state(Menubar_state) = 0;
Menubar_state state() const { return *this; }
};
#endif

View File

@ -69,7 +69,7 @@ class Mouse_cursor : public Texture<PT>,
Clip_guard clip_guard(canvas, *this);
/* draw area behind the mouse cursor */
_view_stack.draw_rec(view_stack_next(), 0, 0, *this);
_view_stack.draw_rec(canvas, view_stack_next(), 0, 0, *this);
/* draw mouse cursor */
canvas.draw_texture(p1(), *this, Texture_painter::MASKED, BLACK, true);

View File

@ -35,15 +35,15 @@ static inline bool _mouse_button(Keycode keycode) {
** User state interface **
**************************/
User_state::User_state(Global_keys &global_keys, Canvas_base &canvas, Menubar &menubar)
User_state::User_state(Global_keys &global_keys, Area view_stack_size, Menubar &menubar)
:
View_stack(canvas, *this), _global_keys(global_keys), _key_cnt(0),
View_stack(view_stack_size, *this), _global_keys(global_keys), _key_cnt(0),
_menubar(menubar), _pointed_view(0), _input_receiver(0),
_global_key_sequence(false)
{ }
void User_state::handle_event(Input::Event ev)
void User_state::handle_event(Input::Event ev, Canvas_base &canvas)
{
Input::Keycode const keycode = ev.keycode();
Input::Event::Type const type = ev.type();
@ -100,29 +100,32 @@ void User_state::handle_event(Input::Event ev)
*/
struct Update_all_guard
{
User_state &user_state;
bool enabled;
char const *menu_title;
User_state &user_state;
Canvas_base &canvas;
bool enabled;
char const *menu_title;
Update_all_guard(User_state &user_state)
: user_state(user_state), enabled(false), menu_title("") { }
Update_all_guard(User_state &user_state, Canvas_base &canvas)
: user_state(user_state), canvas(canvas), enabled(false), menu_title("") { }
~Update_all_guard()
{
if (!enabled)
return;
if (user_state._input_receiver)
user_state._menubar.state(user_state,
user_state._input_receiver->label().string(),
menu_title,
user_state._input_receiver->color());
else
user_state._menubar.state(user_state, "", "", BLACK);
Menubar_state state(user_state, "", "", BLACK);
user_state.update_all_views();
if (user_state._input_receiver)
state = Menubar_state(user_state,
user_state._input_receiver->label().string(),
menu_title,
user_state._input_receiver->color());
user_state._menubar.state(state);
user_state.update_all_views(canvas);
}
} update_all_guard(*this);
} update_all_guard(*this, canvas);
/*
* Handle start of a key sequence
@ -135,7 +138,7 @@ void User_state::handle_event(Input::Event ev)
*/
if (kill() && keycode == Input::BTN_LEFT) {
if (pointed_view)
lock_out_session(pointed_view->session());
lock_out_session(canvas, pointed_view->session());
/* leave kill mode */
update_all_guard.enabled = true;
@ -263,12 +266,12 @@ void User_state::handle_event(Input::Event ev)
** Mode interface **
********************/
void User_state::forget(View const &view)
void User_state::forget(Canvas_base &canvas, View const &view)
{
if (focused_view() == &view) {
Mode::forget(view);
_menubar.state(*this, "", "", BLACK);
update_all_views();
_menubar.state(Menubar_state(*this, "", "", BLACK));
update_all_views(canvas);
}
if (_input_receiver && view.belongs_to(*_input_receiver))
_input_receiver = 0;

View File

@ -71,7 +71,7 @@ class User_state : public Mode, public View_stack
/**
* Constructor
*/
User_state(Global_keys &, Canvas_base &, Menubar &);
User_state(Global_keys &, Area view_stack_size, Menubar &);
/**
* Handle input event
@ -79,7 +79,7 @@ class User_state : public Mode, public View_stack
* This function controls the Nitpicker mode and the
* user state variables.
*/
void handle_event(Input::Event ev);
void handle_event(Input::Event ev, Canvas_base &);
/**
* Accessors
@ -89,7 +89,7 @@ class User_state : public Mode, public View_stack
/**
* Mode interface
*/
void forget(View const &);
void forget(Canvas_base &, View const &);
};
#endif

View File

@ -148,7 +148,7 @@ void View_stack::_optimize_label_rec(View const *cv, View const *lv, Rect rect,
}
void View_stack::_place_labels(Rect rect)
void View_stack::_place_labels(Canvas_base &canvas, Rect rect)
{
/* do not calculate label positions in flat mode */
if (_mode.flat()) return;
@ -163,7 +163,7 @@ void View_stack::_place_labels(Rect rect)
Rect old = view->label_rect(), best;
/* calculate best visible label position */
Rect rect = Rect::intersect(Rect(Point(), _canvas.size()), *view);
Rect rect = Rect::intersect(Rect(Point(), canvas.size()), *view);
if (start) _optimize_label_rec(start, view, rect, &best);
/*
@ -177,13 +177,13 @@ void View_stack::_place_labels(Rect rect)
view->label_pos(Point(x, best.y1()));
/* refresh old and new label positions */
refresh_view(*view, view, old);
refresh_view(*view, view, view->label_rect());
refresh_view(canvas, *view, view, old);
refresh_view(canvas, *view, view, view->label_rect());
}
}
void View_stack::draw_rec(View const *view, View const *dst_view,
void View_stack::draw_rec(Canvas_base &canvas, View const *view, View const *dst_view,
Session const *exclude, Rect rect) const
{
Rect clipped;
@ -201,40 +201,42 @@ void View_stack::draw_rec(View const *view, View const *dst_view,
View const *next = _next_view(view);
/* draw areas at the top/left of the current view */
if (next && top.valid()) draw_rec(next, dst_view, exclude, top);
if (next && left.valid()) draw_rec(next, dst_view, exclude, left);
if (next && top.valid()) draw_rec(canvas, next, dst_view, exclude, top);
if (next && left.valid()) draw_rec(canvas, next, dst_view, exclude, left);
/* draw current view */
if (!dst_view || (dst_view == view) || view->transparent()) {
Clip_guard clip_guard(_canvas, clipped);
Clip_guard clip_guard(canvas, clipped);
/* draw background if view is transparent */
if (view->uses_alpha())
draw_rec(_next_view(view), 0, 0, clipped);
draw_rec(canvas, _next_view(view), 0, 0, clipped);
view->frame(_canvas, _mode);
view->frame(canvas, _mode);
if (!exclude || !view->belongs_to(*exclude))
view->draw(_canvas, _mode);
view->draw(canvas, _mode);
}
/* draw areas at the bottom/right of the current view */
if (next && right.valid()) draw_rec(next, dst_view, exclude, right);
if (next && bottom.valid()) draw_rec(next, dst_view, exclude, bottom);
if (next && right.valid()) draw_rec(canvas, next, dst_view, exclude, right);
if (next && bottom.valid()) draw_rec(canvas, next, dst_view, exclude, bottom);
}
void View_stack::refresh_view(View const &view, View const *dst_view, Rect rect)
void View_stack::refresh_view(Canvas_base &canvas, View const &view,
View const *dst_view, Rect rect)
{
/* clip argument agains view outline */
rect = Rect::intersect(rect, _outline(view));
draw_rec(_first_view(), dst_view, 0, rect);
draw_rec(canvas, _first_view(), dst_view, 0, rect);
}
void View_stack::viewport(View &view, Rect pos, Point buffer_off, bool do_redraw)
void View_stack::viewport(Canvas_base &canvas, View &view, Rect pos,
Point buffer_off, bool do_redraw)
{
Rect old = _outline(view);
@ -245,33 +247,34 @@ void View_stack::viewport(View &view, Rect pos, Point buffer_off, bool do_redraw
/* update labels (except when moving the mouse cursor) */
if (&view != _first_view())
_place_labels(compound);
_place_labels(canvas, compound);
if (!_mode.flat())
do_redraw = true;
/* update area on screen */
draw_rec(_first_view(), 0, do_redraw ? 0 : &view.session(), compound);
draw_rec(canvas, _first_view(), 0, do_redraw ? 0 : &view.session(), compound);
}
void View_stack::stack(View const &view, View const *neighbor, bool behind, bool do_redraw)
void View_stack::stack(Canvas_base &canvas, View const &view,
View const *neighbor, bool behind, bool do_redraw)
{
_views.remove(&view);
_views.insert(&view, _target_stack_position(neighbor, behind));
_place_labels(view);
_place_labels(canvas, view);
/* refresh affected screen area */
refresh_view(view, 0, _outline(view));
refresh_view(canvas, view, 0, _outline(view));
}
void View_stack::title(View &view, const char *title)
void View_stack::title(Canvas_base &canvas, View &view, const char *title)
{
view.title(title);
_place_labels(view);
refresh_view(view, 0, _outline(view));
_place_labels(canvas, view);
refresh_view(canvas, view, 0, _outline(view));
}
@ -288,7 +291,7 @@ View *View_stack::find_view(Point p)
}
void View_stack::remove_view(View const &view)
void View_stack::remove_view(Canvas_base &canvas, View const &view, bool redraw)
{
/* remember geometry of view to remove */
Rect rect = _outline(view);
@ -308,5 +311,6 @@ void View_stack::remove_view(View const &view)
_mode.forget(view);
/* redraw area where the view was visible */
draw_rec(_first_view(), 0, 0, rect);
if (redraw)
draw_rec(canvas, _first_view(), 0, 0, rect);
}

View File

@ -23,7 +23,7 @@ class View_stack
{
private:
Canvas_base &_canvas;
Area _size;
Mode &_mode;
Genode::List<View_stack_elem> _views;
View *_default_background;
@ -55,7 +55,7 @@ class View_stack
/**
* Position labels that are affected by specified area
*/
void _place_labels(Rect);
void _place_labels(Canvas_base &, Rect);
/**
* Return view following the specified view in the view stack
@ -71,13 +71,15 @@ class View_stack
/**
* Constructor
*/
View_stack(Canvas_base &canvas, Mode &mode) :
_canvas(canvas), _mode(mode), _default_background(0) { }
View_stack(Area size, Mode &mode) :
_size(size), _mode(mode), _default_background(0) { }
/**
* Return size
*/
Area size() { return _canvas.size(); }
Area size() const { return _size; }
void size(Area size) { _size = size; }
/**
* Draw views in specified area (recursivly)
@ -87,15 +89,15 @@ class View_stack
* if all views should be drawn
* \param exclude do not draw views of this session
*/
void draw_rec(View const *view, View const *dst_view, Session const *exclude, Rect) const;
void draw_rec(Canvas_base &, View const *view, View const *dst_view, Session const *exclude, Rect) const;
/**
* Draw whole view stack
*/
void update_all_views()
void update_all_views(Canvas_base &canvas)
{
_place_labels(Rect(Point(), _canvas.size()));
draw_rec(_first_view(), 0, 0, Rect(Point(), _canvas.size()));
_place_labels(canvas, Rect(Point(), _size));
draw_rec(canvas, _first_view(), 0, 0, Rect(Point(), _size));
}
/**
@ -110,7 +112,7 @@ class View_stack
* a tailored 'draw_rec_session' function would overcome
* this problem.
*/
void update_session_views(Session const &session, Rect rect)
void update_session_views(Canvas_base &canvas, Session const &session, Rect rect)
{
for (View const *view = _first_view(); view; view = view->view_stack_next()) {
@ -124,7 +126,7 @@ class View_stack
Point offset = view->p1() + view->buffer_off();
Rect r = Rect::intersect(Rect(rect.p1() + offset,
rect.p2() + offset), *view);
refresh_view(*view, view, r);
refresh_view(canvas, *view, view, r);
}
}
@ -136,7 +138,7 @@ class View_stack
* refreshed or 'view' if the refresh should be limited to
* the specified view.
*/
void refresh_view(View const &view, View const *dst, Rect);
void refresh_view(Canvas_base &, View const &view, View const *dst, Rect);
/**
* Define position and viewport
@ -145,7 +147,7 @@ class View_stack
* \param buffer_off view offset of displayed buffer
* \param do_redraw perform screen update immediately
*/
void viewport(View &view, Rect pos, Point buffer_off, bool do_redraw);
void viewport(Canvas_base &, View &view, Rect pos, Point buffer_off, bool do_redraw);
/**
* Insert view at specified position in view stack
@ -158,13 +160,13 @@ class View_stack
* bottom of the view stack, specify neighbor = 0 and
* behind = false.
*/
void stack(View const &view, View const *neighbor = 0,
void stack(Canvas_base &, View const &view, View const *neighbor = 0,
bool behind = true, bool do_redraw = true);
/**
* Set view title
*/
void title(View &view, char const *title);
void title(Canvas_base &, View &view, char const *title);
/**
* Find view at specified position
@ -174,7 +176,7 @@ class View_stack
/**
* Remove view from view stack
*/
void remove_view(View const &);
void remove_view(Canvas_base &, View const &, bool redraw = true);
/**
* Define default background
@ -192,11 +194,11 @@ class View_stack
* Rather than removing the views from the view stack, this function moves
* the session views out of the visible screen area.
*/
void lock_out_session(Session const &session)
void lock_out_session(Canvas_base &canvas, Session const &session)
{
View const *view = _first_view(), *next_view = view->view_stack_next();
while (view) {
if (view->belongs_to(session)) remove_view(*view);
if (view->belongs_to(session)) remove_view(canvas, *view);
view = next_view;
next_view = view ? view->view_stack_next() : 0;
}