diff --git a/os/run/demo.run b/os/run/demo.run
index 62145ee974..20784afe7e 100644
--- a/os/run/demo.run
+++ b/os/run/demo.run
@@ -148,6 +148,7 @@ puts $launchpad_config_fd {
+
}
close $launchpad_config_fd
diff --git a/os/src/server/nitpicker/chunky_menubar.h b/os/src/server/nitpicker/chunky_menubar.h
index 07dc9b1516..c8515e30a3 100644
--- a/os/src/server/nitpicker/chunky_menubar.h
+++ b/os/src/server/nitpicker/chunky_menubar.h
@@ -19,6 +19,7 @@
#include "menubar.h"
+
template
class Chunky_menubar : public Texture,
public Session,
@@ -69,9 +70,10 @@ class Chunky_menubar : public Texture,
** 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(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,
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
diff --git a/os/src/server/nitpicker/input.h b/os/src/server/nitpicker/input.h
index 50a396ebdf..4cc3c9f973 100644
--- a/os/src/server/nitpicker/input.h
+++ b/os/src/server/nitpicker/input.h
@@ -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);
}
}
diff --git a/os/src/server/nitpicker/main.cc b/os/src/server/nitpicker/main.cc
index 29c8e58f58..d581ffa78a 100644
--- a/os/src/server/nitpicker/main.cc
+++ b/os/src/server/nitpicker/main.cc
@@ -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
class Chunky_dataspace_texture : public Buffer,
public Texture
@@ -301,11 +308,14 @@ class Framebuffer::Session_component : public Genode::Rpc_object
::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,
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
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::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::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::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::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,
/* 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,
_buffer_size = 0;
}
+ Canvas_base &_canvas() { return _canvas_accessor.canvas(); }
+
public:
/**
@@ -515,6 +537,7 @@ class Nitpicker::Session_component : public Genode::Rpc_object,
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,
_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,
* 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,
View_component *vc = dynamic_cast(_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
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 = 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
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_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 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 menubar = { menubar_pixels, Area(mode.width(), MENUBAR_HEIGHT) };
+ Attached_dataspace fb_ds = { framebuffer.dataspace() };
+
+ Screen screen = { fb_ds.local_addr(), 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 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 fb_screen = { framebuffer };
+
+ struct Canvas_accessor : ::Canvas_accessor
+ {
+ Genode::Volatile_object &fb_screen;
+
+ Canvas_accessor(Genode::Volatile_object &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 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 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 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());
}
diff --git a/os/src/server/nitpicker/menubar.h b/os/src/server/nitpicker/menubar.h
index 0417cd1477..d60a4bb295 100644
--- a/os/src/server/nitpicker/menubar.h
+++ b/os/src/server/nitpicker/menubar.h
@@ -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
diff --git a/os/src/server/nitpicker/mouse_cursor.h b/os/src/server/nitpicker/mouse_cursor.h
index 5a2cba4152..fcf96774e5 100644
--- a/os/src/server/nitpicker/mouse_cursor.h
+++ b/os/src/server/nitpicker/mouse_cursor.h
@@ -69,7 +69,7 @@ class Mouse_cursor : public Texture,
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);
diff --git a/os/src/server/nitpicker/user_state.cc b/os/src/server/nitpicker/user_state.cc
index 70a65f0a56..6e6c305664 100644
--- a/os/src/server/nitpicker/user_state.cc
+++ b/os/src/server/nitpicker/user_state.cc
@@ -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;
diff --git a/os/src/server/nitpicker/user_state.h b/os/src/server/nitpicker/user_state.h
index ff75aa74b6..4d9d38a323 100644
--- a/os/src/server/nitpicker/user_state.h
+++ b/os/src/server/nitpicker/user_state.h
@@ -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
diff --git a/os/src/server/nitpicker/view_stack.cc b/os/src/server/nitpicker/view_stack.cc
index f1da6c409d..0c1db59684 100644
--- a/os/src/server/nitpicker/view_stack.cc
+++ b/os/src/server/nitpicker/view_stack.cc
@@ -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);
}
diff --git a/os/src/server/nitpicker/view_stack.h b/os/src/server/nitpicker/view_stack.h
index 56bf3c14f1..cc1450f7f9 100644
--- a/os/src/server/nitpicker/view_stack.h
+++ b/os/src/server/nitpicker/view_stack.h
@@ -23,7 +23,7 @@ class View_stack
{
private:
- Canvas_base &_canvas;
+ Area _size;
Mode &_mode;
Genode::List _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;
}