mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 23:28:29 +00:00
@ -12,8 +12,10 @@
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <input/component.h>
|
||||
#include <scout/user_state.h>
|
||||
#include <scout/nitpicker_graphics_backend.h>
|
||||
|
||||
@ -21,16 +23,9 @@
|
||||
#include "services.h"
|
||||
|
||||
|
||||
/**
|
||||
* Runtime configuration
|
||||
*/
|
||||
namespace Scout { namespace Config
|
||||
{
|
||||
int iconbar_detail = 1;
|
||||
int background_detail = 1;
|
||||
int mouse_cursor = 1;
|
||||
int browser_attr = 0;
|
||||
} }
|
||||
static Genode::Allocator *_alloc_ptr;
|
||||
|
||||
void *operator new (__SIZE_TYPE__ n) { return _alloc_ptr->alloc(n); }
|
||||
|
||||
|
||||
void Scout::Launcher::launch() { }
|
||||
@ -40,27 +35,26 @@ class Background_animator : public Scout::Tick
|
||||
{
|
||||
private:
|
||||
|
||||
Framebuffer_window<Scout::Pixel_rgb565> *_fb_win;
|
||||
Framebuffer_window<Scout::Pixel_rgb565> &_fb_win;
|
||||
|
||||
int _bg_offset;
|
||||
int _bg_offset = 0;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Background_animator(Framebuffer_window<Scout::Pixel_rgb565> *fb_win):
|
||||
_fb_win(fb_win), _bg_offset(0) {
|
||||
schedule(20); }
|
||||
Background_animator(Framebuffer_window<Scout::Pixel_rgb565> &fb_win)
|
||||
: _fb_win(fb_win) { schedule(20); }
|
||||
|
||||
/**
|
||||
* Tick interface
|
||||
*/
|
||||
int on_tick()
|
||||
{
|
||||
_fb_win->bg_offset(_bg_offset);
|
||||
_fb_win.bg_offset(_bg_offset);
|
||||
_bg_offset += 2;
|
||||
_fb_win->refresh();
|
||||
_fb_win.refresh();
|
||||
|
||||
/* schedule next tick */
|
||||
return 1;
|
||||
@ -77,10 +71,10 @@ static bool config_alpha = true;
|
||||
/**
|
||||
* Size and position of virtual frame buffer
|
||||
*/
|
||||
static long config_fb_width = 500;
|
||||
static long config_fb_height = 400;
|
||||
static long config_fb_x = 400;
|
||||
static long config_fb_y = 260;
|
||||
static unsigned long config_fb_width = 500;
|
||||
static unsigned long config_fb_height = 400;
|
||||
static long config_fb_x = 400;
|
||||
static long config_fb_y = 260;
|
||||
|
||||
/**
|
||||
* Window title
|
||||
@ -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:
|
||||
|
||||
Scout::Platform &_pf;
|
||||
Scout::User_state &_user_state;
|
||||
Framebuffer_window<Genode::Pixel_rgb565> &_fb_win;
|
||||
Genode::Attached_rom_dataspace &_config;
|
||||
unsigned long _curr_time, _old_time;
|
||||
Env &_env;
|
||||
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
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()
|
||||
{
|
||||
@ -204,27 +271,11 @@ class Main : public Scout::Event_handler
|
||||
_user_state.update_view_offset();
|
||||
}
|
||||
|
||||
Genode::Signal_handler<Main> _config_handler;
|
||||
Signal_handler<Main> _config_handler {
|
||||
_env.ep(), *this, &Main::_handle_config };
|
||||
|
||||
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
|
||||
{
|
||||
using Scout::Event;
|
||||
@ -242,70 +293,22 @@ class Main : public Scout::Event_handler
|
||||
_user_state.handle_event(ev);
|
||||
|
||||
if (ev.type == Event::TIMER) {
|
||||
Scout::Tick::handle(_pf.timer_ticks());
|
||||
Scout::Tick::handle(_platform.timer_ticks());
|
||||
}
|
||||
|
||||
/* perform periodic redraw */
|
||||
_curr_time = _pf.timer_ticks();
|
||||
_curr_time = _platform.timer_ticks();
|
||||
if ((_curr_time - _old_time > 20) || (_curr_time < _old_time)) {
|
||||
_old_time = _curr_time;
|
||||
_fb_win.process_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
_config.sigh(_config_handler);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***************
|
||||
** 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);
|
||||
}
|
||||
void Component::construct(Genode::Env &env) { static Liquid_fb::Main main(env); }
|
||||
|
@ -29,16 +29,6 @@
|
||||
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
|
||||
{
|
||||
private:
|
||||
@ -88,18 +78,21 @@ class Window_content : public Scout::Element
|
||||
|
||||
struct Fb_texture
|
||||
{
|
||||
Genode::Allocator &alloc;
|
||||
unsigned w, h;
|
||||
Genode::Attached_ram_dataspace ds;
|
||||
Genode::Pixel_rgb565 *pixel;
|
||||
unsigned char *alpha;
|
||||
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),
|
||||
ds(Genode::env()->ram_session(), w*h*sizeof(Genode::Pixel_rgb565)),
|
||||
alloc(alloc), w(w), h(h),
|
||||
ds(ram, local_rm, w*h*sizeof(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))
|
||||
{
|
||||
int alpha_min = config_alpha ? 0 : 255;
|
||||
@ -122,14 +115,18 @@ class Window_content : public Scout::Element
|
||||
|
||||
~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;
|
||||
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'
|
||||
@ -152,13 +149,15 @@ class Window_content : public Scout::Element
|
||||
|
||||
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,
|
||||
bool config_alpha)
|
||||
:
|
||||
_ram(ram), _rm(rm), _alloc(alloc),
|
||||
_config_alpha(config_alpha),
|
||||
_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),
|
||||
_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)
|
||||
return;
|
||||
|
||||
Genode::destroy(Genode::env()->heap(), _fb);
|
||||
|
||||
_fb = new (Genode::env()->heap())
|
||||
Fb_texture(_next_size.w(), _next_size.h(), _config_alpha);
|
||||
_fb.construct(_ram, _rm, _alloc, _next_size.w(), _next_size.h(), _config_alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,8 +231,8 @@ class Framebuffer::Session_component : public Genode::Rpc_object<Session>
|
||||
|
||||
public:
|
||||
|
||||
Session_component(Window_content &window_content)
|
||||
: _window_content(window_content) { }
|
||||
Session_component(Genode::Env &env, Window_content &window_content)
|
||||
: _timer(env), _window_content(window_content) { }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void init_services(Genode::Rpc_entrypoint &ep)
|
||||
void init_services(Genode::Env &env, Input::Session_component &input_component)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
static Framebuffer::Session_component fb_session(*_window_content);
|
||||
static Static_root<Framebuffer::Session> fb_root(ep.manage(&fb_session));
|
||||
static Framebuffer::Session_component fb_session(env, *_window_content);
|
||||
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.
|
||||
* This is the right time to tell mummy about our services.
|
||||
*/
|
||||
env()->parent()->announce(ep.manage(&fb_root));
|
||||
env()->parent()->announce(ep.manage(&input_root));
|
||||
env.parent().announce(env.ep().manage(fb_root));
|
||||
env.parent().announce(env.ep().manage(input_root));
|
||||
}
|
||||
|
@ -14,14 +14,17 @@
|
||||
#ifndef _SERVICES_H_
|
||||
#define _SERVICES_H_
|
||||
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/component.h>
|
||||
#include <base/allocator.h>
|
||||
#include <scout/canvas.h>
|
||||
|
||||
#include "elements.h"
|
||||
|
||||
extern Scout::Element *window_content();
|
||||
extern void init_window_content(unsigned fb_w, unsigned fb_h, bool config_alpha);
|
||||
extern void init_services(Genode::Rpc_entrypoint &ep);
|
||||
extern void init_window_content(Genode::Ram_session &, Genode::Region_map &,
|
||||
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 unlock_window_content();
|
||||
|
||||
|
@ -12,14 +12,11 @@
|
||||
*/
|
||||
|
||||
#include <util/arg_string.h>
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/lock.h>
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/session_label.h>
|
||||
#include <root/component.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <log_session/log_session.h>
|
||||
#include <nitpicker_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);
|
||||
|
||||
|
||||
namespace Nitlog {
|
||||
|
||||
class Session_component;
|
||||
class Root;
|
||||
struct Main;
|
||||
|
||||
using namespace Genode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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:
|
||||
|
||||
Genode::Color _color;
|
||||
Log_window *_log_window;
|
||||
char _label[LABEL_LEN];
|
||||
int _id;
|
||||
Log_window &_log_window;
|
||||
|
||||
Session_label const _label;
|
||||
|
||||
int const _id;
|
||||
|
||||
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:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Log_session_component(const char *label, Log_window *log_window)
|
||||
: _color(0, 0, 0), _log_window(log_window)
|
||||
{
|
||||
static int 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));
|
||||
}
|
||||
Session_component(Session_label const &label,
|
||||
Log_window &log_window, int &cnt)
|
||||
:
|
||||
_log_window(log_window), _label(label), _id(cnt++)
|
||||
{ }
|
||||
|
||||
|
||||
/***************************
|
||||
** Log session interface **
|
||||
***************************/
|
||||
|
||||
Genode::size_t write(String const &log_text)
|
||||
size_t write(String const &log_text)
|
||||
{
|
||||
if (!log_text.valid_string()) {
|
||||
Genode::error("corrupted string");
|
||||
error("corrupted string");
|
||||
return 0;
|
||||
}
|
||||
|
||||
_log_window->write(_color, _label, log_text.string(), _id);
|
||||
return Genode::strlen(log_text.string());
|
||||
_log_window.write(_color, _label.string(), log_text.string(), _id);
|
||||
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:
|
||||
|
||||
Log_window *_log_window;
|
||||
Log_window &_log_window;
|
||||
|
||||
/* session counter, used as a key to generate session colors */
|
||||
int _session_cnt = 0;
|
||||
|
||||
protected:
|
||||
|
||||
Log_session_component *_create_session(const char *args)
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
Genode::log("create log session args: ", args);
|
||||
char label_buf[Log_session_component::LABEL_LEN];
|
||||
log("create log session args: ", args);
|
||||
|
||||
Genode::Arg label_arg = Genode::Arg_string::find_arg(args, "label");
|
||||
label_arg.string(label_buf, sizeof(label_buf), "");
|
||||
|
||||
return new (md_alloc()) Log_session_component(label_buf, _log_window);
|
||||
return new (md_alloc())
|
||||
Session_component(label_from_args(args),
|
||||
_log_window, _session_cnt);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -330,12 +340,11 @@ class Log_root_component : public Genode::Root_component<Log_session_component>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Log_root_component(Genode::Rpc_entrypoint *ep,
|
||||
Genode::Allocator *md_alloc,
|
||||
Log_window *log_window)
|
||||
Root(Entrypoint &ep, Allocator &md_alloc, Log_window &log_window)
|
||||
:
|
||||
Genode::Root_component<Log_session_component>(ep, md_alloc),
|
||||
_log_window(log_window) { }
|
||||
Root_component<Session_component>(ep, md_alloc),
|
||||
_log_window(log_window)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@ -382,91 +391,109 @@ class Log_view
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
struct Nitlog::Main
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/* make sure that we connect to LOG before providing this service by ourself */
|
||||
log("--- nitlog ---");
|
||||
Env &_env;
|
||||
|
||||
/* calculate size of log view in pixels */
|
||||
int log_win_w = default_font.str_w(" ") * LOG_W + 2;
|
||||
int log_win_h = default_font.str_h(" ") * LOG_H + 2;
|
||||
unsigned const _win_w = default_font.str_w(" ") * LOG_W + 2;
|
||||
unsigned const _win_h = default_font.str_h(" ") * LOG_H + 2;
|
||||
|
||||
/* init sessions to the required external services */
|
||||
static Nitpicker::Connection nitpicker;
|
||||
static Timer::Connection timer;
|
||||
Nitpicker::Connection _nitpicker { _env };
|
||||
Timer::Connection _timer { _env };
|
||||
|
||||
nitpicker.buffer(Framebuffer::Mode(log_win_w, log_win_h,
|
||||
Framebuffer::Mode::RGB565), false);
|
||||
void _init_nitpicker_buffer()
|
||||
{
|
||||
_nitpicker.buffer(Framebuffer::Mode(_win_w, _win_h,
|
||||
Framebuffer::Mode::RGB565), false);
|
||||
}
|
||||
|
||||
/* initialize entry point that serves the root interface */
|
||||
enum { STACK_SIZE = 4096*sizeof(long) };
|
||||
static Cap_connection cap;
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "nitlog_ep");
|
||||
bool const _nitpicker_buffer_initialized = (_init_nitpicker_buffer(), true);
|
||||
|
||||
/*
|
||||
* Use sliced heap to allocate each session component at a separate
|
||||
* dataspace.
|
||||
*/
|
||||
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
|
||||
Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
|
||||
|
||||
/* 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,
|
||||
::Area(log_win_w, log_win_h));
|
||||
static Log_window log_window(canvas);
|
||||
Canvas<Pixel_rgb565> _canvas { _fb_ds.local_addr<Pixel_rgb565>(),
|
||||
::Area(_win_w, _win_h) };
|
||||
|
||||
/*
|
||||
* We clip a border of one pixel off the canvas. This way, the
|
||||
* border remains unaffected by the drawing operations and
|
||||
* acts as an outline for the log window.
|
||||
*/
|
||||
canvas.clip(::Rect(::Point(1, 1), ::Area(log_win_w - 2, log_win_h - 2)));
|
||||
Log_window _log_window { _canvas };
|
||||
|
||||
void _init_canvas()
|
||||
{
|
||||
/*
|
||||
* We clip a border of one pixel off the canvas. This way, the
|
||||
* border remains unaffected by the drawing operations and
|
||||
* acts as an outline for the log window.
|
||||
*/
|
||||
_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 */
|
||||
Nitpicker::Rect log_view_geometry(Nitpicker::Point(20, 20),
|
||||
Nitpicker::Area(log_win_w, log_win_h));
|
||||
Log_view log_view(nitpicker, log_view_geometry);
|
||||
Nitpicker::Rect const _view_geometry { Nitpicker::Point(20, 20),
|
||||
Nitpicker::Area(_win_w, _win_h) };
|
||||
Log_view _view { _nitpicker, _view_geometry };
|
||||
|
||||
/* 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 */
|
||||
env()->parent()->announce(ep.manage(&log_root));
|
||||
Attached_dataspace _ev_ds { _env.rm(), _nitpicker.input()->dataspace() };
|
||||
|
||||
/* handle input events */
|
||||
Input::Event *ev_buf = env()->rm_session()->attach(nitpicker.input()->dataspace());
|
||||
Nitpicker::Point old_mouse_pos;
|
||||
unsigned key_cnt = 0;
|
||||
while (1) {
|
||||
Nitpicker::Point _old_mouse_pos;
|
||||
unsigned _key_cnt = 0;
|
||||
|
||||
while (!nitpicker.input()->pending()) {
|
||||
if (log_window.draw())
|
||||
nitpicker.framebuffer()->refresh(0, 0, log_win_w, log_win_h);
|
||||
timer.msleep(20);
|
||||
}
|
||||
Signal_handler<Main> _input_handler {
|
||||
_env.ep(), *this, &Main::_handle_input };
|
||||
|
||||
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++;
|
||||
if (ev->type() == Input::Event::RELEASE) key_cnt--;
|
||||
Input::Event const &ev = ev_buf[i];
|
||||
|
||||
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 */
|
||||
if (ev->type() == Input::Event::MOTION && key_cnt > 0)
|
||||
log_view.move(log_view.pos() + mouse_pos - old_mouse_pos);
|
||||
if (ev.type() == Input::Event::MOTION && _key_cnt > 0)
|
||||
_view.move(_view.pos() + mouse_pos - _old_mouse_pos);
|
||||
|
||||
/* find selected view and bring it to front */
|
||||
if (ev->type() == Input::Event::PRESS && key_cnt == 1)
|
||||
log_view.top();
|
||||
if (ev.type() == Input::Event::PRESS && _key_cnt == 1)
|
||||
_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); }
|
||||
|
Reference in New Issue
Block a user