diff --git a/repos/ports/run/vbox_pointer.run b/repos/ports/run/vbox_pointer.run index a33d9c0dec..dc14cd8af8 100644 --- a/repos/ports/run/vbox_pointer.run +++ b/repos/ports/run/vbox_pointer.run @@ -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"/> diff --git a/repos/ports/src/app/vbox_pointer/main.cc b/repos/ports/src/app/vbox_pointer/main.cc index 8e56a70d17..e739f3092d 100644 --- a/repos/ports/src/app/vbox_pointer/main.cc +++ b/repos/ports/src/app/vbox_pointer/main.cc @@ -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); } diff --git a/repos/ports/src/app/vbox_pointer/policy.cc b/repos/ports/src/app/vbox_pointer/policy.cc index eb6925925d..c9781c0f30 100644 --- a/repos/ports/src/app/vbox_pointer/policy.cc +++ b/repos/ports/src/app/vbox_pointer/policy.cc @@ -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)); + }); } diff --git a/repos/ports/src/app/vbox_pointer/policy.h b/repos/ports/src/app/vbox_pointer/policy.h index 64cccbea3e..f44b44f52c 100644 --- a/repos/ports/src/app/vbox_pointer/policy.h +++ b/repos/ports/src/app/vbox_pointer/policy.h @@ -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); diff --git a/repos/ports/src/test/vbox_pointer/main.cc b/repos/ports/src/test/vbox_pointer/main.cc index 5840f4030f..58a4f04fe7 100644 --- a/repos/ports/src/test/vbox_pointer/main.cc +++ b/repos/ports/src/test/vbox_pointer/main.cc @@ -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); }