scout/launchpad/liquid_fb/nitlog: API transition

Issue #1987
This commit is contained in:
Norman Feske
2017-01-11 16:06:26 +01:00
parent 7790c7cb67
commit 36db1866a2
22 changed files with 590 additions and 536 deletions

View File

@ -21,9 +21,7 @@
#include <base/allocator.h> #include <base/allocator.h>
#include <base/service.h> #include <base/service.h>
#include <base/printf.h>
#include <base/lock.h> #include <base/lock.h>
#include <cap_session/connection.h>
#include <timer_session/timer_session.h> #include <timer_session/timer_session.h>
#include <pd_session/client.h> #include <pd_session/client.h>
#include <init/child.h> #include <init/child.h>

View File

@ -0,0 +1,24 @@
/*
* \brief Mini C initialization
* \author Christian Helmuth
* \date 2008-07-24
*/
/*
* Copyright (C) 2008-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _MINI_C__INIT_H_
#define _MINI_C__INIT_H_
#include <base/allocator.h>
/**
* Initialize malloc/free
*/
extern "C" void mini_c_init(Genode::Allocator &);
#endif /* _MINI_C__INIT_H_ */

View File

@ -1,35 +0,0 @@
/*
* \brief Malloc/free wrappers for Genode
* \date 2008-07-24
* \author Norman Feske
*/
/*
* Copyright (C) 2008-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__SCOUT__ALLOC_H_
#define _INCLUDE__SCOUT__ALLOC_H_
#include <base/env.h>
namespace Scout {
static inline void *malloc(unsigned long size)
{
return Genode::env()->heap()->alloc(size);
}
static inline void free(void *addr)
{
/*
* FIXME: We expect the heap to know the size of the
* block and thus, just specify zero as size.
*/
Genode::env()->heap()->free(addr, 0); }
}
#endif /* _INCLUDE__SCOUT__ALLOC_H_ */

View File

@ -79,11 +79,18 @@ class Scout::Canvas : public Canvas_base
{ {
private: private:
Genode::Allocator &_alloc;
Genode::Surface<PT> _surface; Genode::Surface<PT> _surface;
public: public:
Canvas(PT *base, Area size) : _surface(base, size) { } /**
* Constructor
*
* \param alloc allocator to be used for allocating textures
*/
Canvas(PT *base, Area size, Genode::Allocator &alloc)
: _alloc(alloc), _surface(base, size) { }
Area size() const { return _surface.size(); } Area size() const { return _surface.size(); }
@ -145,14 +152,14 @@ class Scout::Canvas : public Canvas_base
{ {
using namespace Genode; using namespace Genode;
PT *pixel = (PT *)env()->heap()->alloc(size.count()*sizeof(PT)); PT *pixel = (PT *)_alloc.alloc(size.count()*sizeof(PT));
unsigned char *alpha = 0; unsigned char *alpha = 0;
if (has_alpha) if (has_alpha)
alpha = (unsigned char *)env()->heap()->alloc(size.count()); alpha = (unsigned char *)_alloc.alloc(size.count());
return new (env()->heap()) Genode::Texture<PT>(pixel, alpha, size); return new (_alloc) Genode::Texture<PT>(pixel, alpha, size);
} }
virtual void free_texture(Texture_base *texture_base) virtual void free_texture(Texture_base *texture_base)
@ -164,11 +171,11 @@ class Scout::Canvas : public Canvas_base
Genode::size_t const num_pixels = texture->size().count(); Genode::size_t const num_pixels = texture->size().count();
if (texture->alpha()) if (texture->alpha())
env()->heap()->free(texture->alpha(), num_pixels); _alloc.free(texture->alpha(), num_pixels);
env()->heap()->free(texture->pixel(), sizeof(PT)*num_pixels); _alloc.free(texture->pixel(), sizeof(PT)*num_pixels);
destroy(env()->heap(), texture); destroy(_alloc, texture);
} }
virtual void set_rgba_texture(Texture_base *texture_base, virtual void set_rgba_texture(Texture_base *texture_base,

View File

@ -17,6 +17,7 @@
/* Genode includes */ /* Genode includes */
#include <nitpicker_session/connection.h> #include <nitpicker_session/connection.h>
#include <os/pixel_rgb565.h> #include <os/pixel_rgb565.h>
#include <base/attached_dataspace.h>
/* Scout includes */ /* Scout includes */
#include <scout/graphics_backend.h> #include <scout/graphics_backend.h>
@ -32,6 +33,8 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
{ {
private: private:
Genode::Region_map &_local_rm;
Nitpicker::Connection &_nitpicker; Nitpicker::Connection &_nitpicker;
Genode::Dataspace_capability _init_fb_ds(Area max_size) Genode::Dataspace_capability _init_fb_ds(Area max_size)
@ -43,20 +46,13 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
Area _max_size; Area _max_size;
Genode::Dataspace_capability _fb_ds = { _init_fb_ds(_max_size) }; Genode::Attached_dataspace _fb_ds { _local_rm, _init_fb_ds(_max_size) };
void *_map_fb_ds()
{
return Genode::env()->rm_session()->attach(_fb_ds);
}
void *_fb_local_base = { _map_fb_ds() };
typedef Nitpicker::Session::View_handle View_handle; typedef Nitpicker::Session::View_handle View_handle;
Point _position; Point _position;
Area _view_size; Area _view_size;
View_handle _view; View_handle _view { _nitpicker.create_view() };
Canvas_base *_canvas[2]; Canvas_base *_canvas[2];
bool _flip_state = { false }; bool _flip_state = { false };
@ -83,7 +79,7 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
template <typename PT> template <typename PT>
PT *_base(unsigned idx) PT *_base(unsigned idx)
{ {
return (PT *)_fb_local_base + idx*_max_size.count(); return (PT *)_fb_ds.local_addr<PT>() + idx*_max_size.count();
} }
unsigned _front_idx() const { return _flip_state ? 1 : 0; } unsigned _front_idx() const { return _flip_state ? 1 : 0; }
@ -91,20 +87,27 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
public: public:
Nitpicker_graphics_backend(Nitpicker::Connection &nitpicker, /**
* Constructor
*
* \param alloc allocator used for allocating textures
*/
Nitpicker_graphics_backend(Genode::Region_map &local_rm,
Nitpicker::Connection &nitpicker,
Genode::Allocator &alloc,
Area max_size, Point position, Area view_size) Area max_size, Point position, Area view_size)
: :
_local_rm(local_rm),
_nitpicker(nitpicker), _nitpicker(nitpicker),
_max_size(max_size), _max_size(max_size),
_position(position), _position(position),
_view_size(view_size), _view_size(view_size)
_view(_nitpicker.create_view())
{ {
bring_to_front(); bring_to_front();
typedef Genode::Pixel_rgb565 PT; typedef Genode::Pixel_rgb565 PT;
static Canvas<PT> canvas_0(_base<PT>(0), max_size); static Canvas<PT> canvas_0(_base<PT>(0), max_size, alloc);
static Canvas<PT> canvas_1(_base<PT>(1), max_size); static Canvas<PT> canvas_1(_base<PT>(1), max_size, alloc);
_canvas[0] = &canvas_0; _canvas[0] = &canvas_0;
_canvas[1] = &canvas_1; _canvas[1] = &canvas_1;
@ -115,8 +118,8 @@ class Scout::Nitpicker_graphics_backend : public Graphics_backend
** Graphics_backend interface ** ** Graphics_backend interface **
********************************/ ********************************/
Canvas_base &front() { return *_canvas[_front_idx()]; } Canvas_base &front() override { return *_canvas[_front_idx()]; }
Canvas_base &back() { return *_canvas[ _back_idx()]; } Canvas_base &back() override { return *_canvas[ _back_idx()]; }
void copy_back_to_front(Rect rect) void copy_back_to_front(Rect rect)
{ {

View File

@ -35,19 +35,6 @@ namespace Scout {
} }
inline void *operator new(__SIZE_TYPE__ size)
{
using Genode::env;
void *addr = env()->heap()->alloc(size);
if (!addr) {
Genode::error("env()->heap() has consumed ", env()->heap()->consumed());
Genode::error("env()->ram_session()->quota = ", env()->ram_session()->quota());
throw Genode::Allocator::Out_of_memory();
}
return addr;
}
class Scout::Platform class Scout::Platform
{ {
private: private:

View File

@ -13,6 +13,7 @@
#include <base/component.h> #include <base/component.h>
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <base/heap.h>
#include <scout/platform.h> #include <scout/platform.h>
#include <scout/tick.h> #include <scout/tick.h>
@ -24,19 +25,16 @@
#include "elements.h" #include "elements.h"
#include "launchpad_window.h" #include "launchpad_window.h"
#include <base/env.h>
#include <init/child_config.h> #include <init/child_config.h>
/** static Genode::Allocator *_alloc_ptr;
* Runtime configuration
*/ void *operator new (__SIZE_TYPE__ n) { return _alloc_ptr->alloc(n); }
namespace Scout { namespace Config {
int iconbar_detail = 1;
int background_detail = 1; using namespace Scout;
int mouse_cursor = 1; using namespace Genode;
int browser_attr = 0;
} }
/** /**
@ -46,28 +44,32 @@ class Avail_quota_update : public Scout::Tick
{ {
private: private:
Launchpad *_launchpad; Ram_session &_ram;
Genode::size_t _avail; Launchpad &_launchpad;
size_t _avail = 0;
public: public:
/** /**
* Constructor * Constructor
*/ */
Avail_quota_update(Launchpad *launchpad): Avail_quota_update(Ram_session &ram, Launchpad &launchpad)
_launchpad(launchpad), _avail(0) { :
schedule(200); } _ram(ram), _launchpad(launchpad)
{
schedule(200);
}
/** /**
* Tick interface * Tick interface
*/ */
int on_tick() int on_tick()
{ {
Genode::size_t new_avail = Genode::env()->ram_session()->avail(); size_t new_avail = _ram.avail();
/* update launchpad window if needed */ /* update launchpad window if needed */
if (new_avail != _avail) if (new_avail != _avail)
_launchpad->quota(new_avail); _launchpad.quota(new_avail);
_avail = new_avail; _avail = new_avail;
@ -79,14 +81,59 @@ class Avail_quota_update : public Scout::Tick
struct Main : Scout::Event_handler struct Main : Scout::Event_handler
{ {
Scout::Platform &_pf; Env &_env;
Scout::Window &_launchpad;
Scout::User_state &_user_state;
unsigned long _old_time = _pf.timer_ticks(); Heap _heap { _env.ram(), _env.rm() };
Main(Scout::Platform &pf, Scout::Window &launchpad, Scout::User_state &user_state) bool const _global_new_initialized = (_alloc_ptr = &_heap, true);
: _pf(pf), _launchpad(launchpad), _user_state(user_state) { }
Nitpicker::Connection _nitpicker { _env };
Platform _platform { _env, *_nitpicker.input() };
bool const _event_handler_registered = (_platform.event_handler(*this), true);
Attached_rom_dataspace _config { _env, "config" };
int const _initial_x = _config.xml().attribute_value("xpos", 550U);
int const _initial_y = _config.xml().attribute_value("ypos", 150U);
unsigned const _initial_w = _config.xml().attribute_value("width", 400U);
unsigned const _initial_h = _config.xml().attribute_value("height", 400U);
Scout::Area const _max_size { 530, 620 };
Scout::Point const _initial_position { _initial_x, _initial_y };
Scout::Area const _initial_size { _initial_w, _initial_h };
Nitpicker_graphics_backend
_graphics_backend { _env.rm(), _nitpicker, _heap, _max_size,
_initial_position, _initial_size };
Launchpad_window<Pixel_rgb565>
_launchpad { _env, _graphics_backend, _initial_position, _initial_size,
_max_size, _env.ram().avail() };
void _process_config()
{
try { _launchpad.process_config(_config.xml()); } catch (...) { }
}
bool const _config_processed = (_process_config(), true);
Avail_quota_update _avail_quota_update { _env.ram(), _launchpad };
User_state _user_state { &_launchpad, &_launchpad,
_initial_position.x(), _initial_position.y() };
void _init_launchpad()
{
_launchpad.parent(&_user_state);
_launchpad.format(_initial_size);
_launchpad.ypos(0);
}
bool const _launchpad_initialized = (_init_launchpad(), true);
unsigned long _old_time = _platform.timer_ticks();
void handle_event(Scout::Event const &event) override void handle_event(Scout::Event const &event) override
{ {
@ -100,62 +147,19 @@ struct Main : Scout::Event_handler
_user_state.handle_event(ev); _user_state.handle_event(ev);
if (ev.type == Event::TIMER) if (ev.type == Event::TIMER)
Tick::handle(_pf.timer_ticks()); Tick::handle(_platform.timer_ticks());
/* perform periodic redraw */ /* perform periodic redraw */
unsigned long const curr_time = _pf.timer_ticks(); unsigned long const curr_time = _platform.timer_ticks();
if (!_pf.event_pending() && ((curr_time - _old_time > 20) if (!_platform.event_pending() && ((curr_time - _old_time > 20)
|| (curr_time < _old_time))) { || (curr_time < _old_time))) {
_old_time = curr_time; _old_time = curr_time;
_launchpad.process_redraw(); _launchpad.process_redraw();
} }
} }
Main(Env &env) : _env(env) { }
}; };
/*************** void Component::construct(Genode::Env &env) { static Main main(env); }
** Component **
***************/
void Component::construct(Genode::Env &env)
{
using namespace Scout;
static Nitpicker::Connection nitpicker(env);
static Platform pf(env, *nitpicker.input());
static Genode::Attached_rom_dataspace config(env, "config");
long const initial_x = config.xml().attribute_value("xpos", 550U);
long const initial_y = config.xml().attribute_value("ypos", 150U);
long const initial_w = config.xml().attribute_value("width", 400U);
long const initial_h = config.xml().attribute_value("height", 400U);
Area const max_size (530, 620);
Point const initial_position(initial_x, initial_y);
Area const initial_size (initial_w, initial_h);
static Nitpicker_graphics_backend
graphics_backend(nitpicker, max_size, initial_position, initial_size);
/* create instance of launchpad window */
static Launchpad_window<Pixel_rgb565>
launchpad(env, graphics_backend, initial_position, initial_size,
max_size, env.ram().avail());
/* request config file from ROM service */
try { launchpad.process_config(config.xml()); } catch (...) { }
static Avail_quota_update avail_quota_update(&launchpad);
/* create user state manager */
static User_state user_state(&launchpad, &launchpad,
initial_position.x(), initial_position.y());
launchpad.parent(&user_state);
launchpad.format(initial_size);
launchpad.ypos(0);
static Main main(pf, launchpad, user_state);
pf.event_handler(main);
}

View File

@ -232,15 +232,15 @@ template <typename PT>
Browser_window<PT>::Browser_window(Document *initial_content, Browser_window<PT>::Browser_window(Document *initial_content,
Graphics_backend &gfx_backend, Graphics_backend &gfx_backend,
Point position, Area size, Point position, Area size,
Area max_size, int attr) Area max_size, Config const &config)
: :
Browser(_IH + _TH), Window(gfx_backend, position, size, max_size, true), Browser(_IH + _TH), Window(gfx_backend, position, size, max_size, true),
_config(config),
_gfx_backend(gfx_backend) _gfx_backend(gfx_backend)
{ {
/* init attributes */ /* init attributes */
_ypos = 0; _ypos = 0;
_document = initial_content; _document = initial_content;
_attr = attr;
/* init docview and history with initial document */ /* init docview and history with initial document */
_docview.texture(&_texture); _docview.texture(&_texture);

View File

@ -61,7 +61,9 @@ class Scout::Browser_window : public Scrollbar_listener,
/** /**
* General properties * General properties
*/ */
int _attr; /* attribute mask */ Config const &_config;
int _attr = _config.browser_attr; /* attribute mask */
/** /**
* Remember graphics backend used as texture allocator * Remember graphics backend used as texture allocator
@ -72,7 +74,7 @@ class Scout::Browser_window : public Scrollbar_listener,
* Widgets * Widgets
*/ */
Titlebar<PT> _titlebar; Titlebar<PT> _titlebar;
Sky_texture<PT, 512, 512> _texture; Sky_texture<PT, 512, 512> _texture { _config.background_detail };
PT _icon_fg [_NUM_ICONS][_IH][_IW]; PT _icon_fg [_NUM_ICONS][_IH][_IW];
unsigned char _icon_fg_alpha [_NUM_ICONS][_IH][_IW]; unsigned char _icon_fg_alpha [_NUM_ICONS][_IH][_IW];
Refracted_icon<PT, short> _icon [_NUM_ICONS]; Refracted_icon<PT, short> _icon [_NUM_ICONS];
@ -112,7 +114,7 @@ class Scout::Browser_window : public Scrollbar_listener,
*/ */
Browser_window(Document *content, Graphics_backend &gfx_backend, Browser_window(Document *content, Graphics_backend &gfx_backend,
Point position, Area size, Area max_size, Point position, Area size, Area max_size,
int attr = ATTR_SIZER | ATTR_TITLEBAR); Config const &config);
/** /**
* Return visible document offset * Return visible document offset

View File

@ -14,12 +14,14 @@
#ifndef _CONFIG_H_ #ifndef _CONFIG_H_
#define _CONFIG_H_ #define _CONFIG_H_
namespace Scout { namespace Config { namespace Scout { struct Config; }
extern int iconbar_detail;
extern int background_detail;
extern int mouse_cursor;
extern int browser_attr;
} }
struct Scout::Config
{
bool background_detail = 1;
bool mouse_cursor = 0;
int browser_attr = 7;
};
#endif /* _CONFIG_H_ */ #endif /* _CONFIG_H_ */

View File

@ -236,7 +236,7 @@ class Scout::Launcher : public Anchor
public: public:
static void init(Genode::Env &); static void init(Genode::Env &, Genode::Allocator &);
/** /**
* Constructors * Constructors
@ -403,6 +403,8 @@ class Scout::Png_image : public Element
public: public:
static void init(Genode::Allocator &);
/** /**
* Constructor * Constructor
*/ */

View File

@ -21,6 +21,11 @@
using namespace Genode; using namespace Genode;
using namespace Scout; using namespace Scout;
/* initialized by 'Launcher::init' */
static Launchpad *_launchpad_ptr;
static Allocator *_alloc_ptr;
static Env *_env_ptr;
/********************************************** /**********************************************
** Registry containing child configurations ** ** Registry containing child configurations **
@ -55,7 +60,7 @@ struct Config_registry::Entry : List<Config_registry::Entry>::Element
snprintf(buf, sizeof(buf), "%s.config", name); snprintf(buf, sizeof(buf), "%s.config", name);
Rom_connection *config = 0; Rom_connection *config = 0;
try { try {
config = new (env()->heap()) Rom_connection(buf); config = new (*_alloc_ptr) Rom_connection(*_env_ptr, buf);
return config->dataspace(); return config->dataspace();
} }
catch (...) { } catch (...) { }
@ -80,7 +85,7 @@ Dataspace_capability Config_registry::config(char const *name)
return e->dataspace; return e->dataspace;
/* if lookup failed, create and register new config */ /* if lookup failed, create and register new config */
Entry *entry = new (env()->heap()) Entry(name); Entry *entry = new (*_alloc_ptr) Entry(name);
_configs.insert(entry); _configs.insert(entry);
return entry->dataspace; return entry->dataspace;
@ -91,25 +96,12 @@ Dataspace_capability Config_registry::config(char const *name)
** Launcher interface ** ** Launcher interface **
************************/ ************************/
void Launcher::init(Genode::Env &env, Allocator &alloc)
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()); static Launchpad launchpad(env, env.ram().avail());
launchpad_ptr = &launchpad; _launchpad_ptr = &launchpad;
_alloc_ptr = &alloc;
_env_ptr = &env;
} }
@ -117,6 +109,11 @@ void Launcher::launch()
{ {
static Config_registry config_registry; static Config_registry config_registry;
launchpad().start_child(prg_name(), quota(), if (!_launchpad_ptr) {
class Missing_launchpad_init_call { };
throw Missing_launchpad_init_call();
}
_launchpad_ptr->start_child(prg_name(), quota(),
config_registry.config(prg_name().string())); config_registry.config(prg_name().string()));
} }

View File

@ -12,6 +12,7 @@
*/ */
#include <base/component.h> #include <base/component.h>
#include <base/heap.h>
#include <scout/platform.h> #include <scout/platform.h>
#include <scout/tick.h> #include <scout/tick.h>
@ -25,16 +26,9 @@
extern Scout::Document *create_document(); extern Scout::Document *create_document();
static Genode::Allocator *_alloc_ptr;
/** void *operator new (__SIZE_TYPE__ n) { return _alloc_ptr->alloc(n); }
* Runtime configuration
*/
namespace Scout { namespace Config {
int iconbar_detail = 1;
int background_detail = 1;
int mouse_cursor = 1;
int browser_attr = 0;
} }
#define POINTER_RGBA _binary_pointer_rgba_start #define POINTER_RGBA _binary_pointer_rgba_start
@ -52,25 +46,82 @@ static Scout::Generic_icon **navicons[] = { &Scout::Navbar::next_icon,
extern int native_startup(int, char **); extern int native_startup(int, char **);
namespace Scout { struct Main; } namespace Scout {
struct Main;
using namespace Genode;
}
struct Scout::Main : Scout::Event_handler struct Scout::Main : Scout::Event_handler
{ {
Scout::Platform &_pf; Env &_env;
Scout::Window &_browser;
Scout::User_state &_user_state; Heap _heap { _env.ram(), _env.rm() };
Scout::Element &_mcursor;
bool const _global_new_initialized = (_alloc_ptr = &_heap, true);
bool const _launcher_initialized = (Launcher::init(_env, _heap), true);
bool const _png_image_initialized = (Png_image::init(_heap), true);
Nitpicker::Connection _nitpicker { _env };
Platform _platform { _env, *_nitpicker.input() };
bool const _event_handler_registered = (_platform.event_handler(*this), true);
Area const _max_size { 530, 620 };
Point const _initial_position { 256, 80 };
Area const _initial_size { 530, 400 };
Config const _config;
Nitpicker_graphics_backend
_graphics_backend { _env.rm(), _nitpicker, _heap, _max_size,
_initial_position, _initial_size };
void _init_navicons()
{
for (unsigned int i = 0; i < sizeof(navicons)/sizeof(void *); i++) {
Fade_icon<Pixel_rgb565, 64, 64> *icon = new Fade_icon<Pixel_rgb565, 64, 64>;
icon->rgba(navicons_rgba[i]);
icon->alpha(100);
*navicons[i] = icon;
}
}
bool const _navicons_initialized = (_init_navicons(), true);
Document &_doc = *create_document();
/* create instance of browser window */
Browser_window<Pixel_rgb565> _browser { &_doc, _graphics_backend,
_initial_position, _initial_size,
_max_size, _config };
/* initialize mouse cursor */
Icon<Pixel_rgb565, 32, 32> _mcursor;
void _init_mouse_cursor()
{
if (_config.mouse_cursor) {
_mcursor.geometry(Rect(Point(0, 0), Area(32, 32)));
_mcursor.rgba(POINTER_RGBA);
_mcursor.alpha(255);
_mcursor.findable(0);
_browser.append(&_mcursor);
}
}
bool const _mouse_cursor_initialized = (_init_mouse_cursor(), true);
User_state _user_state { &_browser, &_browser,
_initial_position.x(), _initial_position.y() };
bool const _browser_ypos_initialized = (_browser.ypos(0), true);
Scout::Point _mouse_position; Scout::Point _mouse_position;
unsigned long _old_time = _pf.timer_ticks(); unsigned long _old_time = _platform.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 void handle_event(Scout::Event const &event) override
{ {
@ -83,7 +134,7 @@ struct Scout::Main : Scout::Event_handler
ev.mouse_position = ev.mouse_position - _user_state.view_position(); ev.mouse_position = ev.mouse_position - _user_state.view_position();
/* update mouse cursor */ /* update mouse cursor */
if (Config::mouse_cursor && (ev.mouse_position.x() != _mouse_position.x() if (_config.mouse_cursor && (ev.mouse_position.x() != _mouse_position.x()
|| ev.mouse_position.y() != _mouse_position.y())) { || ev.mouse_position.y() != _mouse_position.y())) {
int x1 = min(ev.mouse_position.x(), _mouse_position.x()); int x1 = min(ev.mouse_position.x(), _mouse_position.x());
int y1 = min(ev.mouse_position.y(), _mouse_position.y()); int y1 = min(ev.mouse_position.y(), _mouse_position.y());
@ -102,79 +153,19 @@ struct Scout::Main : Scout::Event_handler
_user_state.handle_event(ev); _user_state.handle_event(ev);
if (event.type == Event::TIMER) if (event.type == Event::TIMER)
Tick::handle(_pf.timer_ticks()); Tick::handle(_platform.timer_ticks());
/* perform periodic redraw */ /* perform periodic redraw */
unsigned long curr_time = _pf.timer_ticks(); unsigned long curr_time = _platform.timer_ticks();
if (!_pf.event_pending() && ((curr_time - _old_time > 20) if (!_platform.event_pending() && ((curr_time - _old_time > 20)
|| (curr_time < _old_time))) { || (curr_time < _old_time))) {
_old_time = curr_time; _old_time = curr_time;
_browser.process_redraw(); _browser.process_redraw();
} }
} }
Main(Env &env) : _env(env) { }
}; };
/*************** void Component::construct(Genode::Env &env) { static Scout::Main main(env); }
** Component **
***************/
void Component::construct(Genode::Env &env)
{
using namespace Scout;
Launcher::init(env);
static Nitpicker::Connection nitpicker;
static Platform pf(env, *nitpicker.input());
Area const max_size(530, 620);
Point const initial_position(256, 80);
Area const initial_size(530, 400);
Config::mouse_cursor = 0;
Config::browser_attr = 7;
static Nitpicker_graphics_backend
graphics_backend(nitpicker, max_size, initial_position, initial_size);
/* initialize icons for navigation bar */
for (unsigned int i = 0; i < sizeof(navicons)/sizeof(void *); i++) {
Fade_icon<Pixel_rgb565, 64, 64> *icon = new Fade_icon<Pixel_rgb565, 64, 64>;
icon->rgba(navicons_rgba[i]);
icon->alpha(100);
*navicons[i] = icon;
}
static Document *doc = create_document();
/* create instance of browser window */
static Browser_window<Pixel_rgb565> browser
(
doc,
graphics_backend,
initial_position,
initial_size,
max_size,
Config::browser_attr
);
/* initialize mouse cursor */
static Icon<Pixel_rgb565, 32, 32> mcursor;
if (Config::mouse_cursor) {
mcursor.geometry(Rect(Point(0, 0), Area(32, 32)));
mcursor.rgba(POINTER_RGBA);
mcursor.alpha(255);
mcursor.findable(0);
browser.append(&mcursor);
}
/* create user state manager */
static User_state user_state(&browser, &browser,
initial_position.x(), initial_position.y());
browser.ypos(0);
static Main main(pf, browser, user_state, mcursor);
pf.event_handler(main);
}

View File

@ -12,15 +12,26 @@
*/ */
#include <png.h> #include <png.h>
#include <scout/misc_math.h> #include <scout/misc_math.h>
#include <scout/alloc.h> #include <mini_c/init.h>
#include "elements.h" #include "elements.h"
using namespace Scout; using namespace Scout;
static Genode::Allocator *_alloc_ptr;
static Genode::Allocator &alloc()
{
if (_alloc_ptr)
return *_alloc_ptr;
Genode::error("missing call of Png_image::init");
class Png_image_init_missing { };
throw Png_image_init_missing();
}
class Png_stream class Png_stream
{ {
private: private:
@ -66,6 +77,13 @@ extern "C" int l4libpng_fread(void *buf, int size, int nmemb, void *stream)
} }
void Png_image::init(Genode::Allocator &alloc)
{
_alloc_ptr = &alloc;
mini_c_init(alloc);
}
/*********************** /***********************
** Element interface ** ** Element interface **
***********************/ ***********************/
@ -74,8 +92,7 @@ void Png_image::fill_cache(Canvas_base &canvas)
{ {
if (_texture) return; if (_texture) return;
Png_stream *stream = new (alloc()) Png_stream((char *)_png_data);
Png_stream *stream = new Png_stream((char *)_png_data);
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr) return; if (!png_ptr) return;
@ -120,8 +137,8 @@ void Png_image::fill_cache(Canvas_base &canvas)
int needed_row_size = png_get_rowbytes(png_ptr, info_ptr)*8; int needed_row_size = png_get_rowbytes(png_ptr, info_ptr)*8;
if (curr_row_size < needed_row_size) { if (curr_row_size < needed_row_size) {
if (row_ptr) Scout::free(row_ptr); if (row_ptr) alloc().free(row_ptr, curr_row_size);
row_ptr = (png_byte *)Scout::malloc(needed_row_size); row_ptr = (png_byte *)alloc().alloc(needed_row_size);
curr_row_size = needed_row_size; curr_row_size = needed_row_size;
} }

View File

@ -30,15 +30,18 @@ class Scout::Refracted_icon : public Element
{ {
private: private:
PT *_backbuf; /* pixel back buffer */ bool _detailed = true; /* level of detail */
int _filter_backbuf; /* backbuf filtering flag */ PT *_backbuf = nullptr; /* pixel back buffer */
DT *_distmap; /* distortion table */ int _filter_backbuf = 0; /* backbuf filtering flag */
int _distmap_w, _distmap_h; /* size of distmap */ DT *_distmap = nullptr; /* distortion table */
PT *_fg; /* foreground pixels */ int _distmap_w = 0, _distmap_h = 0; /* size of distmap */
unsigned char *_fg_alpha; /* foreground alpha values */ PT *_fg = nullptr; /* foreground pixels */
unsigned char *_fg_alpha = nullptr; /* foreground alpha values */
public: public:
void detailed(bool detailed) { _detailed = detailed; }
/** /**
* Define pixel back buffer for the icon. This buffer is used for the * Define pixel back buffer for the icon. This buffer is used for the
* draw operation. It should have the same number of pixels as the * draw operation. It should have the same number of pixels as the
@ -112,7 +115,7 @@ class Scout::Refracted_icon : public Element
Texture<PT> fg(_fg, _fg_alpha, Area(_distmap_w/2, _distmap_h/2)); Texture<PT> fg(_fg, _fg_alpha, Area(_distmap_w/2, _distmap_h/2));
canvas.draw_refracted_icon(_position + abs_position, distmap, tmp, fg, canvas.draw_refracted_icon(_position + abs_position, distmap, tmp, fg,
Config::iconbar_detail, _filter_backbuf); _detailed, _filter_backbuf);
} }
}; };

View File

@ -32,14 +32,18 @@ class Scout::Sky_texture : public Element
{ {
private: private:
bool const _detailed;
Sky_texture_painter::Static_sky_texture<PT, TW, TH> _sky_texture; Sky_texture_painter::Static_sky_texture<PT, TW, TH> _sky_texture;
public: public:
Sky_texture(bool detailed = true) : _detailed(detailed) { }
void draw(Canvas_base &canvas, Point abs_position) void draw(Canvas_base &canvas, Point abs_position)
{ {
canvas.draw_sky_texture(abs_position.y(), _sky_texture, canvas.draw_sky_texture(abs_position.y(), _sky_texture,
Config::background_detail); _detailed);
} }
}; };

View File

@ -118,7 +118,7 @@ void Launchpad::process_config(Genode::Xml_node config_node)
Rom_name const name = Rom_name const name =
node.sub_node("configfile").attribute_value("name", Rom_name()); node.sub_node("configfile").attribute_value("name", Rom_name());
Rom_connection &config_rom = *new (_heap) Rom_connection(name.string()); Rom_connection &config_rom = *new (_heap) Rom_connection(_env, name.string());
config_ds = config_rom.dataspace(); config_ds = config_rom.dataspace();
} }
@ -129,10 +129,10 @@ void Launchpad::process_config(Genode::Xml_node config_node)
/* allocate dataspace for config */ /* allocate dataspace for config */
size_t const size = config_node.size(); size_t const size = config_node.size();
config_ds = env()->ram_session()->alloc(size); config_ds = _env.ram().alloc(size);
/* copy configuration into new dataspace */ /* copy configuration into new dataspace */
Attached_dataspace attached(config_ds); Attached_dataspace attached(_env.rm(), config_ds);
memcpy(attached.local_addr<char>(), config_node.addr(), size); memcpy(attached.local_addr<char>(), config_node.addr(), size);
} }
@ -152,9 +152,9 @@ Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name
Launchpad_child::Name const unique_name = _get_unique_child_name(binary_name); Launchpad_child::Name const unique_name = _get_unique_child_name(binary_name);
log("using unique child name \"", unique_name, "\""); log("using unique child name \"", unique_name, "\"");
if (ram_quota > env()->ram_session()->avail()) { if (ram_quota > _env.ram().avail()) {
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; ram_quota = _env.ram().avail() - 256*1000;
} }
size_t metadata_size = 4096*16 + sizeof(Launchpad_child); size_t metadata_size = 4096*16 + sizeof(Launchpad_child);

View File

@ -11,11 +11,26 @@
* under the terms of the GNU General Public License version 2. * under the terms of the GNU General Public License version 2.
*/ */
#include <base/env.h> #include <base/log.h>
#include <util/string.h> #include <util/string.h>
#include <mini_c/init.h>
using namespace Genode; using namespace Genode;
static Allocator *_alloc_ptr;
static Allocator &alloc()
{
if (_alloc_ptr)
return *_alloc_ptr;
error("missing call of mini_c_init");
class Missing_mini_c_init { };
throw Missing_mini_c_init();
}
void mini_c_init(Allocator &alloc) { _alloc_ptr = &alloc; }
extern "C" void *malloc(unsigned size) extern "C" void *malloc(unsigned size)
{ {
@ -27,7 +42,7 @@ extern "C" void *malloc(unsigned size)
*/ */
unsigned long real_size = size + sizeof(unsigned long); unsigned long real_size = size + sizeof(unsigned long);
void *addr = 0; void *addr = 0;
if (!env()->heap()->alloc(real_size, &addr)) if (!alloc().alloc(real_size, &addr))
return 0; return 0;
*(unsigned long *)addr = real_size; *(unsigned long *)addr = real_size;
@ -46,5 +61,5 @@ extern "C" void *calloc(unsigned nmemb, unsigned size)
extern "C" void free(void *ptr) extern "C" void free(void *ptr)
{ {
unsigned long *addr = ((unsigned long *)ptr) - 1; unsigned long *addr = ((unsigned long *)ptr) - 1;
env()->heap()->free(addr, *addr); alloc().free(addr, *addr);
} }

View File

@ -12,8 +12,10 @@
*/ */
#include <base/component.h> #include <base/component.h>
#include <base/heap.h>
#include <base/rpc_server.h> #include <base/rpc_server.h>
#include <base/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <input/component.h>
#include <scout/user_state.h> #include <scout/user_state.h>
#include <scout/nitpicker_graphics_backend.h> #include <scout/nitpicker_graphics_backend.h>
@ -21,16 +23,9 @@
#include "services.h" #include "services.h"
/** static Genode::Allocator *_alloc_ptr;
* Runtime configuration
*/ void *operator new (__SIZE_TYPE__ n) { return _alloc_ptr->alloc(n); }
namespace Scout { namespace Config
{
int iconbar_detail = 1;
int background_detail = 1;
int mouse_cursor = 1;
int browser_attr = 0;
} }
void Scout::Launcher::launch() { } void Scout::Launcher::launch() { }
@ -40,27 +35,26 @@ class Background_animator : public Scout::Tick
{ {
private: private:
Framebuffer_window<Scout::Pixel_rgb565> *_fb_win; Framebuffer_window<Scout::Pixel_rgb565> &_fb_win;
int _bg_offset; int _bg_offset = 0;
public: public:
/** /**
* Constructor * Constructor
*/ */
Background_animator(Framebuffer_window<Scout::Pixel_rgb565> *fb_win): Background_animator(Framebuffer_window<Scout::Pixel_rgb565> &fb_win)
_fb_win(fb_win), _bg_offset(0) { : _fb_win(fb_win) { schedule(20); }
schedule(20); }
/** /**
* Tick interface * Tick interface
*/ */
int on_tick() int on_tick()
{ {
_fb_win->bg_offset(_bg_offset); _fb_win.bg_offset(_bg_offset);
_bg_offset += 2; _bg_offset += 2;
_fb_win->refresh(); _fb_win.refresh();
/* schedule next tick */ /* schedule next tick */
return 1; return 1;
@ -77,8 +71,8 @@ static bool config_alpha = true;
/** /**
* Size and position of virtual frame buffer * Size and position of virtual frame buffer
*/ */
static long config_fb_width = 500; static unsigned long config_fb_width = 500;
static long config_fb_height = 400; static unsigned long config_fb_height = 400;
static long config_fb_x = 400; static long config_fb_x = 400;
static long config_fb_y = 260; static long config_fb_y = 260;
@ -171,15 +165,88 @@ struct Input_handler
}; };
class Main : public Scout::Event_handler namespace Liquid_fb {
class Main;
using namespace Scout;
using namespace Genode;
}
class Liquid_fb::Main : public Scout::Event_handler
{ {
private: private:
Scout::Platform &_pf; Env &_env;
Scout::User_state &_user_state;
Framebuffer_window<Genode::Pixel_rgb565> &_fb_win; Heap _heap { _env.ram(), _env.rm() };
Genode::Attached_rom_dataspace &_config;
unsigned long _curr_time, _old_time; bool const _global_new_initialized = (_alloc_ptr = &_heap, true);
Attached_rom_dataspace _config { _env, "config" };
void _process_config()
{
try { read_config(_config.xml()); } catch (...) { }
}
bool const _config_processed = (_process_config(), true);
/* heuristic for allocating the double-buffer backing store */
enum { WINBORDER_WIDTH = 10, WINBORDER_HEIGHT = 40 };
Nitpicker::Connection _nitpicker { _env };
Platform _platform { _env, *_nitpicker.input() };
bool const _event_handler_registered = (_platform.event_handler(*this), true);
Scout::Area const _max_size { config_fb_width + WINBORDER_WIDTH,
config_fb_height + WINBORDER_HEIGHT };
Scout::Point const _initial_position { config_fb_x, config_fb_y };
Scout::Area const _initial_size = _max_size;
Nitpicker_graphics_backend
_graphics_backend { _env.rm(), _nitpicker, _heap, _max_size,
_initial_position, _initial_size };
Input::Session_component _input_session_component { _env, _env.ram() };
bool const _window_content_initialized =
(init_window_content(_env.ram(), _env.rm(), _heap, _input_session_component,
config_fb_width, config_fb_height, config_alpha), true);
Framebuffer_window<Pixel_rgb565>
_fb_win { _graphics_backend, window_content(),
_initial_position, _initial_size, _max_size,
config_title, config_alpha,
config_resize_handle, config_decoration };
/* create background animator if configured */
Constructible<Background_animator> _fb_win_bg_anim;
void _init_background_animator()
{
if (config_animate) {
_fb_win_bg_anim.construct(_fb_win);
}
}
bool _background_animator_initialized = (_init_background_animator(), true);
User_state _user_state { &_fb_win, &_fb_win,
_initial_position.x(), _initial_position.y() };
void _init_fb_win()
{
_fb_win.parent(&_user_state);
_fb_win.content_geometry(config_fb_x, config_fb_y,
config_fb_width, config_fb_height);
}
bool _fb_win_initialized = (_init_fb_win(), true);
bool _services_initialized = (init_services(_env, _input_session_component), true);
unsigned long _curr_time = _platform.timer_ticks();
unsigned long _old_time = _curr_time;
void _handle_config() void _handle_config()
{ {
@ -204,27 +271,11 @@ class Main : public Scout::Event_handler
_user_state.update_view_offset(); _user_state.update_view_offset();
} }
Genode::Signal_handler<Main> _config_handler; Signal_handler<Main> _config_handler {
_env.ep(), *this, &Main::_handle_config };
public: public:
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),
_config(config),
_config_handler(ep, *this, &Main::_handle_config)
{
_curr_time = _old_time = _pf.timer_ticks();
config.sigh(_config_handler);
}
void handle_event(Scout::Event const &event) override void handle_event(Scout::Event const &event) override
{ {
using Scout::Event; using Scout::Event;
@ -242,70 +293,22 @@ class Main : public Scout::Event_handler
_user_state.handle_event(ev); _user_state.handle_event(ev);
if (ev.type == Event::TIMER) { if (ev.type == Event::TIMER) {
Scout::Tick::handle(_pf.timer_ticks()); Scout::Tick::handle(_platform.timer_ticks());
} }
/* perform periodic redraw */ /* perform periodic redraw */
_curr_time = _pf.timer_ticks(); _curr_time = _platform.timer_ticks();
if ((_curr_time - _old_time > 20) || (_curr_time < _old_time)) { if ((_curr_time - _old_time > 20) || (_curr_time < _old_time)) {
_old_time = _curr_time; _old_time = _curr_time;
_fb_win.process_redraw(); _fb_win.process_redraw();
} }
} }
Main(Env &env) : _env(env)
{
_config.sigh(_config_handler);
}
}; };
/*************** void Component::construct(Genode::Env &env) { static Liquid_fb::Main main(env); }
** Component **
***************/
void Component::construct(Genode::Env &env)
{
using namespace Scout;
static Genode::Attached_rom_dataspace config(env, "config");
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(env);
static Platform pf(env, *nitpicker.input());
Area const max_size(config_fb_width + WINBORDER_WIDTH,
config_fb_height + WINBORDER_HEIGHT);
Point const initial_position(config_fb_x, config_fb_y);
Area const initial_size = max_size;
static Nitpicker_graphics_backend
graphics_backend(nitpicker, max_size, initial_position, initial_size);
/* initialize our window content */
init_window_content(config_fb_width, config_fb_height, config_alpha);
/* create instance of browser window */
static Framebuffer_window<Pixel_rgb565>
fb_win(graphics_backend, window_content(),
initial_position, initial_size, max_size,
config_title, config_alpha,
config_resize_handle, config_decoration);
if (config_animate) {
static Background_animator fb_win_bg_anim(&fb_win);
}
/* create user state manager */
static User_state user_state(&fb_win, &fb_win,
initial_position.x(), initial_position.y());
fb_win.parent(&user_state);
fb_win.content_geometry(config_fb_x, config_fb_y,
config_fb_width, config_fb_height);
/* initialize public services */
init_services(env.ep().rpc_ep());
static Main main(pf, user_state, fb_win, env.ep(), config);
pf.event_handler(main);
}

View File

@ -29,16 +29,6 @@
typedef Genode::Texture<Genode::Pixel_rgb565> Texture_rgb565; typedef Genode::Texture<Genode::Pixel_rgb565> Texture_rgb565;
/**
* Return singleton instance of input session component
*/
Input::Session_component &input_session()
{
static Input::Session_component inst;
return inst;
}
class Window_content : public Scout::Element class Window_content : public Scout::Element
{ {
private: private:
@ -88,18 +78,21 @@ class Window_content : public Scout::Element
struct Fb_texture struct Fb_texture
{ {
Genode::Allocator &alloc;
unsigned w, h; unsigned w, h;
Genode::Attached_ram_dataspace ds; Genode::Attached_ram_dataspace ds;
Genode::Pixel_rgb565 *pixel; Genode::Pixel_rgb565 *pixel;
unsigned char *alpha; unsigned char *alpha;
Genode::Texture<Genode::Pixel_rgb565> texture; Genode::Texture<Genode::Pixel_rgb565> texture;
Fb_texture(unsigned w, unsigned h, bool config_alpha) Fb_texture(Genode::Ram_session &ram, Genode::Region_map &local_rm,
Genode::Allocator &alloc,
unsigned w, unsigned h, bool config_alpha)
: :
w(w), h(h), alloc(alloc), w(w), h(h),
ds(Genode::env()->ram_session(), w*h*sizeof(Genode::Pixel_rgb565)), ds(ram, local_rm, w*h*sizeof(Genode::Pixel_rgb565)),
pixel(ds.local_addr<Genode::Pixel_rgb565>()), pixel(ds.local_addr<Genode::Pixel_rgb565>()),
alpha((unsigned char *)Genode::env()->heap()->alloc(w*h)), alpha((unsigned char *)alloc.alloc(w*h)),
texture(pixel, alpha, Scout::Area(w, h)) texture(pixel, alpha, Scout::Area(w, h))
{ {
int alpha_min = config_alpha ? 0 : 255; int alpha_min = config_alpha ? 0 : 255;
@ -122,14 +115,18 @@ class Window_content : public Scout::Element
~Fb_texture() ~Fb_texture()
{ {
Genode::env()->heap()->free(alpha, w*h); alloc.free(alpha, w*h);
} }
}; };
Genode::Ram_session &_ram;
Genode::Region_map &_rm;
Genode::Allocator &_alloc;
bool _config_alpha; bool _config_alpha;
Content_event_handler _ev_handler; Content_event_handler _ev_handler;
Fb_texture *_fb;
Genode::Reconstructible<Fb_texture> _fb;
/** /**
* Size of the framebuffer handed out by the next call of 'dataspace' * Size of the framebuffer handed out by the next call of 'dataspace'
@ -152,13 +149,15 @@ class Window_content : public Scout::Element
public: public:
Window_content(unsigned fb_w, unsigned fb_h, Window_content(Genode::Ram_session &ram, Genode::Region_map &rm,
Genode::Allocator &alloc, unsigned fb_w, unsigned fb_h,
Input::Session_component &input_session, Input::Session_component &input_session,
bool config_alpha) bool config_alpha)
: :
_ram(ram), _rm(rm), _alloc(alloc),
_config_alpha(config_alpha), _config_alpha(config_alpha),
_ev_handler(input_session, this), _ev_handler(input_session, this),
_fb(new (Genode::env()->heap()) Fb_texture(fb_w, fb_h, _config_alpha)), _fb(_ram, _rm, _alloc, fb_w, fb_h, _config_alpha),
_next_size(fb_w, fb_h), _next_size(fb_w, fb_h),
_designated_size(_next_size) _designated_size(_next_size)
{ {
@ -189,10 +188,7 @@ class Window_content : public Scout::Element
if (_next_size.w() == _fb->w && _next_size.h() == _fb->h) if (_next_size.w() == _fb->w && _next_size.h() == _fb->h)
return; return;
Genode::destroy(Genode::env()->heap(), _fb); _fb.construct(_ram, _rm, _alloc, _next_size.w(), _next_size.h(), _config_alpha);
_fb = new (Genode::env()->heap())
Fb_texture(_next_size.w(), _next_size.h(), _config_alpha);
} }
/** /**
@ -235,8 +231,8 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
public: public:
Session_component(Window_content &window_content) Session_component(Genode::Env &env, Window_content &window_content)
: _window_content(window_content) { } : _timer(env), _window_content(window_content) { }
Genode::Dataspace_capability dataspace() override Genode::Dataspace_capability dataspace() override
{ {
@ -266,26 +262,30 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
}; };
void init_window_content(unsigned fb_w, unsigned fb_h, bool config_alpha) void init_window_content(Genode::Ram_session &ram, Genode::Region_map &rm,
Genode::Allocator &alloc,
Input::Session_component &input_component,
unsigned fb_w, unsigned fb_h, bool config_alpha)
{ {
static Window_content content(fb_w, fb_h, input_session(), config_alpha); static Window_content content(ram, rm, alloc, fb_w, fb_h,
input_component, config_alpha);
_window_content = &content; _window_content = &content;
} }
void init_services(Genode::Rpc_entrypoint &ep) void init_services(Genode::Env &env, Input::Session_component &input_component)
{ {
using namespace Genode; using namespace Genode;
static Framebuffer::Session_component fb_session(*_window_content); static Framebuffer::Session_component fb_session(env, *_window_content);
static Static_root<Framebuffer::Session> fb_root(ep.manage(&fb_session)); static Static_root<Framebuffer::Session> fb_root(env.ep().manage(fb_session));
static Input::Root_component input_root(ep, input_session()); static Input::Root_component input_root(env.ep().rpc_ep(), input_component);
/* /*
* Now, the root interfaces are ready to accept requests. * Now, the root interfaces are ready to accept requests.
* This is the right time to tell mummy about our services. * This is the right time to tell mummy about our services.
*/ */
env()->parent()->announce(ep.manage(&fb_root)); env.parent().announce(env.ep().manage(fb_root));
env()->parent()->announce(ep.manage(&input_root)); env.parent().announce(env.ep().manage(input_root));
} }

View File

@ -14,14 +14,17 @@
#ifndef _SERVICES_H_ #ifndef _SERVICES_H_
#define _SERVICES_H_ #define _SERVICES_H_
#include <base/rpc_server.h> #include <base/component.h>
#include <base/allocator.h>
#include <scout/canvas.h> #include <scout/canvas.h>
#include "elements.h" #include "elements.h"
extern Scout::Element *window_content(); extern Scout::Element *window_content();
extern void init_window_content(unsigned fb_w, unsigned fb_h, bool config_alpha); extern void init_window_content(Genode::Ram_session &, Genode::Region_map &,
extern void init_services(Genode::Rpc_entrypoint &ep); Genode::Allocator &, Input::Session_component &,
unsigned fb_w, unsigned fb_h, bool config_alpha);
extern void init_services(Genode::Env &, Input::Session_component &);
extern void lock_window_content(); extern void lock_window_content();
extern void unlock_window_content(); extern void unlock_window_content();

View File

@ -12,14 +12,11 @@
*/ */
#include <util/arg_string.h> #include <util/arg_string.h>
#include <base/env.h> #include <base/component.h>
#include <base/sleep.h>
#include <base/lock.h>
#include <base/heap.h> #include <base/heap.h>
#include <base/snprintf.h>
#include <base/rpc_server.h> #include <base/rpc_server.h>
#include <base/session_label.h>
#include <root/component.h> #include <root/component.h>
#include <cap_session/connection.h>
#include <log_session/log_session.h> #include <log_session/log_session.h>
#include <nitpicker_session/connection.h> #include <nitpicker_session/connection.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
@ -50,6 +47,18 @@ extern char _binary_mono_tff_start;
Font default_font(&_binary_mono_tff_start); Font default_font(&_binary_mono_tff_start);
namespace Nitlog {
class Session_component;
class Root;
struct Main;
using namespace Genode;
}
/** /**
* Pixel-type-independent interface to graphics backend * Pixel-type-independent interface to graphics backend
*/ */
@ -248,81 +257,82 @@ class Log_window
}; };
class Log_session_component : public Genode::Rpc_object<Genode::Log_session> class Nitlog::Session_component : public Rpc_object<Log_session>
{ {
public:
enum { LABEL_LEN = 64 };
private: private:
Genode::Color _color; Log_window &_log_window;
Log_window *_log_window;
char _label[LABEL_LEN]; Session_label const _label;
int _id;
int const _id;
static int _bit(int v, int bit_num) { return (v >> bit_num) & 1; } static int _bit(int v, int bit_num) { return (v >> bit_num) & 1; }
/**
* Compute session color
*/
static Color _session_color(int id)
{
int const scale = 32;
int const offset = 64;
int r = (_bit(id, 3) + 2*_bit(id, 0))*scale + offset;
int g = (_bit(id, 4) + 2*_bit(id, 1))*scale + offset;
int b = (_bit(id, 5) + 2*_bit(id, 2))*scale + offset;
return Color(r, g, b);
}
Color const _color = _session_color(_id);
public: public:
/** /**
* Constructor * Constructor
*/ */
Log_session_component(const char *label, Log_window *log_window) Session_component(Session_label const &label,
: _color(0, 0, 0), _log_window(log_window) Log_window &log_window, int &cnt)
{ :
static int cnt; _log_window(log_window), _label(label), _id(cnt++)
{ }
_id = cnt++;
const int scale = 32;
const int offset = 64;
/* compute session color */
int r = (_bit(_id, 3) + 2*_bit(_id, 0))*scale + offset;
int g = (_bit(_id, 4) + 2*_bit(_id, 1))*scale + offset;
int b = (_bit(_id, 5) + 2*_bit(_id, 2))*scale + offset;
_color = Genode::Color(r, g, b);
Genode::strncpy(_label, label, sizeof(_label));
}
/*************************** /***************************
** Log session interface ** ** Log session interface **
***************************/ ***************************/
Genode::size_t write(String const &log_text) size_t write(String const &log_text)
{ {
if (!log_text.valid_string()) { if (!log_text.valid_string()) {
Genode::error("corrupted string"); error("corrupted string");
return 0; return 0;
} }
_log_window->write(_color, _label, log_text.string(), _id); _log_window.write(_color, _label.string(), log_text.string(), _id);
return Genode::strlen(log_text.string()); return strlen(log_text.string());
} }
}; };
class Log_root_component : public Genode::Root_component<Log_session_component> class Nitlog::Root : public Root_component<Session_component>
{ {
private: private:
Log_window *_log_window; Log_window &_log_window;
/* session counter, used as a key to generate session colors */
int _session_cnt = 0;
protected: protected:
Log_session_component *_create_session(const char *args) Session_component *_create_session(const char *args)
{ {
Genode::log("create log session args: ", args); log("create log session args: ", args);
char label_buf[Log_session_component::LABEL_LEN];
Genode::Arg label_arg = Genode::Arg_string::find_arg(args, "label"); return new (md_alloc())
label_arg.string(label_buf, sizeof(label_buf), ""); Session_component(label_from_args(args),
_log_window, _session_cnt);
return new (md_alloc()) Log_session_component(label_buf, _log_window);
} }
public: public:
@ -330,12 +340,11 @@ class Log_root_component : public Genode::Root_component<Log_session_component>
/** /**
* Constructor * Constructor
*/ */
Log_root_component(Genode::Rpc_entrypoint *ep, Root(Entrypoint &ep, Allocator &md_alloc, Log_window &log_window)
Genode::Allocator *md_alloc,
Log_window *log_window)
: :
Genode::Root_component<Log_session_component>(ep, md_alloc), Root_component<Session_component>(ep, md_alloc),
_log_window(log_window) { } _log_window(log_window)
{ }
}; };
@ -382,91 +391,109 @@ class Log_view
}; };
int main(int argc, char **argv) struct Nitlog::Main
{ {
using namespace Genode; Env &_env;
/* make sure that we connect to LOG before providing this service by ourself */
log("--- nitlog ---");
/* calculate size of log view in pixels */ /* calculate size of log view in pixels */
int log_win_w = default_font.str_w(" ") * LOG_W + 2; unsigned const _win_w = default_font.str_w(" ") * LOG_W + 2;
int log_win_h = default_font.str_h(" ") * LOG_H + 2; unsigned const _win_h = default_font.str_h(" ") * LOG_H + 2;
/* init sessions to the required external services */ /* init sessions to the required external services */
static Nitpicker::Connection nitpicker; Nitpicker::Connection _nitpicker { _env };
static Timer::Connection timer; Timer::Connection _timer { _env };
nitpicker.buffer(Framebuffer::Mode(log_win_w, log_win_h, void _init_nitpicker_buffer()
{
_nitpicker.buffer(Framebuffer::Mode(_win_w, _win_h,
Framebuffer::Mode::RGB565), false); Framebuffer::Mode::RGB565), false);
}
/* initialize entry point that serves the root interface */ bool const _nitpicker_buffer_initialized = (_init_nitpicker_buffer(), true);
enum { STACK_SIZE = 4096*sizeof(long) };
static Cap_connection cap;
static Rpc_entrypoint ep(&cap, STACK_SIZE, "nitlog_ep");
/* Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
* Use sliced heap to allocate each session component at a separate
* dataspace.
*/
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
/* create log window */ /* create log window */
void *addr = env()->rm_session()->attach(nitpicker.framebuffer()->dataspace()); Attached_dataspace _fb_ds { _env.rm(), _nitpicker.framebuffer()->dataspace() };
static Canvas<Pixel_rgb565> canvas((Pixel_rgb565 *)addr, Canvas<Pixel_rgb565> _canvas { _fb_ds.local_addr<Pixel_rgb565>(),
::Area(log_win_w, log_win_h)); ::Area(_win_w, _win_h) };
static Log_window log_window(canvas);
Log_window _log_window { _canvas };
void _init_canvas()
{
/* /*
* We clip a border of one pixel off the canvas. This way, the * We clip a border of one pixel off the canvas. This way, the
* border remains unaffected by the drawing operations and * border remains unaffected by the drawing operations and
* acts as an outline for the log window. * acts as an outline for the log window.
*/ */
canvas.clip(::Rect(::Point(1, 1), ::Area(log_win_w - 2, log_win_h - 2))); _canvas.clip(::Rect(::Point(1, 1), ::Area(_win_w - 2, _win_h - 2)));
}
bool const _canvas_initialized = (_init_canvas(), true);
/* create view for log window */ /* create view for log window */
Nitpicker::Rect log_view_geometry(Nitpicker::Point(20, 20), Nitpicker::Rect const _view_geometry { Nitpicker::Point(20, 20),
Nitpicker::Area(log_win_w, log_win_h)); Nitpicker::Area(_win_w, _win_h) };
Log_view log_view(nitpicker, log_view_geometry); Log_view _view { _nitpicker, _view_geometry };
/* create root interface for service */ /* create root interface for service */
static Log_root_component log_root(&ep, &sliced_heap, &log_window); Root _root { _env.ep(), _sliced_heap, _log_window };
/* announce service at our parent */ Attached_dataspace _ev_ds { _env.rm(), _nitpicker.input()->dataspace() };
env()->parent()->announce(ep.manage(&log_root));
/* handle input events */ Nitpicker::Point _old_mouse_pos;
Input::Event *ev_buf = env()->rm_session()->attach(nitpicker.input()->dataspace()); unsigned _key_cnt = 0;
Nitpicker::Point old_mouse_pos;
unsigned key_cnt = 0;
while (1) {
while (!nitpicker.input()->pending()) { Signal_handler<Main> _input_handler {
if (log_window.draw()) _env.ep(), *this, &Main::_handle_input };
nitpicker.framebuffer()->refresh(0, 0, log_win_w, log_win_h);
timer.msleep(20);
}
for (int i = 0, num_ev = nitpicker.input()->flush(); i < num_ev; i++) { void _handle_input()
{
Input::Event const *ev_buf = _ev_ds.local_addr<Input::Event const>();
Input::Event *ev = &ev_buf[i]; for (int i = 0, num_ev = _nitpicker.input()->flush(); i < num_ev; i++) {
if (ev->type() == Input::Event::PRESS) key_cnt++; Input::Event const &ev = ev_buf[i];
if (ev->type() == Input::Event::RELEASE) key_cnt--;
Nitpicker::Point mouse_pos(ev->ax(), ev->ay()); if (ev.type() == Input::Event::PRESS) _key_cnt++;
if (ev.type() == Input::Event::RELEASE) _key_cnt--;
Nitpicker::Point mouse_pos(ev.ax(), ev.ay());
/* move view */ /* move view */
if (ev->type() == Input::Event::MOTION && key_cnt > 0) if (ev.type() == Input::Event::MOTION && _key_cnt > 0)
log_view.move(log_view.pos() + mouse_pos - old_mouse_pos); _view.move(_view.pos() + mouse_pos - _old_mouse_pos);
/* find selected view and bring it to front */ /* find selected view and bring it to front */
if (ev->type() == Input::Event::PRESS && key_cnt == 1) if (ev.type() == Input::Event::PRESS && _key_cnt == 1)
log_view.top(); _view.top();
old_mouse_pos = mouse_pos; _old_mouse_pos = mouse_pos;
} }
} }
return 0;
Signal_handler<Main> _timer_handler {
_env.ep(), *this, &Main::_handle_timer };
void _handle_timer()
{
if (_log_window.draw())
_nitpicker.framebuffer()->refresh(0, 0, _win_w, _win_h);
} }
Main(Env &env) : _env(env)
{
/* announce service at our parent */
_env.parent().announce(_env.ep().manage(_root));
_timer.sigh(_timer_handler);
_timer.trigger_periodic(20*1000);
_nitpicker.input()->sigh(_input_handler);
}
};
void Component::construct(Genode::Env &env) { static Nitlog::Main main(env); }