mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-11 13:22:33 +00:00
parent
eb90d92009
commit
c0f1d99d7a
@ -15,6 +15,7 @@
|
||||
#define _CONFIG_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/volatile_object.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <util/color.h>
|
||||
|
||||
@ -24,8 +25,10 @@
|
||||
namespace Decorator {
|
||||
|
||||
class Config;
|
||||
|
||||
typedef Genode::String<200> Window_title;
|
||||
|
||||
using Genode::Allocator;
|
||||
using Genode::Volatile_object;
|
||||
}
|
||||
|
||||
|
||||
@ -78,8 +81,41 @@ class Decorator::Config
|
||||
|
||||
private:
|
||||
|
||||
struct Buffered_xml
|
||||
{
|
||||
Allocator &_alloc;
|
||||
char const * const _ptr; /* pointer to dynamically allocated buffer */
|
||||
Xml_node const _xml; /* referring to buffer of '_ptr' */
|
||||
|
||||
/**
|
||||
* \throw Allocator::Out_of_memory
|
||||
*/
|
||||
static char const *_init_ptr(Allocator &alloc, Xml_node node)
|
||||
{
|
||||
char *ptr = (char *)alloc.alloc(node.size());
|
||||
Genode::memcpy(ptr, node.addr(), node.size());
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \throw Allocator::Out_of_memory
|
||||
*/
|
||||
Buffered_xml(Allocator &alloc, Xml_node node)
|
||||
:
|
||||
_alloc(alloc), _ptr(_init_ptr(alloc, node)), _xml(_ptr, node.size())
|
||||
{ }
|
||||
|
||||
~Buffered_xml() { _alloc.free(const_cast<char *>(_ptr), _xml.size()); }
|
||||
|
||||
Xml_node xml() const { return _xml; }
|
||||
};
|
||||
|
||||
Genode::Allocator &_alloc;
|
||||
|
||||
Volatile_object<Buffered_xml> _buffered_config;
|
||||
|
||||
/**
|
||||
* Maximum number of configured window controls
|
||||
*/
|
||||
@ -105,7 +141,9 @@ class Decorator::Config
|
||||
|
||||
public:
|
||||
|
||||
Config(Genode::Allocator &alloc) : _alloc(alloc)
|
||||
Config(Genode::Allocator &alloc, Xml_node config)
|
||||
:
|
||||
_alloc(alloc), _buffered_config(_alloc, config)
|
||||
{
|
||||
_reset_window_controls();
|
||||
}
|
||||
@ -153,7 +191,7 @@ class Decorator::Config
|
||||
Color result(68, 75, 95);
|
||||
|
||||
try {
|
||||
Genode::Session_policy policy(title);
|
||||
Genode::Session_policy policy(title, _buffered_config->xml());
|
||||
result = policy.attribute_value("color", result);
|
||||
|
||||
} catch (Genode::Session_policy::No_policy_defined) { }
|
||||
@ -167,10 +205,10 @@ class Decorator::Config
|
||||
int gradient_percent(Window_title const &title) const
|
||||
{
|
||||
unsigned long result =
|
||||
Genode::config()->xml_node().attribute_value("gradient", 32UL);
|
||||
_buffered_config->xml().attribute_value("gradient", 32UL);
|
||||
|
||||
try {
|
||||
Genode::Session_policy policy(title);
|
||||
Genode::Session_policy policy(title, _buffered_config->xml());
|
||||
result = policy.attribute_value("gradient", result);
|
||||
|
||||
} catch (Genode::Session_policy::No_policy_defined) { }
|
||||
@ -181,8 +219,10 @@ class Decorator::Config
|
||||
/**
|
||||
* Update the internally cached configuration state
|
||||
*/
|
||||
void update()
|
||||
void update(Xml_node config)
|
||||
{
|
||||
_buffered_config.construct(_alloc, config);
|
||||
|
||||
_reset_window_controls();
|
||||
|
||||
/*
|
||||
@ -213,8 +253,6 @@ class Decorator::Config
|
||||
new (_alloc) Window_control(type, align);
|
||||
};
|
||||
|
||||
Xml_node config = Genode::config()->xml_node();
|
||||
|
||||
try { config.sub_node("controls").for_each_sub_node(lambda); }
|
||||
catch (Xml_node::Nonexistent_sub_node) { }
|
||||
}
|
||||
|
@ -13,12 +13,12 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/signal.h>
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
#include <os/pixel_rgb565.h>
|
||||
#include <os/attached_rom_dataspace.h>
|
||||
#include <os/reporter.h>
|
||||
#include <os/server.h>
|
||||
|
||||
/* decorator includes */
|
||||
#include <decorator/window_stack.h>
|
||||
@ -37,49 +37,50 @@ namespace Decorator {
|
||||
|
||||
struct Decorator::Main : Window_factory_base
|
||||
{
|
||||
Server::Entrypoint &ep;
|
||||
Env &_env;
|
||||
|
||||
Nitpicker::Connection nitpicker;
|
||||
Nitpicker::Connection _nitpicker { _env };
|
||||
|
||||
Framebuffer::Mode mode = { nitpicker.mode() };
|
||||
Framebuffer::Mode _mode = { _nitpicker.mode() };
|
||||
|
||||
Attached_dataspace fb_ds = { (nitpicker.buffer(mode, false),
|
||||
nitpicker.framebuffer()->dataspace()) };
|
||||
Attached_dataspace _fb_ds = { _env.rm(),
|
||||
(_nitpicker.buffer(_mode, false),
|
||||
_nitpicker.framebuffer()->dataspace()) };
|
||||
|
||||
Canvas<Pixel_rgb565> canvas = { fb_ds.local_addr<Pixel_rgb565>(),
|
||||
Area(mode.width(), mode.height()) };
|
||||
Canvas<Pixel_rgb565> _canvas = { _fb_ds.local_addr<Pixel_rgb565>(),
|
||||
Area(_mode.width(), _mode.height()) };
|
||||
|
||||
Window_stack window_stack = { *this };
|
||||
Window_stack _window_stack = { *this };
|
||||
|
||||
/**
|
||||
* Install handler for responding to window-layout changes
|
||||
* Handler for responding to window-layout changes
|
||||
*/
|
||||
void handle_window_layout_update(unsigned);
|
||||
void _handle_window_layout_update();
|
||||
|
||||
Signal_rpc_member<Main> window_layout_dispatcher = {
|
||||
ep, *this, &Main::handle_window_layout_update };
|
||||
Signal_handler<Main> _window_layout_handler = {
|
||||
_env.ep(), *this, &Main::_handle_window_layout_update };
|
||||
|
||||
Attached_rom_dataspace window_layout { "window_layout" };
|
||||
Attached_rom_dataspace _window_layout { _env, "window_layout" };
|
||||
|
||||
/**
|
||||
* Install handler for responding to pointer-position updates
|
||||
* Handler for responding to pointer-position updates
|
||||
*/
|
||||
void handle_pointer_update(unsigned);
|
||||
void _handle_pointer_update();
|
||||
|
||||
Signal_rpc_member<Main> pointer_dispatcher = {
|
||||
ep, *this, &Main::handle_pointer_update };
|
||||
Signal_handler<Main> _pointer_handler = {
|
||||
_env.ep(), *this, &Main::_handle_pointer_update };
|
||||
|
||||
Attached_rom_dataspace pointer { "pointer" };
|
||||
Attached_rom_dataspace _pointer { _env, "pointer" };
|
||||
|
||||
Window_base::Hover hover;
|
||||
Window_base::Hover _hover;
|
||||
|
||||
Reporter hover_reporter = { "hover" };
|
||||
Reporter _hover_reporter = { "hover" };
|
||||
|
||||
bool window_layout_update_needed = false;
|
||||
bool _window_layout_update_needed = false;
|
||||
|
||||
Reporter decorator_margins_reporter = { "decorator_margins" };
|
||||
Reporter _decorator_margins_reporter = { "decorator_margins" };
|
||||
|
||||
Animator animator;
|
||||
Animator _animator;
|
||||
|
||||
/**
|
||||
* Process the update every 'frame_period' nitpicker sync signals. The
|
||||
@ -92,42 +93,46 @@ struct Decorator::Main : Window_factory_base
|
||||
* 'frame_period' of 2 results in an update rate of 1000/20 = 50 frames per
|
||||
* second.
|
||||
*/
|
||||
unsigned frame_cnt = 0;
|
||||
unsigned frame_period = 2;
|
||||
unsigned _frame_cnt = 0;
|
||||
unsigned _frame_period = 2;
|
||||
|
||||
/**
|
||||
* Install handler for responding to nitpicker sync events
|
||||
*/
|
||||
void handle_nitpicker_sync(unsigned);
|
||||
void _handle_nitpicker_sync();
|
||||
|
||||
Signal_rpc_member<Main> nitpicker_sync_dispatcher = {
|
||||
ep, *this, &Main::handle_nitpicker_sync };
|
||||
Signal_handler<Main> _nitpicker_sync_handler = {
|
||||
_env.ep(), *this, &Main::_handle_nitpicker_sync };
|
||||
|
||||
Config config { *Genode::env()->heap() };
|
||||
Heap _heap { _env.ram(), _env.rm() };
|
||||
|
||||
void handle_config(unsigned);
|
||||
Attached_rom_dataspace _config { _env, "config" };
|
||||
|
||||
Signal_rpc_member<Main> config_dispatcher = {
|
||||
ep, *this, &Main::handle_config};
|
||||
void _handle_config();
|
||||
|
||||
Signal_handler<Main> _config_handler = {
|
||||
_env.ep(), *this, &Main::_handle_config};
|
||||
|
||||
Config _decorator_config { _heap, _config.xml() };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Main(Server::Entrypoint &ep) : ep(ep)
|
||||
Main(Env &env) : _env(env)
|
||||
{
|
||||
Genode::config()->sigh(config_dispatcher);
|
||||
handle_config(0);
|
||||
_config.sigh(_config_handler);
|
||||
_handle_config();
|
||||
|
||||
window_layout.sigh(window_layout_dispatcher);
|
||||
pointer.sigh(pointer_dispatcher);
|
||||
_window_layout.sigh(_window_layout_handler);
|
||||
_pointer.sigh(_pointer_handler);
|
||||
|
||||
nitpicker.framebuffer()->sync_sigh(nitpicker_sync_dispatcher);
|
||||
_nitpicker.framebuffer()->sync_sigh(_nitpicker_sync_handler);
|
||||
|
||||
hover_reporter.enabled(true);
|
||||
_hover_reporter.enabled(true);
|
||||
|
||||
decorator_margins_reporter.enabled(true);
|
||||
_decorator_margins_reporter.enabled(true);
|
||||
|
||||
Genode::Reporter::Xml_generator xml(decorator_margins_reporter, [&] ()
|
||||
Genode::Reporter::Xml_generator xml(_decorator_margins_reporter, [&] ()
|
||||
{
|
||||
xml.node("floating", [&] () {
|
||||
|
||||
@ -141,8 +146,8 @@ struct Decorator::Main : Window_factory_base
|
||||
});
|
||||
|
||||
/* import initial state */
|
||||
handle_pointer_update(0);
|
||||
handle_window_layout_update(0);
|
||||
_handle_pointer_update();
|
||||
_handle_window_layout_update();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,14 +157,15 @@ struct Decorator::Main : Window_factory_base
|
||||
{
|
||||
for (unsigned retry = 0 ; retry < 2; retry ++) {
|
||||
try {
|
||||
return new (env()->heap())
|
||||
Window(attribute(window_node, "id", 0UL), nitpicker, animator, config);
|
||||
return new (_heap)
|
||||
Window(attribute(window_node, "id", 0UL), _nitpicker,
|
||||
_animator, _decorator_config);
|
||||
} catch (Nitpicker::Session::Out_of_metadata) {
|
||||
Genode::log("Handle Out_of_metadata of nitpicker session - upgrade by 8K");
|
||||
nitpicker.upgrade_ram(8192);
|
||||
_nitpicker.upgrade_ram(8192);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,23 +173,23 @@ struct Decorator::Main : Window_factory_base
|
||||
*/
|
||||
void destroy(Window_base *window) override
|
||||
{
|
||||
Genode::destroy(env()->heap(), static_cast<Window *>(window));
|
||||
Genode::destroy(_heap, static_cast<Window *>(window));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Decorator::Main::handle_config(unsigned)
|
||||
void Decorator::Main::_handle_config()
|
||||
{
|
||||
Genode::config()->reload();
|
||||
_config.update();
|
||||
|
||||
config.update();
|
||||
_decorator_config.update(_config.xml());
|
||||
|
||||
/* notify all windows to consider the updated policy */
|
||||
window_stack.for_each_window([&] (Window_base &window) {
|
||||
_window_stack.for_each_window([&] (Window_base &window) {
|
||||
static_cast<Window &>(window).adapt_to_changed_config(); });
|
||||
|
||||
/* trigger redraw of the window stack */
|
||||
handle_window_layout_update(0);
|
||||
_handle_window_layout_update();
|
||||
}
|
||||
|
||||
|
||||
@ -235,29 +241,29 @@ static void update_hover_report(Genode::Xml_node pointer_node,
|
||||
}
|
||||
|
||||
|
||||
void Decorator::Main::handle_window_layout_update(unsigned)
|
||||
void Decorator::Main::_handle_window_layout_update()
|
||||
{
|
||||
window_layout.update();
|
||||
_window_layout.update();
|
||||
|
||||
window_layout_update_needed = true;
|
||||
_window_layout_update_needed = true;
|
||||
}
|
||||
|
||||
|
||||
void Decorator::Main::handle_nitpicker_sync(unsigned)
|
||||
void Decorator::Main::_handle_nitpicker_sync()
|
||||
{
|
||||
if (frame_cnt++ < frame_period)
|
||||
if (_frame_cnt++ < _frame_period)
|
||||
return;
|
||||
|
||||
frame_cnt = 0;
|
||||
_frame_cnt = 0;
|
||||
|
||||
bool model_updated = false;
|
||||
|
||||
if (window_layout_update_needed && window_layout.valid()) {
|
||||
if (_window_layout_update_needed && _window_layout.valid()) {
|
||||
|
||||
try {
|
||||
Xml_node xml(window_layout.local_addr<char>(),
|
||||
window_layout.size());
|
||||
window_stack.update_model(xml);
|
||||
Xml_node xml(_window_layout.local_addr<char>(),
|
||||
_window_layout.size());
|
||||
_window_stack.update_model(xml);
|
||||
|
||||
model_updated = true;
|
||||
|
||||
@ -265,9 +271,9 @@ void Decorator::Main::handle_nitpicker_sync(unsigned)
|
||||
* A decorator element might have appeared or disappeared under
|
||||
* the pointer.
|
||||
*/
|
||||
if (pointer.valid())
|
||||
update_hover_report(Xml_node(pointer.local_addr<char>()),
|
||||
window_stack, hover, hover_reporter);
|
||||
if (_pointer.valid())
|
||||
update_hover_report(Xml_node(_pointer.local_addr<char>()),
|
||||
_window_stack, _hover, _hover_reporter);
|
||||
|
||||
} catch (Xml_node::Invalid_syntax) {
|
||||
|
||||
@ -275,58 +281,44 @@ void Decorator::Main::handle_nitpicker_sync(unsigned)
|
||||
* An error occured with processing the XML model. Flush the
|
||||
* internal representation.
|
||||
*/
|
||||
window_stack.flush();
|
||||
_window_stack.flush();
|
||||
}
|
||||
|
||||
window_layout_update_needed = false;
|
||||
_window_layout_update_needed = false;
|
||||
}
|
||||
|
||||
bool const windows_animated = window_stack.schedule_animated_windows();
|
||||
bool const windows_animated = _window_stack.schedule_animated_windows();
|
||||
|
||||
/*
|
||||
* To make the perceived animation speed independent from the setting of
|
||||
* 'frame_period', we update the animation as often as the nitpicker
|
||||
* sync signal occurs.
|
||||
*/
|
||||
for (unsigned i = 0; i < frame_period; i++)
|
||||
animator.animate();
|
||||
for (unsigned i = 0; i < _frame_period; i++)
|
||||
_animator.animate();
|
||||
|
||||
if (!model_updated && !windows_animated)
|
||||
return;
|
||||
|
||||
Dirty_rect dirty = window_stack.draw(canvas);
|
||||
Dirty_rect dirty = _window_stack.draw(_canvas);
|
||||
|
||||
window_stack.update_nitpicker_views();
|
||||
_window_stack.update_nitpicker_views();
|
||||
|
||||
nitpicker.execute();
|
||||
_nitpicker.execute();
|
||||
|
||||
dirty.flush([&] (Rect const &r) {
|
||||
nitpicker.framebuffer()->refresh(r.x1(), r.y1(), r.w(), r.h()); });
|
||||
_nitpicker.framebuffer()->refresh(r.x1(), r.y1(), r.w(), r.h()); });
|
||||
}
|
||||
|
||||
|
||||
void Decorator::Main::handle_pointer_update(unsigned)
|
||||
void Decorator::Main::_handle_pointer_update()
|
||||
{
|
||||
pointer.update();
|
||||
_pointer.update();
|
||||
|
||||
if (pointer.valid())
|
||||
update_hover_report(Xml_node(pointer.local_addr<char>()),
|
||||
window_stack, hover, hover_reporter);
|
||||
if (_pointer.valid())
|
||||
update_hover_report(Xml_node(_pointer.local_addr<char>()),
|
||||
_window_stack, _hover, _hover_reporter);
|
||||
}
|
||||
|
||||
|
||||
/************
|
||||
** Server **
|
||||
************/
|
||||
|
||||
namespace Server {
|
||||
|
||||
char const *name() { return "decorator_ep"; }
|
||||
|
||||
size_t stack_size() { return 8*1024*sizeof(long); }
|
||||
|
||||
void construct(Entrypoint &ep)
|
||||
{
|
||||
static Decorator::Main main(ep);
|
||||
}
|
||||
}
|
||||
void Component::construct(Genode::Env &env) { static Decorator::Main main(env); }
|
||||
|
@ -2,7 +2,7 @@ TARGET = decorator
|
||||
SRC_CC = main.cc texture_by_id.cc default_font.h window.cc
|
||||
SRC_BIN = closer.rgba maximize.rgba minimize.rgba windowed.rgba
|
||||
SRC_BIN += droidsansb10.tff
|
||||
LIBS = base config server
|
||||
LIBS = base
|
||||
TFF_DIR = $(call select_from_repositories,src/app/scout/data)
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user