mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-14 22:47:12 +00:00
parent
e91170a49c
commit
48f216f481
repos/ports
@ -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"/>
|
||||
|
@ -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); }
|
||||
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user