vbox_pointer: API transition

Ref #1987
This commit is contained in:
Norman Feske 2017-01-03 14:18:58 +01:00
parent e91170a49c
commit 48f216f481
5 changed files with 126 additions and 157 deletions

View File

@ -85,9 +85,9 @@ set config {
<provides><service name="Nitpicker"/></provides>
<config>
<report focus="yes" hover="yes" xray="yes"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer"/>
<domain name="smiley" layer="3" content="client" label="no"/>
<domain name="default" layer="3" content="client" label="no"/>
<domain name="pointer" layer="1" content="client" label="no" origin="pointer"/>
<domain name="smiley" layer="3" content="client" label="no" hover="always" focus="click"/>
<domain name="default" layer="3" content="client" label="yes" hover="always" focus="click"/>
<policy label_prefix="pointer" domain="pointer"/>
<policy label_prefix="test-domain-smiley" domain="smiley"/>

View File

@ -14,8 +14,9 @@
*/
/* Genode includes */
#include <os/attached_rom_dataspace.h>
#include <os/config.h>
#include <base/component.h>
#include <base/heap.h>
#include <base/attached_rom_dataspace.h>
#include <os/pixel_rgb565.h>
#include <nitpicker_session/connection.h>
@ -24,6 +25,8 @@
#include "policy.h"
#include "big_mouse.h"
namespace Vbox_pointer { class Main; }
template <typename PT>
void convert_default_pointer_data_to_pixels(PT *pixel, Nitpicker::Area size)
@ -45,29 +48,32 @@ void convert_default_pointer_data_to_pixels(PT *pixel, Nitpicker::Area size)
}
class Main : public Vbox_pointer::Pointer_updater
class Vbox_pointer::Main : public Vbox_pointer::Pointer_updater
{
private:
Genode::Env &_env;
typedef Vbox_pointer::String String;
typedef Vbox_pointer::Policy Policy;
typedef Vbox_pointer::Policy_registry Policy_registry;
Genode::Attached_rom_dataspace _hover_ds { "hover" };
Genode::Attached_rom_dataspace _xray_ds { "xray" };
Genode::Attached_rom_dataspace _hover_ds { _env, "hover" };
Genode::Attached_rom_dataspace _xray_ds { _env, "xray" };
Genode::Attached_rom_dataspace _config { _env, "config" };
Genode::Signal_receiver _sig_rec;
Genode::Signal_handler<Main> _hover_signal_handler {
_env.ep(), *this, &Main::_handle_hover };
Genode::Signal_handler<Main> _xray_signal_handler {
_env.ep(), *this, &Main::_handle_xray };
Genode::Signal_dispatcher<Main> _hover_signal_dispatcher {
_sig_rec, *this, &Main::_handle_hover };
Genode::Signal_dispatcher<Main> _xray_signal_dispatcher {
_sig_rec, *this, &Main::_handle_xray };
Nitpicker::Connection _nitpicker;
Nitpicker::Connection _nitpicker { _env };
Nitpicker::Session::View_handle _view = _nitpicker.create_view();
Policy_registry _policy_registry { *this };
Genode::Heap _heap { _env.ram(), _env.rm() };
Policy_registry _policy_registry { *this, _env, _heap };
String _hovered_label;
String _hovered_domain;
@ -82,24 +88,22 @@ class Main : public Vbox_pointer::Pointer_updater
void _show_default_pointer();
void _show_shape_pointer(Policy *p);
void _update_pointer();
void _handle_hover(unsigned num = 0);
void _handle_xray(unsigned num = 0);
void _handle_hover();
void _handle_xray();
public:
Main();
Main(Genode::Env &);
/*******************************
** Pointer_updater interface **
*******************************/
void update_pointer(Policy *policy) override;
Genode::Signal_receiver & signal_receiver() override { return _sig_rec; }
void update_pointer(Policy &policy) override;
};
void Main::_resize_nitpicker_buffer_if_needed(Nitpicker::Area pointer_size)
void Vbox_pointer::Main::_resize_nitpicker_buffer_if_needed(Nitpicker::Area pointer_size)
{
if (pointer_size == _current_pointer_size)
return;
@ -116,7 +120,7 @@ void Main::_resize_nitpicker_buffer_if_needed(Nitpicker::Area pointer_size)
}
void Main::_show_default_pointer()
void Vbox_pointer::Main::_show_default_pointer()
{
/* only draw default pointer if not already drawn */
if (_default_pointer_visible)
@ -146,7 +150,7 @@ void Main::_show_default_pointer()
}
void Main::_show_shape_pointer(Policy *p)
void Vbox_pointer::Main::_show_shape_pointer(Policy *p)
{
try {
_resize_nitpicker_buffer_if_needed(p->shape_size());
@ -156,7 +160,7 @@ void Main::_show_shape_pointer(Policy *p)
throw;
}
Genode::Attached_dataspace ds { _pointer_ds };
Genode::Attached_dataspace ds { _env.rm(), _pointer_ds };
p->draw_shape(ds.local_addr<Genode::Pixel_rgb565>());
@ -170,7 +174,7 @@ void Main::_show_shape_pointer(Policy *p)
}
void Main::_update_pointer()
void Vbox_pointer::Main::_update_pointer()
{
Policy *policy = nullptr;
@ -185,7 +189,7 @@ void Main::_update_pointer()
}
void Main::_handle_hover(unsigned)
void Vbox_pointer::Main::_handle_hover()
{
using Vbox_pointer::read_string_attribute;
@ -213,7 +217,7 @@ void Main::_handle_hover(unsigned)
}
void Main::_handle_xray(unsigned)
void Vbox_pointer::Main::_handle_xray()
{
_xray_ds.update();
if (!_xray_ds.valid())
@ -236,15 +240,15 @@ void Main::_handle_xray(unsigned)
}
void Main::update_pointer(Policy *policy)
void Vbox_pointer::Main::update_pointer(Policy &policy)
{
/* update pointer if shape-changing policy is hovered */
if (policy == _policy_registry.lookup(_hovered_label, _hovered_domain))
if (&policy == _policy_registry.lookup(_hovered_label, _hovered_domain))
_update_pointer();
}
Main::Main()
Vbox_pointer::Main::Main(Genode::Env &env) : _env(env)
{
/*
* Try to allocate the Nitpicker buffer for the maximum supported
@ -256,11 +260,11 @@ Main::Main()
_nitpicker.buffer(mode, true /* use alpha */);
_policy_registry.update(Genode::config()->xml_node());
_policy_registry.update(_config.xml());
/* register signal handlers */
_hover_ds.sigh(_hover_signal_dispatcher);
_xray_ds.sigh(_xray_signal_dispatcher);
_hover_ds.sigh(_hover_signal_handler);
_xray_ds.sigh(_xray_signal_handler);
_nitpicker.enqueue<Nitpicker::Session::Command::To_front>(_view);
_nitpicker.execute();
@ -272,18 +276,4 @@ Main::Main()
}
int main()
{
static Main main;
/* dispatch signals */
for (;;) {
Genode::Signal sig = main.signal_receiver().wait_for_signal();
Genode::Signal_dispatcher_base *dispatcher =
dynamic_cast<Genode::Signal_dispatcher_base *>(sig.context());
if (dispatcher)
dispatcher->dispatch(sig.num());
}
}
void Component::construct(Genode::Env &env) { static Vbox_pointer::Main main(env); }

View File

@ -34,28 +34,30 @@ class Vbox_pointer::Policy_entry : public Vbox_pointer::Policy,
{
private:
Genode::Env &_env;
String _label;
String _domain;
Pointer_updater &_updater;
Genode::Attached_ram_dataspace _texture_pixel_ds { Genode::env()->ram_session(),
Genode::Attached_ram_dataspace _texture_pixel_ds { _env.ram(), _env.rm(),
Vbox_pointer::MAX_WIDTH *
Vbox_pointer::MAX_HEIGHT *
sizeof(Genode::Pixel_rgb888) };
Genode::Attached_ram_dataspace _texture_alpha_ds { Genode::env()->ram_session(),
Genode::Attached_ram_dataspace _texture_alpha_ds { _env.ram(), _env.rm(),
Vbox_pointer::MAX_WIDTH *
Vbox_pointer::MAX_HEIGHT };
Genode::Attached_rom_dataspace _shape_ds;
Genode::Signal_dispatcher<Policy_entry> shape_signal_dispatcher {
_updater.signal_receiver(), *this, &Policy_entry::_import_shape };
Genode::Signal_handler<Policy_entry> _shape_signal_handler {
_env.ep(), *this, &Policy_entry::_import_shape };
Nitpicker::Area _shape_size;
Nitpicker::Point _shape_hot;
void _import_shape(unsigned = 0)
void _import_shape()
{
using namespace Genode;
@ -76,7 +78,7 @@ class Vbox_pointer::Policy_entry : public Vbox_pointer::Policy,
|| shape_report->height > Vbox_pointer::MAX_HEIGHT) {
_shape_size = Nitpicker::Area();
_shape_hot = Nitpicker::Point();
_updater.update_pointer(this);
_updater.update_pointer(*this);
}
_shape_size = Nitpicker::Area(shape_report->width, shape_report->height);
@ -104,20 +106,21 @@ class Vbox_pointer::Policy_entry : public Vbox_pointer::Policy,
texture.rgba(rgba_line, _shape_size.w(), y);
}
_updater.update_pointer(this);
_updater.update_pointer(*this);
}
public:
Policy_entry(String const &label, String const &domain, String const &rom,
Policy_entry(Genode::Env &env, String const &label,
String const &domain, String const &rom,
Pointer_updater &updater)
:
_label(label), _domain(domain), _updater(updater),
_shape_ds(rom.string())
_env(env), _label(label), _domain(domain), _updater(updater),
_shape_ds(_env, rom.string())
{
_import_shape();
_shape_ds.sigh(shape_signal_dispatcher);
_shape_ds.sigh(_shape_signal_handler);
}
/**
@ -185,23 +188,19 @@ void Vbox_pointer::Policy_registry::update(Genode::Xml_node config)
{
/* TODO real update should flush at least */
try {
for (Genode::Xml_node policy = config.sub_node("policy");
true; policy = policy.next("policy")) {
config.for_each_sub_node("policy", [&] (Genode::Xml_node policy) {
String label = read_string_attribute(policy, "label", String());
String domain = read_string_attribute(policy, "domain", String());
String rom = read_string_attribute(policy, "rom", String());
String const label = read_string_attribute(policy, "label", String());
String const domain = read_string_attribute(policy, "domain", String());
String const rom = read_string_attribute(policy, "rom", String());
if (!label.valid() && !domain.valid())
Genode::warning("policy does not declare label/domain attribute");
else if (!rom.valid())
Genode::warning("policy does not declare shape rom");
else
insert(new (Genode::env()->heap())
Policy_entry(label, domain, rom, _updater));
}
} catch (...) { }
if (!label.valid() && !domain.valid())
Genode::warning("policy does not declare label/domain attribute");
else if (!rom.valid())
Genode::warning("policy does not declare shape rom");
else
insert(new (_alloc) Policy_entry(_env, label, domain, rom, _updater));
});
}

View File

@ -34,8 +34,7 @@ namespace Vbox_pointer {
struct Vbox_pointer::Pointer_updater
{
virtual void update_pointer(Policy *initiator) = 0;
virtual Genode::Signal_receiver & signal_receiver() = 0;
virtual void update_pointer(Policy &initiator) = 0;
};
@ -53,12 +52,15 @@ class Vbox_pointer::Policy_registry : private Genode::List<Policy_entry>
{
private:
Pointer_updater &_updater;
Pointer_updater &_updater;
Genode::Env &_env;
Genode::Allocator &_alloc;
public:
Policy_registry(Pointer_updater &updater)
: _updater(updater) { }
Policy_registry(Pointer_updater &updater, Genode::Env &env,
Genode::Allocator &alloc)
: _updater(updater), _env(env), _alloc(alloc) { }
void update(Genode::Xml_node config);

View File

@ -11,84 +11,30 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/printf.h>
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <util/string.h>
#include <os/reporter.h>
#include <os/config.h>
#include <vbox_pointer/shape_report.h>
static bool const verbose = false;
typedef Genode::String<16> String;
static String read_string_attribute(Genode::Xml_node const &node,
char const *attr,
String const &default_value)
{
try {
char buf[String::capacity()];
node.attribute(attr).value(buf, sizeof(buf));
return String(Genode::Cstring(buf));
}
catch (...) {
return default_value; }
}
struct Shape
{
enum { WIDTH = 16, HEIGHT = 16 };
String const id;
typedef Genode::String<16> Id;
Id const id;
unsigned const x_hot;
unsigned const y_hot;
unsigned char const map[WIDTH*HEIGHT];
};
struct Shape_report : Vbox_pointer::Shape_report
{
Genode::Reporter reporter { "shape", "shape", sizeof(Vbox_pointer::Shape_report) };
Shape_report()
:
Vbox_pointer::Shape_report{true, 0, 0, Shape::WIDTH, Shape::HEIGHT, { 0 }}
void print(Genode::Output &output) const
{
reporter.enabled(true);
}
void report(Shape const &s)
{
x_hot = s.x_hot;
y_hot = s.y_hot;
unsigned const w = Shape::WIDTH;
unsigned const h = Shape::HEIGHT;
for (unsigned y = 0; y < h; ++y) {
for (unsigned x = 0; x < w; ++x) {
shape[(y*w + x)*4 + 0] = 0xff;
shape[(y*w + x)*4 + 1] = 0xff;
shape[(y*w + x)*4 + 2] = 0xff;
shape[(y*w + x)*4 + 3] = s.map[y*w +x] ? 0xe0 : 0;
if (verbose)
Genode::printf("%c", s.map[y*w +x] ? 'X' : ' ');
}
if (verbose)
Genode::printf("\n");
}
if (verbose)
Genode::printf(".%s.%u.%u.\n", s.id.string(), s.x_hot, s.y_hot);
reporter.report(static_cast<Vbox_pointer::Shape_report *>(this),
sizeof(Vbox_pointer::Shape_report));
Genode::print(output, ".", id, ".", x_hot, ".", y_hot, ".");
}
};
static Shape const shape[] = {
{ "arrow", 0, 0, {
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@ -178,10 +124,9 @@ static Shape const shape[] = {
};
static Shape const & select_shape()
static Shape const &select_shape(Genode::Xml_node config)
{
String const id = read_string_attribute(Genode::config()->xml_node(),
"shape", String("arrow"));
Shape::Id const id = config.attribute_value("shape", Shape::Id("arrow"));
for (Shape const &s : shape)
if (s.id == id)
@ -192,19 +137,52 @@ static Shape const & select_shape()
}
int main()
struct Main
{
static Shape_report r;
Genode::Env &_env;
/* register signal handler for config changes */
Genode::Signal_receiver sig_rec;
Genode::Signal_context sig_ctx;
Vbox_pointer::Shape_report _shape_report {
true, 0, 0, Shape::WIDTH, Shape::HEIGHT, { 0 } };
Genode::config()->sigh(sig_rec.manage(&sig_ctx));
Genode::Reporter _reporter {
"shape", "shape", sizeof(Vbox_pointer::Shape_report) };
while (true) {
r.report(select_shape());
sig_rec.wait_for_signal();
Genode::config()->reload();
Genode::Signal_handler<Main> _config_handler {
_env.ep(), *this, &Main::_handle_config };
Genode::Attached_rom_dataspace _config { _env, "config" };
void _handle_config()
{
_config.update();
Shape const &shape = select_shape(_config.xml());
_shape_report.x_hot = shape.x_hot;
_shape_report.y_hot = shape.y_hot;
unsigned const w = Shape::WIDTH;
unsigned const h = Shape::HEIGHT;
for (unsigned y = 0; y < h; ++y) {
for (unsigned x = 0; x < w; ++x) {
_shape_report.shape[(y*w + x)*4 + 0] = 0xff;
_shape_report.shape[(y*w + x)*4 + 1] = 0xff;
_shape_report.shape[(y*w + x)*4 + 2] = 0xff;
_shape_report.shape[(y*w + x)*4 + 3] = shape.map[y*w +x] ? 0xe0 : 0;
}
}
_reporter.report(&_shape_report, sizeof(Vbox_pointer::Shape_report));
}
}
Main(Genode::Env &env) : _env(env)
{
_reporter.enabled(true);
_config.sigh(_config_handler);
_handle_config();
}
};
void Component::construct(Genode::Env &env) { static Main main(env); }