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