mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
parent
0056167157
commit
14718401ea
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user