mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-12 20:28:20 +00:00
Adapt high-level components to new parent API
This patch adjusts the various users of the 'Child' API to the changes on the account of the new non-blocking parent interface. It also removes the use of the no-longer-available 'Connection::KEEP_OPEN' feature. With the adjustment, we took the opportunity to redesign several components to fit the non-blocking execution model much better, in particular the demo applications. Issue #2120
This commit is contained in:
committed by
Christian Helmuth
parent
8bafb9d41b
commit
b44f0554bd
@ -32,18 +32,18 @@ class Kill_event_handler : public Scout::Event_handler
|
||||
{
|
||||
private:
|
||||
|
||||
Launchpad *_launchpad;
|
||||
Launchpad_child *_launchpad_child;
|
||||
Launchpad &_launchpad;
|
||||
Launchpad_child &_launchpad_child;
|
||||
|
||||
public:
|
||||
|
||||
Kill_event_handler(Launchpad *launchpad, Launchpad_child *launchpad_child):
|
||||
Kill_event_handler(Launchpad &launchpad, Launchpad_child &launchpad_child):
|
||||
_launchpad(launchpad), _launchpad_child(launchpad_child) { }
|
||||
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Scout::Event &ev)
|
||||
void handle_event(Scout::Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
|
||||
@ -53,7 +53,7 @@ class Kill_event_handler : public Scout::Event_handler
|
||||
if (ev.type == Event::RELEASE) key_cnt--;
|
||||
|
||||
if (ev.type == Event::RELEASE && key_cnt == 0)
|
||||
_launchpad->exit_child(_launchpad_child);
|
||||
_launchpad.exit_child(_launchpad_child);
|
||||
}
|
||||
};
|
||||
|
||||
@ -73,7 +73,7 @@ class Child_entry : public Scout::Parent_element,
|
||||
Scout::Block _block;
|
||||
Kbyte_loadbar<PT> _loadbar;
|
||||
|
||||
char _name[_NAME_LEN];
|
||||
Launchpad_child::Name const _name;
|
||||
|
||||
Scout::Fade_icon<PT, _IW, _IH> _kill_icon;
|
||||
Scout::Fade_icon<PT, _IW, _IH> _fold_icon;
|
||||
@ -85,14 +85,14 @@ class Child_entry : public Scout::Parent_element,
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Child_entry(const char *name, int quota_kb, int max_quota_kb,
|
||||
Launchpad *launchpad, Launchpad_child *launchpad_child)
|
||||
Child_entry(Launchpad_child::Name const &name, int quota_kb, int max_quota_kb,
|
||||
Launchpad &launchpad, Launchpad_child &launchpad_child)
|
||||
:
|
||||
_block(Scout::Block::RIGHT), _loadbar(0, &Scout::label_font),
|
||||
_name(name),
|
||||
_kill_event_handler(launchpad, launchpad_child)
|
||||
{
|
||||
Genode::strncpy(_name, name, sizeof(_name));
|
||||
_block.append_plaintext(_name, &Scout::plain_style);
|
||||
_block.append_plaintext(_name.string(), &Scout::plain_style);
|
||||
|
||||
_loadbar.max_value(max_quota_kb);
|
||||
_loadbar.value(quota_kb);
|
||||
@ -118,7 +118,7 @@ class Child_entry : public Scout::Parent_element,
|
||||
/**
|
||||
* Accessors
|
||||
*/
|
||||
const char *name() { return _name; }
|
||||
Launchpad_child::Name name() { return _name; }
|
||||
|
||||
|
||||
/******************************
|
||||
|
@ -22,6 +22,7 @@ class Launch_entry : public Scout::Parent_element, public Loadbar_listener
|
||||
{
|
||||
private:
|
||||
|
||||
Scout::Launcher::Name _prg_name;
|
||||
Scout::Block _block;
|
||||
Kbyte_loadbar<PT> _loadbar;
|
||||
Scout::Launcher_config _config;
|
||||
@ -37,15 +38,16 @@ class Launch_entry : public Scout::Parent_element, public Loadbar_listener
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Launch_entry(const char *prg_name, unsigned long initial_quota,
|
||||
Launch_entry(Scout::Launcher::Name const &prg_name, unsigned long initial_quota,
|
||||
unsigned long max_quota, Launchpad *launchpad,
|
||||
Genode::Dataspace_capability config_ds)
|
||||
:
|
||||
_prg_name(prg_name),
|
||||
_block(Scout::Block::RIGHT), _loadbar(this, &Scout::label_font),
|
||||
_config(config_ds),
|
||||
_launcher(prg_name, launchpad, initial_quota * 1024UL, &_config)
|
||||
{
|
||||
_block.append_launchertext(prg_name, &Scout::link_style, &_launcher);
|
||||
_block.append_launchertext(_prg_name.string(), &Scout::link_style, &_launcher);
|
||||
|
||||
_loadbar.max_value(max_quota);
|
||||
_loadbar.value(initial_quota);
|
||||
|
@ -35,11 +35,12 @@ extern unsigned char TITLEBAR_RGBA[];
|
||||
********************************/
|
||||
|
||||
template <typename PT>
|
||||
Launchpad_window<PT>::Launchpad_window(Graphics_backend &gfx_backend,
|
||||
Launchpad_window<PT>::Launchpad_window(Genode::Env &env,
|
||||
Graphics_backend &gfx_backend,
|
||||
Point position, Area size, Area max_size,
|
||||
unsigned long initial_quota)
|
||||
:
|
||||
Launchpad(initial_quota),
|
||||
Launchpad(env, initial_quota),
|
||||
Window(gfx_backend, position, size, max_size, false),
|
||||
_docview(0),
|
||||
_spacer(1, _TH),
|
||||
|
@ -14,6 +14,9 @@
|
||||
#ifndef _LAUNCHPAD_WINDOW_H_
|
||||
#define _LAUNCHPAD_WINDOW_H_
|
||||
|
||||
#include <base/env.h>
|
||||
#include <dataspace/capability.h>
|
||||
|
||||
#include <scout/platform.h>
|
||||
#include <scout/window.h>
|
||||
|
||||
@ -73,7 +76,8 @@ class Launchpad_window : public Scout::Scrollbar_listener,
|
||||
*
|
||||
* \param initial_quota maximum value of quota displays
|
||||
*/
|
||||
Launchpad_window(Scout::Graphics_backend &gfx_backend,
|
||||
Launchpad_window(Genode::Env &env,
|
||||
Scout::Graphics_backend &gfx_backend,
|
||||
Scout::Point position, Scout::Area size,
|
||||
Scout::Area max_size, unsigned long inital_quota);
|
||||
|
||||
@ -123,39 +127,40 @@ class Launchpad_window : public Scout::Scrollbar_listener,
|
||||
_status_entry.refresh();
|
||||
}
|
||||
|
||||
void add_launcher(const char *filename,
|
||||
void add_launcher(Launchpad_child::Name const &name,
|
||||
unsigned long default_quota,
|
||||
Genode::Dataspace_capability config_ds = Genode::Dataspace_capability())
|
||||
Genode::Dataspace_capability config_ds = Genode::Dataspace_capability()) override
|
||||
{
|
||||
Launch_entry<PT> *le;
|
||||
le = new Launch_entry<PT>(filename, default_quota / 1024,
|
||||
le = new Launch_entry<PT>(name, default_quota / 1024,
|
||||
initial_quota() / 1024,
|
||||
this, config_ds);
|
||||
_launch_section.append(le);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void add_child(const char *unique_name,
|
||||
void add_child(Launchpad_child::Name const &name,
|
||||
unsigned long quota,
|
||||
Launchpad_child *launchpad_child,
|
||||
Genode::Allocator *alloc)
|
||||
Launchpad_child &launchpad_child,
|
||||
Genode::Allocator &alloc) override
|
||||
{
|
||||
Child_entry<PT> *ce;
|
||||
ce = new (alloc) Child_entry<PT>(unique_name, quota / 1024,
|
||||
ce = new (alloc) Child_entry<PT>(name, quota / 1024,
|
||||
initial_quota() / 1024,
|
||||
this, launchpad_child);
|
||||
*this, launchpad_child);
|
||||
_child_entry_list.insert(ce);
|
||||
_kiddy_section.append(ce);
|
||||
format(_size);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void remove_child(const char *name, Genode::Allocator *alloc)
|
||||
void remove_child(Launchpad_child::Name const &name,
|
||||
Genode::Allocator &alloc) override
|
||||
{
|
||||
/* lookup child entry by its name */
|
||||
Child_entry<PT> *ce = _child_entry_list.first();
|
||||
for ( ; ce; ce = ce->Genode::List<Child_entry<PT> >::Element::next())
|
||||
if (Genode::strcmp(ce->name(), name) == 0)
|
||||
if (name == ce->name())
|
||||
break;
|
||||
|
||||
if (!ce) {
|
||||
|
@ -53,7 +53,7 @@ class Loadbar_event_handler : public Scout::Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Scout::Event &ev)
|
||||
void handle_event(Scout::Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
using Scout::Event;
|
||||
|
@ -11,6 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
|
||||
#include <scout/platform.h>
|
||||
#include <scout/tick.h>
|
||||
#include <scout/user_state.h>
|
||||
@ -85,15 +87,52 @@ static long read_int_attr_from_config(const char *attr, long default_value)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
struct Main : Scout::Event_handler
|
||||
{
|
||||
Scout::Platform &_pf;
|
||||
Scout::Window &_launchpad;
|
||||
Scout::User_state &_user_state;
|
||||
|
||||
unsigned long _old_time = _pf.timer_ticks();
|
||||
|
||||
Main(Scout::Platform &pf, Scout::Window &launchpad, Scout::User_state &user_state)
|
||||
: _pf(pf), _launchpad(launchpad), _user_state(user_state) { }
|
||||
|
||||
void handle_event(Scout::Event const &event) override
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
Event ev = event;
|
||||
|
||||
if (ev.type != Event::WHEEL)
|
||||
ev.mouse_position = ev.mouse_position - _user_state.view_position();
|
||||
|
||||
_user_state.handle_event(ev);
|
||||
|
||||
if (ev.type == Event::TIMER)
|
||||
Tick::handle(_pf.timer_ticks());
|
||||
|
||||
/* perform periodic redraw */
|
||||
unsigned long const curr_time = _pf.timer_ticks();
|
||||
if (!_pf.event_pending() && ((curr_time - _old_time > 20)
|
||||
|| (curr_time < _old_time))) {
|
||||
_old_time = curr_time;
|
||||
_launchpad.process_redraw();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
static Nitpicker::Connection nitpicker;
|
||||
static Platform pf(*nitpicker.input());
|
||||
static Nitpicker::Connection nitpicker(env);
|
||||
static Platform pf(env, *nitpicker.input());
|
||||
|
||||
long initial_x = read_int_attr_from_config("xpos", 550);
|
||||
long initial_y = read_int_attr_from_config("ypos", 150);
|
||||
@ -109,17 +148,13 @@ int main(int argc, char **argv)
|
||||
|
||||
/* create instance of launchpad window */
|
||||
static Launchpad_window<Pixel_rgb565>
|
||||
launchpad(
|
||||
graphics_backend, initial_position, initial_size, max_size,
|
||||
Genode::env()->ram_session()->avail()
|
||||
);
|
||||
launchpad(env, graphics_backend, initial_position, initial_size,
|
||||
max_size, env.ram().avail());
|
||||
|
||||
/* request config file from ROM service */
|
||||
try {
|
||||
launchpad.process_config();
|
||||
} catch (...) { }
|
||||
try { launchpad.process_config(); } catch (...) { }
|
||||
|
||||
Avail_quota_update avail_quota_update(&launchpad);
|
||||
static Avail_quota_update avail_quota_update(&launchpad);
|
||||
|
||||
/* create user state manager */
|
||||
static User_state user_state(&launchpad, &launchpad,
|
||||
@ -129,36 +164,6 @@ int main(int argc, char **argv)
|
||||
launchpad.format(initial_size);
|
||||
launchpad.ypos(0);
|
||||
|
||||
Genode::printf("--- entering main loop ---\n");
|
||||
|
||||
/* enter main loop */
|
||||
unsigned long curr_time, old_time;
|
||||
curr_time = old_time = pf.timer_ticks();
|
||||
for (;;) {
|
||||
Event ev = pf.get_event();
|
||||
|
||||
launchpad.gui_lock.lock();
|
||||
|
||||
if (ev.type != Event::WHEEL)
|
||||
ev.mouse_position = ev.mouse_position - user_state.view_position();
|
||||
|
||||
user_state.handle_event(ev);
|
||||
|
||||
if (ev.type == Event::TIMER)
|
||||
Tick::handle(pf.timer_ticks());
|
||||
|
||||
/* perform periodic redraw */
|
||||
curr_time = pf.timer_ticks();
|
||||
if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) {
|
||||
old_time = curr_time;
|
||||
launchpad.process_redraw();
|
||||
}
|
||||
|
||||
launchpad.gui_lock.unlock();
|
||||
|
||||
if (ev.type == Event::QUIT)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
static Main main(pf, launchpad, user_state);
|
||||
pf.event_handler(main);
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ class Iconbar_event_handler : public Scout::Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
|
||||
|
@ -426,7 +426,7 @@ void Verbatim::format_fixed_width(int w)
|
||||
** Link_token **
|
||||
****************/
|
||||
|
||||
void Link_token::handle(Event &e)
|
||||
void Link_token::handle_event(Event const &e)
|
||||
{
|
||||
if (e.type != Event::PRESS) return;
|
||||
|
||||
@ -444,7 +444,7 @@ void Link_token::handle(Event &e)
|
||||
** Launcher_link_token **
|
||||
*************************/
|
||||
|
||||
void Launcher_link_token::handle(Event &e)
|
||||
void Launcher_link_token::handle_event(Event const &e)
|
||||
{
|
||||
if (e.type != Event::PRESS) return;
|
||||
|
||||
|
@ -200,7 +200,7 @@ class Scout::Link_token : public Token, public Link, public Event_handler,
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &e);
|
||||
void handle_event(Event const &) override;
|
||||
|
||||
/**
|
||||
* Tick interface
|
||||
@ -221,9 +221,13 @@ class Launchpad;
|
||||
|
||||
class Scout::Launcher : public Anchor
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Genode::String<64> Name;
|
||||
|
||||
private:
|
||||
|
||||
const char *_prg_name; /* null-terminated name of the program */
|
||||
Name _prg_name;
|
||||
int _active;
|
||||
int _exec_once;
|
||||
Launchpad *_launchpad;
|
||||
@ -232,22 +236,24 @@ class Scout::Launcher : public Anchor
|
||||
|
||||
public:
|
||||
|
||||
static void init(Genode::Env &);
|
||||
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
Launcher(const char *prg_name, int exec_once = 0,
|
||||
Launcher(Name const &prg_name, int exec_once = 0,
|
||||
unsigned long quota = 0, Launcher_config *config = 0) :
|
||||
_prg_name(prg_name), _active(1),
|
||||
_exec_once(exec_once), _quota(quota), _config(config) { }
|
||||
|
||||
Launcher(const char *prg_name, Launchpad *launchpad,
|
||||
Launcher(Name const &prg_name, Launchpad *launchpad,
|
||||
unsigned long quota, Launcher_config *config = 0) :
|
||||
_prg_name(prg_name), _launchpad(launchpad), _quota(quota),
|
||||
_config(config) { }
|
||||
|
||||
int active() { return _active; }
|
||||
|
||||
const char *prg_name() { return _prg_name; }
|
||||
Name prg_name() { return _prg_name; }
|
||||
|
||||
void quota(unsigned long quota) { _quota = quota; }
|
||||
|
||||
@ -280,7 +286,7 @@ class Scout::Launcher_link_token : public Link_token
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &e);
|
||||
void handle_event(Event const &) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,9 +18,6 @@
|
||||
#include <base/snprintf.h>
|
||||
#include "elements.h"
|
||||
|
||||
static Launchpad launchpad(Genode::env()->ram_session()->quota());
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
using namespace Scout;
|
||||
|
||||
@ -94,10 +91,32 @@ Dataspace_capability Config_registry::config(char const *name)
|
||||
** Launcher interface **
|
||||
************************/
|
||||
|
||||
|
||||
static Launchpad *launchpad_ptr;
|
||||
|
||||
|
||||
static Launchpad &launchpad()
|
||||
{
|
||||
if (!launchpad_ptr) {
|
||||
class Missing_launchpad_init_call { };
|
||||
throw Missing_launchpad_init_call();
|
||||
}
|
||||
|
||||
return *launchpad_ptr;
|
||||
}
|
||||
|
||||
|
||||
void Launcher::init(Genode::Env &env)
|
||||
{
|
||||
static Launchpad launchpad(env, env.ram().avail());
|
||||
launchpad_ptr = &launchpad;
|
||||
}
|
||||
|
||||
|
||||
void Launcher::launch()
|
||||
{
|
||||
static Config_registry config_registry;
|
||||
|
||||
launchpad.start_child(prg_name(), quota(),
|
||||
config_registry.config(prg_name()));
|
||||
launchpad().start_child(prg_name(), quota(),
|
||||
config_registry.config(prg_name().string()));
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
|
||||
#include <scout/platform.h>
|
||||
#include <scout/tick.h>
|
||||
#include <scout/user_state.h>
|
||||
@ -45,20 +47,86 @@ extern unsigned char NAV_PREV_RGBA[];
|
||||
|
||||
static unsigned char *navicons_rgba[] = { NAV_NEXT_RGBA, NAV_PREV_RGBA };
|
||||
static Scout::Generic_icon **navicons[] = { &Scout::Navbar::next_icon,
|
||||
&Scout::Navbar::prev_icon };
|
||||
&Scout::Navbar::prev_icon };
|
||||
|
||||
extern int native_startup(int, char **);
|
||||
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
namespace Scout { struct Main; }
|
||||
|
||||
|
||||
struct Scout::Main : Scout::Event_handler
|
||||
{
|
||||
Scout::Platform &_pf;
|
||||
Scout::Window &_browser;
|
||||
Scout::User_state &_user_state;
|
||||
Scout::Element &_mcursor;
|
||||
|
||||
Scout::Point _mouse_position;
|
||||
|
||||
unsigned long _old_time = _pf.timer_ticks();
|
||||
|
||||
Main(Scout::Platform &pf, Scout::Window &browser,
|
||||
Scout::User_state &user_state, Scout::Element &mcursor)
|
||||
:
|
||||
_pf(pf), _browser(browser), _user_state(user_state), _mcursor(mcursor)
|
||||
{ }
|
||||
|
||||
void handle_event(Scout::Event const &event) override
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
Event ev = event;
|
||||
|
||||
if (event.type != Event::WHEEL) {
|
||||
|
||||
ev.mouse_position = ev.mouse_position - _user_state.view_position();
|
||||
|
||||
/* update mouse cursor */
|
||||
if (Config::mouse_cursor && (ev.mouse_position.x() != _mouse_position.x()
|
||||
|| ev.mouse_position.y() != _mouse_position.y())) {
|
||||
int x1 = min(ev.mouse_position.x(), _mouse_position.x());
|
||||
int y1 = min(ev.mouse_position.y(), _mouse_position.y());
|
||||
int x2 = max(ev.mouse_position.x() + _mcursor.size().w() - 1,
|
||||
_mouse_position.x() + _mcursor.size().w() - 1);
|
||||
int y2 = max(ev.mouse_position.y() + _mcursor.size().h() - 1,
|
||||
_mouse_position.y() + _mcursor.size().h() - 1);
|
||||
|
||||
_mcursor.geometry(Rect(ev.mouse_position, _mcursor.size()));
|
||||
_browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||
|
||||
_mouse_position = ev.mouse_position;
|
||||
}
|
||||
}
|
||||
|
||||
_user_state.handle_event(ev);
|
||||
|
||||
if (event.type == Event::TIMER)
|
||||
Tick::handle(_pf.timer_ticks());
|
||||
|
||||
/* perform periodic redraw */
|
||||
unsigned long curr_time = _pf.timer_ticks();
|
||||
if (!_pf.event_pending() && ((curr_time - _old_time > 20)
|
||||
|| (curr_time < _old_time))) {
|
||||
_old_time = curr_time;
|
||||
_browser.process_redraw();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
Launcher::init(env);
|
||||
|
||||
static Nitpicker::Connection nitpicker;
|
||||
static Platform pf(*nitpicker.input());
|
||||
static Platform pf(env, *nitpicker.input());
|
||||
|
||||
Area const max_size(530, 620);
|
||||
Point const initial_position(256, 80);
|
||||
@ -92,10 +160,9 @@ int main(int argc, char **argv)
|
||||
);
|
||||
|
||||
/* initialize mouse cursor */
|
||||
Point mouse_position;
|
||||
static Icon<Pixel_rgb565, 32, 32> mcursor;
|
||||
if (Config::mouse_cursor) {
|
||||
mcursor.geometry(Rect(mouse_position, Area(32, 32)));
|
||||
mcursor.geometry(Rect(Point(0, 0), Area(32, 32)));
|
||||
mcursor.rgba(POINTER_RGBA);
|
||||
mcursor.alpha(255);
|
||||
mcursor.findable(0);
|
||||
@ -107,47 +174,7 @@ int main(int argc, char **argv)
|
||||
initial_position.x(), initial_position.y());
|
||||
browser.ypos(0);
|
||||
|
||||
/* enter main loop */
|
||||
unsigned long curr_time, old_time;
|
||||
curr_time = old_time = pf.timer_ticks();
|
||||
for (;;) {
|
||||
Event ev = pf.get_event();
|
||||
static Main main(pf, browser, user_state, mcursor);
|
||||
pf.event_handler(main);
|
||||
|
||||
if (ev.type != Event::WHEEL) {
|
||||
ev.mouse_position = ev.mouse_position - user_state.view_position();
|
||||
|
||||
/* update mouse cursor */
|
||||
if (Config::mouse_cursor && (ev.mouse_position.x() != mouse_position.x()
|
||||
|| ev.mouse_position.y() != mouse_position.y())) {
|
||||
int x1 = min(ev.mouse_position.x(), mouse_position.x());
|
||||
int y1 = min(ev.mouse_position.y(), mouse_position.y());
|
||||
int x2 = max(ev.mouse_position.x() + mcursor.size().w() - 1,
|
||||
mouse_position.x() + mcursor.size().w() - 1);
|
||||
int y2 = max(ev.mouse_position.y() + mcursor.size().h() - 1,
|
||||
mouse_position.y() + mcursor.size().h() - 1);
|
||||
|
||||
mcursor.geometry(Rect(ev.mouse_position, mcursor.size()));
|
||||
browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
|
||||
|
||||
mouse_position = ev.mouse_position;
|
||||
}
|
||||
}
|
||||
|
||||
user_state.handle_event(ev);
|
||||
|
||||
if (ev.type == Event::TIMER)
|
||||
Tick::handle(pf.timer_ticks());
|
||||
|
||||
/* perform periodic redraw */
|
||||
curr_time = pf.timer_ticks();
|
||||
if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) {
|
||||
old_time = curr_time;
|
||||
browser.process_redraw();
|
||||
}
|
||||
|
||||
if (ev.type == Event::QUIT)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class Linkicon_event_handler : public Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
if (ev.type != Event::PRESS || !_navbar) return;
|
||||
|
||||
|
@ -69,7 +69,7 @@ class Arrow_event_handler : public Event_handler, public Tick
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
|
||||
@ -166,7 +166,7 @@ class Slider_event_handler : public Event_handler
|
||||
/**
|
||||
* Event handler interface
|
||||
*/
|
||||
void handle(Event &ev)
|
||||
void handle_event(Event const &ev) override
|
||||
{
|
||||
static int key_cnt;
|
||||
static int curr_my, orig_my;
|
||||
|
@ -14,16 +14,10 @@
|
||||
*/
|
||||
|
||||
#include <base/env.h>
|
||||
#include <base/child.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/service.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <base/blocking.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <ram_session/connection.h>
|
||||
#include <cpu_session/connection.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <os/config.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <launchpad/launchpad.h>
|
||||
|
||||
using namespace Genode;
|
||||
@ -33,10 +27,11 @@ using namespace Genode;
|
||||
** Launchpad **
|
||||
***************/
|
||||
|
||||
Launchpad::Launchpad(unsigned long initial_quota)
|
||||
Launchpad::Launchpad(Env &env, unsigned long initial_quota)
|
||||
:
|
||||
_env(env),
|
||||
_initial_quota(initial_quota),
|
||||
_sliced_heap(env()->ram_session(), env()->rm_session())
|
||||
_sliced_heap(_env.ram(), _env.rm())
|
||||
{
|
||||
/* names of services provided by the parent */
|
||||
static const char *names[] = {
|
||||
@ -45,25 +40,24 @@ Launchpad::Launchpad(unsigned long initial_quota)
|
||||
"RAM", "RM", "PD", "CPU", "IO_MEM", "IO_PORT", "IRQ", "ROM", "LOG",
|
||||
|
||||
/* services expected to got started by init */
|
||||
"Nitpicker", "Init", "Timer", "PCI", "Block", "Nic", "Rtc",
|
||||
"Nitpicker", "Init", "Timer", "Block", "Nic", "Rtc",
|
||||
|
||||
0 /* null-termination */
|
||||
};
|
||||
for (unsigned i = 0; names[i]; i++)
|
||||
_parent_services.insert(new (env()->heap())
|
||||
Parent_service(names[i]));
|
||||
new (_heap) Launchpad_child::Parent_service(_parent_services, names[i]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a program with the specified name already exists
|
||||
*/
|
||||
bool Launchpad::_child_name_exists(const char *name)
|
||||
bool Launchpad::_child_name_exists(Launchpad_child::Name const &name)
|
||||
{
|
||||
Launchpad_child *c = _children.first();
|
||||
|
||||
for ( ; c; c = c->List<Launchpad_child>::Element::next())
|
||||
if (strcmp(c->name(), name) == 0)
|
||||
if (c->name() == name)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -73,30 +67,23 @@ bool Launchpad::_child_name_exists(const char *name)
|
||||
/**
|
||||
* Create a unique name based on the filename
|
||||
*
|
||||
* If a program with the filename as name already exists, we
|
||||
* add a counting number as suffix.
|
||||
* If a program with the filename as name already exists, we add a counting
|
||||
* number as suffix.
|
||||
*/
|
||||
void Launchpad::_get_unique_child_name(const char *filename, char *dst, int dst_len)
|
||||
Launchpad_child::Name
|
||||
Launchpad::_get_unique_child_name(Launchpad_child::Name const &binary_name)
|
||||
{
|
||||
Lock::Guard lock_guard(_children_lock);
|
||||
|
||||
char buf[64];
|
||||
char suffix[8];
|
||||
suffix[0] = 0;
|
||||
if (!_child_name_exists(binary_name))
|
||||
return binary_name;
|
||||
|
||||
for (int cnt = 1; true; cnt++) {
|
||||
|
||||
/* build program name composed of filename and numeric suffix */
|
||||
snprintf(buf, sizeof(buf), "%s%s", filename, suffix);
|
||||
for (unsigned cnt = 1; ; cnt++) {
|
||||
|
||||
/* if such a program name does not exist yet, we are happy */
|
||||
if (!_child_name_exists(buf)) {
|
||||
strncpy(dst, buf, dst_len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* increase number of suffix */
|
||||
snprintf(suffix, sizeof(suffix), ".%d", cnt + 1);
|
||||
Launchpad_child::Name const unique(binary_name, ".", cnt);
|
||||
if (!_child_name_exists(unique))
|
||||
return unique;
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,370 +101,98 @@ void Launchpad::process_config()
|
||||
* Iterate through all entries of the config file and create
|
||||
* launchpad entries as specified.
|
||||
*/
|
||||
int launcher_cnt = 0;
|
||||
for (unsigned i = 0; i < config_node.num_sub_nodes(); i++) {
|
||||
Xml_node node = config_node.sub_node(i);
|
||||
if (node.has_type("launcher"))
|
||||
config_node.for_each_sub_node("launcher", [&] (Xml_node node) {
|
||||
|
||||
/* catch XML syntax errors within launcher node */
|
||||
try {
|
||||
/* read file name and default quote from launcher node */
|
||||
Xml_node::Attribute filename_attr = node.attribute("name");
|
||||
typedef Launchpad_child::Name Name;
|
||||
Name *name = new (_heap) Name(node.attribute_value("name", Name()));
|
||||
|
||||
enum { MAX_NAME_LEN = 128 };
|
||||
char *filename = (char *)env()->heap()->alloc(MAX_NAME_LEN);
|
||||
if (!filename) {
|
||||
Genode::error("out of memory while processing configuration");
|
||||
return;
|
||||
}
|
||||
filename_attr.value(filename, MAX_NAME_LEN);
|
||||
Xml_node::Attribute ram_quota_attr = node.attribute("ram_quota");
|
||||
Number_of_bytes default_ram_quota = 0;
|
||||
ram_quota_attr.value(&default_ram_quota);
|
||||
Number_of_bytes default_ram_quota =
|
||||
node.attribute_value("ram_quota", Number_of_bytes(0));
|
||||
|
||||
/*
|
||||
* Obtain configuration for the child
|
||||
*/
|
||||
Dataspace_capability config_ds;
|
||||
/*
|
||||
* Obtain configuration for the child
|
||||
*/
|
||||
Dataspace_capability config_ds;
|
||||
|
||||
if (node.has_sub_node("configfile")
|
||||
&& node.sub_node("configfile").has_attribute("name")) {
|
||||
typedef String<128> Rom_name;
|
||||
|
||||
char name[128];
|
||||
node.sub_node("configfile").attribute("name").value(name, sizeof(name));
|
||||
if (node.has_sub_node("configfile")) {
|
||||
|
||||
Rom_connection config_rom(name);
|
||||
config_rom.on_destruction(Rom_connection::KEEP_OPEN);
|
||||
Rom_name const name =
|
||||
node.sub_node("configfile").attribute_value("name", Rom_name());
|
||||
|
||||
config_ds = config_rom.dataspace();
|
||||
}
|
||||
Rom_connection &config_rom = *new (_heap) Rom_connection(name.string());
|
||||
|
||||
if (node.has_sub_node("config")) {
|
||||
|
||||
Xml_node config_node = node.sub_node("config");
|
||||
|
||||
/* allocate dataspace for config */
|
||||
size_t const config_size = config_node.size();
|
||||
config_ds = env()->ram_session()->alloc(config_size);
|
||||
|
||||
/* copy configuration into new dataspace */
|
||||
char * const ptr = env()->rm_session()->attach(config_ds);
|
||||
Genode::memcpy(ptr, config_node.addr(), config_size);
|
||||
env()->rm_session()->detach(ptr);
|
||||
}
|
||||
|
||||
/* add launchpad entry */
|
||||
add_launcher(filename, default_ram_quota, config_ds);
|
||||
launcher_cnt++;
|
||||
|
||||
} catch (...) {
|
||||
Genode::warning("launcher entry ", launcher_cnt + 1, " is malformed");
|
||||
}
|
||||
else {
|
||||
char buf[32];
|
||||
node.type_name(buf, sizeof(buf));
|
||||
Genode::warning("ignoring unsupported tag <", Genode::Cstring(buf), ">");
|
||||
config_ds = config_rom.dataspace();
|
||||
}
|
||||
}
|
||||
|
||||
if (node.has_sub_node("config")) {
|
||||
|
||||
Xml_node config_node = node.sub_node("config");
|
||||
|
||||
/* allocate dataspace for config */
|
||||
size_t const size = config_node.size();
|
||||
config_ds = env()->ram_session()->alloc(size);
|
||||
|
||||
/* copy configuration into new dataspace */
|
||||
Attached_dataspace attached(config_ds);
|
||||
memcpy(attached.local_addr<char>(), config_node.addr(), size);
|
||||
}
|
||||
|
||||
/* add launchpad entry */
|
||||
add_launcher(*name, default_ram_quota, config_ds);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Launchpad_child *Launchpad::start_child(const char *filename,
|
||||
Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name,
|
||||
unsigned long ram_quota,
|
||||
Genode::Dataspace_capability config_ds)
|
||||
Dataspace_capability config_ds)
|
||||
{
|
||||
Genode::log("starting ", filename, " with quota ", ram_quota);
|
||||
log("starting ", binary_name, " with quota ", ram_quota);
|
||||
|
||||
/* find unique name for new child */
|
||||
char unique_name[64];
|
||||
_get_unique_child_name(filename, unique_name, sizeof(unique_name));
|
||||
Genode::log("using unique child name \"", Cstring(unique_name), "\"");
|
||||
Launchpad_child::Name const unique_name = _get_unique_child_name(binary_name);
|
||||
log("using unique child name \"", unique_name, "\"");
|
||||
|
||||
if (ram_quota > env()->ram_session()->avail()) {
|
||||
Genode::error("child's ram quota is higher than our available quota, using available quota");
|
||||
error("child's ram quota is higher than our available quota, using available quota");
|
||||
ram_quota = env()->ram_session()->avail() - 256*1000;
|
||||
}
|
||||
|
||||
size_t metadata_size = 4096*16 + sizeof(Launchpad_child);
|
||||
|
||||
if (metadata_size > ram_quota) {
|
||||
Genode::error("too low ram_quota to hold child metadata");
|
||||
error("too low ram_quota to hold child metadata");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ram_quota -= metadata_size;
|
||||
|
||||
/* lookup executable elf binary */
|
||||
Dataspace_capability file_cap;
|
||||
Rom_session_capability rom_cap;
|
||||
try {
|
||||
/*
|
||||
* When creating a ROM connection for a non-existing file, the
|
||||
* constructor of 'Rom_connection' throws a 'Parent::Service_denied'
|
||||
* exception.
|
||||
*/
|
||||
Rom_connection rom(prefixed_label(Session_label(Cstring(unique_name)),
|
||||
Session_label(filename)).string());
|
||||
rom.on_destruction(Rom_connection::KEEP_OPEN);
|
||||
rom_cap = rom.cap();
|
||||
file_cap = rom.dataspace();
|
||||
} catch (...) {
|
||||
Genode::error("could not access ROM module \"", filename, "\"");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create ram session for child with some of our own quota */
|
||||
Ram_connection ram;
|
||||
ram.on_destruction(Ram_connection::KEEP_OPEN);
|
||||
ram.ref_account(env()->ram_session_cap());
|
||||
env()->ram_session()->transfer_quota(ram.cap(), ram_quota);
|
||||
|
||||
/* create cpu session for child */
|
||||
Cpu_connection cpu(unique_name);
|
||||
cpu.on_destruction(Cpu_connection::KEEP_OPEN);
|
||||
|
||||
if (!ram.cap().valid() || !cpu.cap().valid()) {
|
||||
if (ram.cap().valid()) {
|
||||
Genode::warning("failed to create CPU session");
|
||||
env()->parent()->close(ram.cap());
|
||||
}
|
||||
if (cpu.cap().valid()) {
|
||||
Genode::warning("failed to create RAM session");
|
||||
env()->parent()->close(cpu.cap());
|
||||
}
|
||||
env()->parent()->close(rom_cap);
|
||||
Genode::log("our quota is ", env()->ram_session()->quota());
|
||||
return 0;
|
||||
}
|
||||
|
||||
Pd_connection pd;
|
||||
pd.on_destruction(Pd_connection::KEEP_OPEN);
|
||||
if (!pd.cap().valid()) {
|
||||
Genode::warning("failed to create PD session");
|
||||
env()->parent()->close(ram.cap());
|
||||
env()->parent()->close(cpu.cap());
|
||||
env()->parent()->close(rom_cap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
Launchpad_child *c = new (&_sliced_heap)
|
||||
Launchpad_child(unique_name, file_cap, pd.cap(), ram.cap(),
|
||||
cpu.cap(), rom_cap,
|
||||
&_cap_session, &_parent_services, &_child_services,
|
||||
config_ds, this);
|
||||
Launchpad_child(_env, unique_name, binary_name, ram_quota,
|
||||
_parent_services, _child_services, config_ds);
|
||||
|
||||
Lock::Guard lock_guard(_children_lock);
|
||||
_children.insert(c);
|
||||
|
||||
add_child(unique_name, ram_quota, c, c->heap());
|
||||
|
||||
add_child(unique_name, ram_quota, *c, c->heap());
|
||||
return c;
|
||||
} catch (Cpu_session::Thread_creation_failed) {
|
||||
Genode::warning("failed to create child - Cpu_session::Thread_creation_failed");
|
||||
} catch (...) {
|
||||
Genode::warning("failed to create child - unknown reason");
|
||||
}
|
||||
|
||||
env()->parent()->close(ram.cap());
|
||||
env()->parent()->close(cpu.cap());
|
||||
env()->parent()->close(rom_cap);
|
||||
} catch (...) {
|
||||
warning("failed to create child - unknown reason"); }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Watchdog-guarded child destruction mechanism
|
||||
*
|
||||
* During the destruction of a child, all sessions of the child are getting
|
||||
* closed. A server, however, may refuse to answer a close call. We detect
|
||||
* this case using a watchdog mechanism, unblock the 'close' call, and
|
||||
* proceed with the closing the other remaining sessions.
|
||||
*/
|
||||
class Child_destructor_thread : Thread_deprecated<2*4096>
|
||||
void Launchpad::exit_child(Launchpad_child &child)
|
||||
{
|
||||
private:
|
||||
|
||||
Launchpad_child *_curr_child; /* currently destructed child */
|
||||
Allocator *_curr_alloc; /* child object'sallocator */
|
||||
Lock _submit_lock; /* only one submission at a time */
|
||||
Lock _activate_lock; /* submission protocol */
|
||||
bool _ready; /* set if submission is completed */
|
||||
int _watchdog_cnt; /* watchdog counter in milliseconds */
|
||||
|
||||
/**
|
||||
* Thread entry function
|
||||
*/
|
||||
void entry() {
|
||||
while (true) {
|
||||
|
||||
/* wait for next submission */
|
||||
_activate_lock.lock();
|
||||
|
||||
/*
|
||||
* Eventually long-taking operation that involves the
|
||||
* closing of all session of the child. This procedure
|
||||
* may need blocking cancellation to proceed in the
|
||||
* case servers are unresponsive.
|
||||
*/
|
||||
try {
|
||||
destroy(_curr_alloc, _curr_child);
|
||||
} catch (Blocking_canceled) {
|
||||
Genode::error("suspicious cancellation");
|
||||
}
|
||||
|
||||
_ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Watchdog timer granularity in milliseconds. This value defined
|
||||
* after how many milliseconds the watchdog is activated.
|
||||
*/
|
||||
enum { WATCHDOG_GRANULARITY_MS = 10 };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Child_destructor_thread() :
|
||||
Thread_deprecated("child_destructor"),
|
||||
_curr_child(0), _curr_alloc(0),
|
||||
_activate_lock(Lock::LOCKED),
|
||||
_ready(true)
|
||||
{
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destruct child, coping with unresponsive servers
|
||||
*
|
||||
* \param alloc Child object's allocator
|
||||
* \param child Child to destruct
|
||||
* \param timeout_ms Maximum destruction time until the destructing
|
||||
* thread gets waken up to give up the close call to
|
||||
* an unreponsive server.
|
||||
*/
|
||||
void submit_for_destruction(Allocator *alloc, Launchpad_child *child,
|
||||
Timer::Session *timer, int timeout_ms)
|
||||
{
|
||||
/* block until destructor thread is ready for new submission */
|
||||
Lock::Guard _lock_guard(_submit_lock);
|
||||
|
||||
/* register submission values */
|
||||
_curr_child = child;
|
||||
_curr_alloc = alloc;
|
||||
_ready = false;
|
||||
_watchdog_cnt = 0;
|
||||
|
||||
/* wake up the destruction thread */
|
||||
_activate_lock.unlock();
|
||||
|
||||
/*
|
||||
* Now, the destruction thread attempts to close all the
|
||||
* child's sessions. Check '_ready' flag periodically.
|
||||
*/
|
||||
while (!_ready) {
|
||||
|
||||
/* give the destruction thread some time to proceed */
|
||||
timer->msleep(WATCHDOG_GRANULARITY_MS);
|
||||
_watchdog_cnt += WATCHDOG_GRANULARITY_MS;
|
||||
|
||||
/* check if we reached the timeout */
|
||||
if (_watchdog_cnt > timeout_ms) {
|
||||
|
||||
/*
|
||||
* The destruction seems to got stuck, let's shake it a
|
||||
* bit to proceed and reset the watchdog counter to give
|
||||
* the next blocking operation a chance to execute.
|
||||
*/
|
||||
child->cancel_blocking();
|
||||
_watchdog_cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Construct a timer session for the watchdog timer on demand
|
||||
*/
|
||||
static Timer::Session *timer_session()
|
||||
{
|
||||
static Timer::Connection timer;
|
||||
return &timer;
|
||||
}
|
||||
|
||||
|
||||
Dataspace_capability Launchpad_child::_ldso_ds()
|
||||
{
|
||||
static bool first_attempt_failed = false;
|
||||
|
||||
if (!first_attempt_failed) {
|
||||
try {
|
||||
static Rom_connection rom("ld.lib.so");
|
||||
static Dataspace_capability ds = rom.dataspace();
|
||||
return ds;
|
||||
} catch (...) { }
|
||||
}
|
||||
|
||||
first_attempt_failed = true;
|
||||
return Dataspace_capability();
|
||||
}
|
||||
|
||||
|
||||
/* construct child-destructor thread early - in case we run out of threads */
|
||||
static Child_destructor_thread child_destructor;
|
||||
|
||||
/**
|
||||
* Destruct Launchpad_child, cope with infinitely blocking server->close calls
|
||||
*
|
||||
* The arguments correspond to the 'Child_destructor_thread::submit_for_destruction'
|
||||
* function.
|
||||
*/
|
||||
static void destruct_child(Allocator *alloc, Launchpad_child *child,
|
||||
Timer::Session *timer, int timeout)
|
||||
{
|
||||
/* if no timer session was provided by our caller, we have create one */
|
||||
if (!timer)
|
||||
timer = timer_session();
|
||||
|
||||
child_destructor.submit_for_destruction(alloc, child, timer, timeout);
|
||||
}
|
||||
|
||||
|
||||
void Launchpad::exit_child(Launchpad_child *child,
|
||||
Timer::Session *timer,
|
||||
int session_close_timeout_ms)
|
||||
{
|
||||
remove_child(child->name(), child->heap());
|
||||
remove_child(child.name(), child.heap());
|
||||
|
||||
Lock::Guard lock_guard(_children_lock);
|
||||
_children.remove(child);
|
||||
_children.remove(&child);
|
||||
|
||||
Ram_session_capability ram_session_cap = child->ram_session_cap();
|
||||
Cpu_session_capability cpu_session_cap = child->cpu_session_cap();
|
||||
Rom_session_capability rom_session_cap = child->rom_session_cap();
|
||||
|
||||
const Genode::Server *server = child->server();
|
||||
destruct_child(&_sliced_heap, child, timer, session_close_timeout_ms);
|
||||
|
||||
env()->parent()->close(cpu_session_cap);
|
||||
env()->parent()->close(rom_session_cap);
|
||||
env()->parent()->close(ram_session_cap);
|
||||
|
||||
/*
|
||||
* The killed child may have provided services to other children.
|
||||
* Since the server is dead by now, we cannot close its sessions
|
||||
* in the cooperative way. Instead, we need to instruct each
|
||||
* other child to forget about session associated with the dead
|
||||
* server. Note that the 'child' pointer points a a no-more
|
||||
* existing object. It is only used to identify the corresponding
|
||||
* session. It must never by de-referenced!
|
||||
*/
|
||||
Launchpad_child *c = _children.first();
|
||||
for ( ; c; c = c->Genode::List<Launchpad_child>::Element::next())
|
||||
c->revoke_server(server);
|
||||
destroy(_sliced_heap, &child);
|
||||
}
|
||||
|
@ -11,10 +11,9 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/signal.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <os/config.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <scout/user_state.h>
|
||||
#include <scout/nitpicker_graphics_backend.h>
|
||||
|
||||
@ -101,12 +100,10 @@ static bool config_decoration = true;
|
||||
/**
|
||||
* Parse configuration
|
||||
*/
|
||||
static void read_config()
|
||||
static void read_config(Genode::Xml_node config_node)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Xml_node config_node = config()->xml_node();
|
||||
|
||||
try {
|
||||
char buf[16];
|
||||
config_node.attribute("animate").value(buf, sizeof(buf));
|
||||
@ -169,42 +166,71 @@ static void read_config()
|
||||
|
||||
struct Input_handler
|
||||
{
|
||||
GENODE_RPC(Rpc_handle_input, void, handle, Scout::Event&);
|
||||
GENODE_RPC(Rpc_handle_input, void, handle_input, Scout::Event const &);
|
||||
GENODE_RPC_INTERFACE(Rpc_handle_input);
|
||||
};
|
||||
|
||||
|
||||
class Input_handler_component : public Genode::Rpc_object<Input_handler,
|
||||
Input_handler_component>
|
||||
class Main : public Scout::Event_handler
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
Scout::Platform &_pf;
|
||||
Scout::User_state &_user_state;
|
||||
Framebuffer_window<Genode::Pixel_rgb565> &_fb_win;
|
||||
Genode::Signal_receiver &_sig_rec;
|
||||
Genode::Attached_rom_dataspace &_config;
|
||||
unsigned long _curr_time, _old_time;
|
||||
|
||||
void _handle_config()
|
||||
{
|
||||
_config.update();
|
||||
|
||||
/* keep the current values by default */
|
||||
config_fb_x = _fb_win.view_x();
|
||||
config_fb_y = _fb_win.view_y();
|
||||
config_fb_width = _fb_win.view_w();
|
||||
config_fb_height = _fb_win.view_h();
|
||||
|
||||
try { read_config(_config.xml()); } catch (...) { }
|
||||
|
||||
_fb_win.name(config_title);
|
||||
_fb_win.config_alpha(config_alpha);
|
||||
_fb_win.config_resize_handle(config_resize_handle);
|
||||
_fb_win.config_decoration(config_decoration);
|
||||
|
||||
/* must get called after 'config_decoration()' */
|
||||
_fb_win.content_geometry(config_fb_x, config_fb_y,
|
||||
config_fb_width, config_fb_height);
|
||||
_user_state.update_view_offset();
|
||||
}
|
||||
|
||||
Genode::Signal_handler<Main> _config_handler;
|
||||
|
||||
public:
|
||||
|
||||
Input_handler_component(Scout::Platform &pf,
|
||||
Scout::User_state &user_state,
|
||||
Framebuffer_window<Genode::Pixel_rgb565> &fb_win,
|
||||
Genode::Signal_receiver &sig_rec)
|
||||
Main(Scout::Platform &pf,
|
||||
Scout::User_state &user_state,
|
||||
Framebuffer_window<Genode::Pixel_rgb565> &fb_win,
|
||||
Genode::Entrypoint &ep,
|
||||
Genode::Attached_rom_dataspace &config)
|
||||
:
|
||||
_pf(pf),
|
||||
_user_state(user_state),
|
||||
_fb_win(fb_win),
|
||||
_sig_rec(sig_rec)
|
||||
_config(config),
|
||||
_config_handler(ep, *this, &Main::_handle_config)
|
||||
{
|
||||
_curr_time = _old_time = _pf.timer_ticks();
|
||||
|
||||
config.sigh(_config_handler);
|
||||
}
|
||||
|
||||
void handle(Scout::Event &ev)
|
||||
void handle_event(Scout::Event const &event) override
|
||||
{
|
||||
using Scout::Event;
|
||||
|
||||
Event ev = event;
|
||||
|
||||
if (ev.type != Event::WHEEL)
|
||||
ev.mouse_position = ev.mouse_position - _user_state.view_position();
|
||||
|
||||
@ -217,30 +243,11 @@ class Input_handler_component : public Genode::Rpc_object<Input_handler,
|
||||
|
||||
if (ev.type == Event::TIMER) {
|
||||
Scout::Tick::handle(_pf.timer_ticks());
|
||||
/* check for configuration changes */
|
||||
if (_sig_rec.pending()) {
|
||||
_sig_rec.wait_for_signal();
|
||||
Genode::config()->reload();
|
||||
/* keep the current values by default */
|
||||
config_fb_x = _fb_win.view_x();
|
||||
config_fb_y = _fb_win.view_y();
|
||||
config_fb_width = _fb_win.view_w();
|
||||
config_fb_height = _fb_win.view_h();
|
||||
try { read_config(); } catch (...) { }
|
||||
_fb_win.name(config_title);
|
||||
_fb_win.config_alpha(config_alpha);
|
||||
_fb_win.config_resize_handle(config_resize_handle);
|
||||
_fb_win.config_decoration(config_decoration);
|
||||
/* must get called after 'config_decoration()' */
|
||||
_fb_win.content_geometry(config_fb_x, config_fb_y,
|
||||
config_fb_width, config_fb_height);
|
||||
_user_state.update_view_offset();
|
||||
}
|
||||
}
|
||||
|
||||
/* perform periodic redraw */
|
||||
_curr_time = _pf.timer_ticks();
|
||||
if (!_pf.event_pending() && ((_curr_time - _old_time > 20) || (_curr_time < _old_time))) {
|
||||
if ((_curr_time - _old_time > 20) || (_curr_time < _old_time)) {
|
||||
_old_time = _curr_time;
|
||||
_fb_win.process_redraw();
|
||||
}
|
||||
@ -248,29 +255,24 @@ class Input_handler_component : public Genode::Rpc_object<Input_handler,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Main program
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
/***************
|
||||
** Component **
|
||||
***************/
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
try { read_config(); } catch (...) { }
|
||||
static Genode::Attached_rom_dataspace config(env, "config");
|
||||
|
||||
/*
|
||||
* Register signal handler for config changes
|
||||
*/
|
||||
static Genode::Signal_receiver sig_rec;
|
||||
static Genode::Signal_context sig_ctx;
|
||||
|
||||
try { Genode::config()->sigh(sig_rec.manage(&sig_ctx)); } catch (...) { }
|
||||
try { read_config(config.xml()); } catch (...) { }
|
||||
|
||||
/* heuristic for allocating the double-buffer backing store */
|
||||
enum { WINBORDER_WIDTH = 10, WINBORDER_HEIGHT = 40 };
|
||||
|
||||
/* init platform */
|
||||
static Nitpicker::Connection nitpicker;
|
||||
static Platform pf(*nitpicker.input());
|
||||
static Nitpicker::Connection nitpicker(env);
|
||||
static Platform pf(env, *nitpicker.input());
|
||||
|
||||
Area const max_size(config_fb_width + WINBORDER_WIDTH,
|
||||
config_fb_height + WINBORDER_HEIGHT);
|
||||
@ -301,27 +303,9 @@ int main(int argc, char **argv)
|
||||
fb_win.content_geometry(config_fb_x, config_fb_y,
|
||||
config_fb_width, config_fb_height);
|
||||
|
||||
/* initialize server entry point */
|
||||
enum { STACK_SIZE = 2*1024*sizeof(Genode::addr_t) };
|
||||
static Genode::Cap_connection cap;
|
||||
static Genode::Rpc_entrypoint ep(&cap, STACK_SIZE, "liquid_fb_ep");
|
||||
|
||||
/* initialize public services */
|
||||
init_services(ep);
|
||||
init_services(env.ep().rpc_ep());
|
||||
|
||||
/* create local input handler service */
|
||||
static Input_handler_component input_handler(pf, user_state, fb_win,
|
||||
sig_rec);
|
||||
Genode::Capability<Input_handler> input_handler_cap = ep.manage(&input_handler);
|
||||
|
||||
/* enter main loop */
|
||||
for (;;) {
|
||||
Event ev = pf.get_event();
|
||||
input_handler_cap.call<Input_handler::Rpc_handle_input>(ev);
|
||||
|
||||
if (ev.type == Event::QUIT)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
static Main main(pf, user_state, fb_win, env.ep(), config);
|
||||
pf.event_handler(main);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class Window_content : public Scout::Element
|
||||
:
|
||||
_input_session(input_session),_element(element) { }
|
||||
|
||||
void handle(Scout::Event &ev)
|
||||
void handle_event(Scout::Event const &ev) override
|
||||
{
|
||||
using namespace Scout;
|
||||
|
||||
|
@ -401,7 +401,7 @@ int main(int argc, char **argv)
|
||||
Framebuffer::Mode::RGB565), false);
|
||||
|
||||
/* initialize entry point that serves the root interface */
|
||||
enum { STACK_SIZE = 4096 };
|
||||
enum { STACK_SIZE = 4096*sizeof(long) };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "nitlog_ep");
|
||||
|
||||
|
Reference in New Issue
Block a user