mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 23:42:32 +00:00
parent
5099d00eb3
commit
78b38cd65b
@ -76,7 +76,6 @@ set config {
|
||||
<config>
|
||||
<policy label="pointer -> hover" report="nitpicker -> hover"/>
|
||||
<policy label="pointer -> xray" report="null"/>
|
||||
<policy label="pointer -> focus" report="nitpicker -> focus"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
@ -92,11 +91,9 @@ set config {
|
||||
<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" 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"/>
|
||||
<default-policy domain="default"/>
|
||||
|
||||
<background color="#00426f"/> <!-- indigo -->
|
||||
@ -113,23 +110,6 @@ set config {
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="report_rom_shapes">
|
||||
<binary name="report_rom"/>
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config>
|
||||
<policy label="pointer -> arrow" report="shape-arrow -> shape"/>
|
||||
<policy label="pointer -> blade" report="shape-blade -> shape"/>
|
||||
<policy label="pointer -> bladex" report="shape-bladex -> shape"/>
|
||||
<policy label="pointer -> smiley" report="shape-smiley -> shape"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="shape-arrow">
|
||||
<binary name="test-vbox_pointer"/>
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
@ -139,7 +119,9 @@ set config {
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Report"> <child name="report_rom_shapes"/> </service>
|
||||
<service name="Report" label="shape">
|
||||
<child name="pointer" label="test-label-arrow -> testnit"/>
|
||||
</service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="shape-blade">
|
||||
@ -151,7 +133,9 @@ set config {
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Report"> <child name="report_rom_shapes"/> </service>
|
||||
<service name="Report" label="shape">
|
||||
<child name="pointer" label="test-label-blade -> testnit"/>
|
||||
</service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="shape-bladex">
|
||||
@ -163,7 +147,9 @@ set config {
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Report"> <child name="report_rom_shapes"/> </service>
|
||||
<service name="Report" label="shape">
|
||||
<child name="pointer" label="test-label-bladex -> testnit"/>
|
||||
</service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="shape-smiley-config">
|
||||
@ -197,7 +183,9 @@ set config {
|
||||
<route>
|
||||
<service name="ROM" label="smiley.config">
|
||||
<child name="shape-smiley-config"/> </service>
|
||||
<service name="Report"> <child name="report_rom_shapes"/> </service>
|
||||
<service name="Report" label="shape">
|
||||
<child name="pointer" label="test-label-smiley -> testnit"/>
|
||||
</service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
@ -208,22 +196,13 @@ set config {
|
||||
<start name="pointer">
|
||||
<binary name="vbox_pointer"/>
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<config>
|
||||
<policy domain="smiley" rom="smiley"/>
|
||||
<policy label="test-label-arrow" rom="arrow"/>
|
||||
<policy label="test-label-blade" rom="blade"/>
|
||||
<policy label="test-label-bladex" rom="bladex"/>
|
||||
</config>
|
||||
<provides> <service name="Report"/> </provides>
|
||||
<route>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Nitpicker"> <child name="nitpicker"/> </service>
|
||||
<service name="ROM" label="xray"> <child name="report_rom_nitpicker"/> </service>
|
||||
<service name="ROM" label="hover"> <child name="report_rom_nitpicker"/> </service>
|
||||
<service name="ROM" label="arrow"> <child name="report_rom_shapes"/> </service>
|
||||
<service name="ROM" label="blade"> <child name="report_rom_shapes"/> </service>
|
||||
<service name="ROM" label="bladex"> <child name="report_rom_shapes"/> </service>
|
||||
<service name="ROM" label="smiley"> <child name="report_rom_shapes"/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
</route>
|
||||
@ -241,7 +220,7 @@ set config {
|
||||
<service name="Nitpicker"> <child name="nitpicker"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="test-domain-smiley">
|
||||
<start name="test-label-smiley">
|
||||
<binary name="testnit"/>
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<route>
|
||||
@ -277,18 +256,6 @@ set config {
|
||||
<service name="Nitpicker"> <child name="nitpicker"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="test-label-blade2">
|
||||
<binary name="testnit"/>
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<route>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Nitpicker"> <child name="nitpicker"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
<start name="test-label-bladex">
|
||||
<binary name="testnit"/>
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
|
@ -113,12 +113,6 @@ append config_of_app {
|
||||
<config>
|
||||
<policy label="vbox_pointer -> hover" report="nitpicker -> hover"/>
|
||||
<policy label="vbox_pointer -> xray" report="nitpicker -> xray"/>}
|
||||
|
||||
for { set i 1} { $i <= $use_vms } { incr i} {
|
||||
append config_of_app "
|
||||
<policy label=\"vbox_pointer -> shape$i\" report=\"vbox$i -> shape\"/>"
|
||||
}
|
||||
|
||||
append config_of_app {
|
||||
<policy label="usb_report_filter -> devices" report="usb_drv -> devices"/>
|
||||
<policy label="usb_report_filter -> usb_drv_config" report="usb_drv -> config"/>
|
||||
@ -154,23 +148,10 @@ append config_of_app {
|
||||
|
||||
<start name="vbox_pointer" priority="-1">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<config>}
|
||||
|
||||
for { set i 1} { $i <= $use_vms } { incr i} {
|
||||
append config_of_app "
|
||||
<policy label=\"nit_fb$i\" rom=\"shape$i\"/>"
|
||||
}
|
||||
|
||||
append config_of_app {
|
||||
</config>
|
||||
<provides> <service name="Report"/> </provides>
|
||||
<route>
|
||||
<service name="Nitpicker"> <child name="nitpicker"/> </service>}
|
||||
|
||||
for { set i 1} { $i <= $use_vms } { incr i} {
|
||||
append config_of_app "
|
||||
<service name=\"ROM\" label=\"shape$i\"> <child name=\"report_rom\"/> </service>"
|
||||
}
|
||||
|
||||
append config_of_app {
|
||||
<service name="ROM" label="hover"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="xray"> <child name="report_rom"/> </service>
|
||||
@ -313,7 +294,10 @@ for { set i 1} { $i <= $use_vms } { incr i} {
|
||||
<service name="Block"> <child name="part_blk"/> </service>}
|
||||
append config_of_app "
|
||||
<service name=\"Framebuffer\"> <child name=\"nit_fb${i}\" /> </service>
|
||||
<service name=\"Input\"> <child name=\"nit_fb${i}\" /> </service>"
|
||||
<service name=\"Input\"> <child name=\"nit_fb${i}\" /> </service>
|
||||
<service name=\"Report\" label=\"shape\">
|
||||
<child name=\"vbox_pointer\" label=\"nit_fb${i} -> \"/>
|
||||
</service>"
|
||||
append config_of_app {
|
||||
<service name="Report"><child name="report_rom" /></service>
|
||||
<service name="ROM" label="usb_devices"> <child name="report_rom" /> </service>
|
||||
|
@ -159,8 +159,6 @@ append_if [expr $use_gui] config {
|
||||
<config>
|
||||
<policy label="vbox_pointer -> hover" report="nitpicker -> hover"/>
|
||||
<policy label="vbox_pointer -> xray" report="nitpicker -> xray"/>
|
||||
<policy label="vbox_pointer -> shape1" report="vbox1 -> shape"/>
|
||||
<policy label="vbox_pointer -> shape2" report="vbox2 -> shape"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
@ -192,14 +190,8 @@ append_if [expr $use_gui] config {
|
||||
|
||||
<start name="vbox_pointer" priority="-1">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<config>
|
||||
<policy label="nit_fb1" rom="shape1"/>
|
||||
<policy label="nit_fb2" rom="shape2"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nitpicker"> <child name="nitpicker"/> </service>
|
||||
<service name="ROM" label="shape1"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="shape2"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="hover"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="xray"> <child name="report_rom"/> </service>
|
||||
<any-service> <parent/> </any-service>
|
||||
@ -251,6 +243,7 @@ append_if [expr $use_gui] config {
|
||||
</config>
|
||||
<route>
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>
|
||||
<service name="Report" label="shape"> <child name="vbox_pointer" label="nit_fb2 -> "/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="Framebuffer"> <child name="nit_fb2" /> </service>
|
||||
<service name="Input"> <child name="nit_fb2" /> </service>
|
||||
@ -283,6 +276,7 @@ append_if [expr $use_bridge] config {
|
||||
<service name="Nic"> <child name="nic_bridge"/> </service>}
|
||||
|
||||
append_if [expr $use_gui] config {
|
||||
<service name="Report" label="shape"> <child name="vbox_pointer" label="nit_fb1 -> "/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="Framebuffer"> <child name="nit_fb1" /> </service>
|
||||
<service name="Input"> <child name="nit_fb1" /> </service>}
|
||||
|
@ -17,12 +17,19 @@
|
||||
#include <base/component.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <os/pixel_alpha8.h>
|
||||
#include <os/pixel_rgb565.h>
|
||||
#include <os/pixel_rgb888.h>
|
||||
#include <os/surface.h>
|
||||
#include <os/texture_rgb888.h>
|
||||
#include <nitpicker_session/connection.h>
|
||||
#include <report_rom/report_service.h>
|
||||
#include <vbox_pointer/dither_painter.h>
|
||||
#include <vbox_pointer/shape_report.h>
|
||||
|
||||
/* local includes */
|
||||
#include "util.h"
|
||||
#include "policy.h"
|
||||
#include "rom_registry.h"
|
||||
#include "big_mouse.h"
|
||||
|
||||
namespace Vbox_pointer { class Main; }
|
||||
@ -48,15 +55,13 @@ void convert_default_pointer_data_to_pixels(PT *pixel, Nitpicker::Area size)
|
||||
}
|
||||
|
||||
|
||||
class Vbox_pointer::Main : public Vbox_pointer::Pointer_updater
|
||||
class Vbox_pointer::Main : public Rom::Reader
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
typedef Vbox_pointer::String String;
|
||||
typedef Vbox_pointer::Policy Policy;
|
||||
typedef Vbox_pointer::Policy_registry Policy_registry;
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Genode::Attached_rom_dataspace _hover_ds { _env, "hover" };
|
||||
Genode::Attached_rom_dataspace _xray_ds { _env, "xray" };
|
||||
@ -71,12 +76,15 @@ class Vbox_pointer::Main : public Vbox_pointer::Pointer_updater
|
||||
|
||||
Nitpicker::Session::View_handle _view = _nitpicker.create_view();
|
||||
|
||||
Genode::Heap _heap { _env.ram(), _env.rm() };
|
||||
Genode::Sliced_heap _sliced_heap { _env.ram(), _env.rm() };
|
||||
|
||||
Policy_registry _policy_registry { *this, _env, _heap };
|
||||
Rom::Registry _rom_registry { _sliced_heap, _env.ram(), _env.rm(), *this };
|
||||
|
||||
bool _verbose = _config.xml().attribute_value("verbose", false);
|
||||
|
||||
Report::Root _report_root { _env, _sliced_heap, _rom_registry, _verbose };
|
||||
|
||||
String _hovered_label;
|
||||
String _hovered_domain;
|
||||
|
||||
bool _xray = false;
|
||||
bool _default_pointer_visible = false;
|
||||
@ -84,22 +92,38 @@ class Vbox_pointer::Main : public Vbox_pointer::Pointer_updater
|
||||
Nitpicker::Area _current_pointer_size;
|
||||
Genode::Dataspace_capability _pointer_ds;
|
||||
|
||||
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 { _env.ram(), _env.rm(),
|
||||
Vbox_pointer::MAX_WIDTH *
|
||||
Vbox_pointer::MAX_HEIGHT };
|
||||
|
||||
void _resize_nitpicker_buffer_if_needed(Nitpicker::Area pointer_size);
|
||||
void _show_default_pointer();
|
||||
void _show_shape_pointer(Policy *p);
|
||||
void _show_shape_pointer(Shape_report &shape_report);
|
||||
void _update_pointer();
|
||||
void _handle_hover();
|
||||
void _handle_xray();
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Reader interface
|
||||
*/
|
||||
void notify_module_changed() override
|
||||
{
|
||||
_update_pointer();
|
||||
}
|
||||
|
||||
void notify_module_invalidated() override
|
||||
{
|
||||
_update_pointer();
|
||||
}
|
||||
|
||||
Main(Genode::Env &);
|
||||
|
||||
/*******************************
|
||||
** Pointer_updater interface **
|
||||
*******************************/
|
||||
|
||||
void update_pointer(Policy &policy) override;
|
||||
};
|
||||
|
||||
|
||||
@ -150,24 +174,57 @@ void Vbox_pointer::Main::_show_default_pointer()
|
||||
}
|
||||
|
||||
|
||||
void Vbox_pointer::Main::_show_shape_pointer(Policy *p)
|
||||
void Vbox_pointer::Main::_show_shape_pointer(Shape_report &shape_report)
|
||||
{
|
||||
Nitpicker::Area shape_size { shape_report.width, shape_report.height };
|
||||
Nitpicker::Point shape_hot { (int)-shape_report.x_hot, (int)-shape_report.y_hot };
|
||||
|
||||
try {
|
||||
_resize_nitpicker_buffer_if_needed(p->shape_size());
|
||||
_resize_nitpicker_buffer_if_needed(shape_size);
|
||||
} catch (...) {
|
||||
error(__func__, ": could not resize the pointer buffer "
|
||||
"for ", p->shape_size(), " pixels");
|
||||
"for ", shape_size, " pixels");
|
||||
throw;
|
||||
}
|
||||
|
||||
if (p->shape_visible()) {
|
||||
Genode::Attached_dataspace ds { _env.rm(), _pointer_ds };
|
||||
p->draw_shape(ds.local_addr<Genode::Pixel_rgb565>());
|
||||
if (shape_report.visible) {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
/* import shape into texture */
|
||||
|
||||
Texture<Pixel_rgb888>
|
||||
texture(_texture_pixel_ds.local_addr<Pixel_rgb888>(),
|
||||
_texture_alpha_ds.local_addr<unsigned char>(),
|
||||
shape_size);
|
||||
|
||||
for (unsigned int y = 0; y < shape_size.h(); y++) {
|
||||
|
||||
/* import the RGBA-encoded line into the texture */
|
||||
unsigned char *shape = shape_report.shape;
|
||||
unsigned char *line = &shape[y * shape_size.w() * 4];
|
||||
texture.rgba(line, shape_size.w(), y);
|
||||
}
|
||||
|
||||
_nitpicker.framebuffer()->refresh(0, 0, p->shape_size().w(), p->shape_size().h());
|
||||
/* draw texture */
|
||||
|
||||
Nitpicker::Rect geometry(p->shape_hot(), p->shape_size());
|
||||
Attached_dataspace ds { _env.rm(), _pointer_ds };
|
||||
|
||||
Pixel_rgb565 *pixel = ds.local_addr<Pixel_rgb565>();
|
||||
|
||||
Pixel_alpha8 *alpha =
|
||||
reinterpret_cast<Pixel_alpha8 *>(pixel + shape_size.count());
|
||||
|
||||
Surface<Pixel_rgb565> pixel_surface(pixel, shape_size);
|
||||
Surface<Pixel_alpha8> alpha_surface(alpha, shape_size);
|
||||
|
||||
Dither_painter::paint(pixel_surface, texture);
|
||||
Dither_painter::paint(alpha_surface, texture);
|
||||
}
|
||||
|
||||
_nitpicker.framebuffer()->refresh(0, 0, shape_size.w(), shape_size.h());
|
||||
|
||||
Nitpicker::Rect geometry(shape_hot, shape_size);
|
||||
_nitpicker.enqueue<Nitpicker::Session::Command::Geometry>(_view, geometry);
|
||||
_nitpicker.execute();
|
||||
|
||||
@ -177,16 +234,42 @@ void Vbox_pointer::Main::_show_shape_pointer(Policy *p)
|
||||
|
||||
void Vbox_pointer::Main::_update_pointer()
|
||||
{
|
||||
Policy *policy = nullptr;
|
||||
|
||||
if (_xray
|
||||
|| !(policy = _policy_registry.lookup(_hovered_label, _hovered_domain))
|
||||
|| (policy->shape_visible() && !policy->shape_valid()))
|
||||
if (_xray) {
|
||||
_show_default_pointer();
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
_show_shape_pointer(policy);
|
||||
} catch (...) { _show_default_pointer(); }
|
||||
|
||||
Rom::Readable_module &shape_module =
|
||||
_rom_registry.lookup(*this, _hovered_label);
|
||||
|
||||
try {
|
||||
Shape_report shape_report;
|
||||
|
||||
shape_module.read_content(*this, (char*)&shape_report, sizeof(shape_report));
|
||||
|
||||
if (shape_report.visible) {
|
||||
|
||||
if ((shape_report.width == 0) ||
|
||||
(shape_report.height == 0) ||
|
||||
(shape_report.width > MAX_WIDTH) ||
|
||||
(shape_report.height > MAX_HEIGHT))
|
||||
throw Genode::Exception();
|
||||
|
||||
_show_shape_pointer(shape_report);
|
||||
}
|
||||
|
||||
} catch (...) {
|
||||
_rom_registry.release(*this, shape_module);
|
||||
throw;
|
||||
}
|
||||
|
||||
_rom_registry.release(*this, shape_module);
|
||||
|
||||
} catch (...) {
|
||||
_show_default_pointer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -203,12 +286,13 @@ void Vbox_pointer::Main::_handle_hover()
|
||||
Genode::Xml_node node(_hover_ds.local_addr<char>());
|
||||
|
||||
String hovered_label = read_string_attribute(node, "label", String());
|
||||
String hovered_domain = read_string_attribute(node, "domain", String());
|
||||
|
||||
/* update pointer if hovered domain or label changed */
|
||||
if (hovered_label != _hovered_label || hovered_domain != _hovered_domain) {
|
||||
if (_verbose)
|
||||
Genode::log("hovered_label: ", hovered_label);
|
||||
|
||||
/* update pointer if hovered label changed */
|
||||
if (hovered_label != _hovered_label) {
|
||||
_hovered_label = hovered_label;
|
||||
_hovered_domain = hovered_domain;
|
||||
_update_pointer();
|
||||
}
|
||||
}
|
||||
@ -240,15 +324,6 @@ void Vbox_pointer::Main::_handle_xray()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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))
|
||||
_update_pointer();
|
||||
}
|
||||
|
||||
|
||||
Vbox_pointer::Main::Main(Genode::Env &env) : _env(env)
|
||||
{
|
||||
/*
|
||||
@ -261,8 +336,6 @@ Vbox_pointer::Main::Main(Genode::Env &env) : _env(env)
|
||||
|
||||
_nitpicker.buffer(mode, true /* use alpha */);
|
||||
|
||||
_policy_registry.update(_config.xml());
|
||||
|
||||
/* register signal handlers */
|
||||
_hover_ds.sigh(_hover_signal_handler);
|
||||
_xray_ds.sigh(_xray_signal_handler);
|
||||
@ -274,6 +347,9 @@ Vbox_pointer::Main::Main(Genode::Env &env) : _env(env)
|
||||
_handle_hover();
|
||||
_handle_xray();
|
||||
_update_pointer();
|
||||
|
||||
/* announce 'Report' service */
|
||||
env.parent().announce(env.ep().manage(_report_root));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,224 +0,0 @@
|
||||
/*
|
||||
* \brief VirtualBox pointer policies implementation
|
||||
* \author Christian Prochaska
|
||||
* \author Christian Helmuth
|
||||
* \date 2015-06-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <os/pixel_alpha8.h>
|
||||
#include <os/pixel_rgb888.h>
|
||||
#include <os/surface.h>
|
||||
#include <os/texture_rgb888.h>
|
||||
#include <vbox_pointer/dither_painter.h>
|
||||
|
||||
/* local includes */
|
||||
#include "policy.h"
|
||||
|
||||
|
||||
/******************************
|
||||
** Entry in policy registry **
|
||||
******************************/
|
||||
|
||||
class Vbox_pointer::Policy_entry : public Vbox_pointer::Policy,
|
||||
public Genode::List<Policy_entry>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
String _label;
|
||||
String _domain;
|
||||
|
||||
Pointer_updater &_updater;
|
||||
|
||||
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 { _env.ram(), _env.rm(),
|
||||
Vbox_pointer::MAX_WIDTH *
|
||||
Vbox_pointer::MAX_HEIGHT };
|
||||
Genode::Attached_rom_dataspace _shape_ds;
|
||||
|
||||
Genode::Signal_handler<Policy_entry> _shape_signal_handler {
|
||||
_env.ep(), *this, &Policy_entry::_import_shape };
|
||||
|
||||
bool _shape_visible;
|
||||
Nitpicker::Area _shape_size;
|
||||
Nitpicker::Point _shape_hot;
|
||||
|
||||
void _import_shape()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
_shape_ds.update();
|
||||
|
||||
if (!_shape_ds.valid())
|
||||
return;
|
||||
|
||||
if (_shape_ds.size() < sizeof(Vbox_pointer::Shape_report))
|
||||
return;
|
||||
|
||||
Vbox_pointer::Shape_report *shape_report =
|
||||
_shape_ds.local_addr<Vbox_pointer::Shape_report>();
|
||||
|
||||
_shape_visible = shape_report->visible;
|
||||
|
||||
if (!_shape_visible
|
||||
|| shape_report->width == 0 || shape_report->height == 0
|
||||
|| shape_report->width > Vbox_pointer::MAX_WIDTH
|
||||
|| shape_report->height > Vbox_pointer::MAX_HEIGHT) {
|
||||
_shape_size = Nitpicker::Area();
|
||||
_shape_hot = Nitpicker::Point();
|
||||
_updater.update_pointer(*this);
|
||||
return;
|
||||
}
|
||||
|
||||
_shape_size = Nitpicker::Area(shape_report->width, shape_report->height);
|
||||
_shape_hot = Nitpicker::Point(-shape_report->x_hot, -shape_report->y_hot);
|
||||
|
||||
Texture<Pixel_rgb888>
|
||||
texture(_texture_pixel_ds.local_addr<Pixel_rgb888>(),
|
||||
_texture_alpha_ds.local_addr<unsigned char>(),
|
||||
_shape_size);
|
||||
|
||||
for (unsigned int y = 0; y < _shape_size.h(); y++) {
|
||||
|
||||
/* import the RGBA-encoded line into the texture */
|
||||
unsigned char *shape = shape_report->shape;
|
||||
unsigned char *line = &shape[y * _shape_size.w() * 4];
|
||||
texture.rgba(line, _shape_size.w(), y);
|
||||
}
|
||||
|
||||
_updater.update_pointer(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Policy_entry(Genode::Env &env, String const &label,
|
||||
String const &domain, String const &rom,
|
||||
Pointer_updater &updater)
|
||||
:
|
||||
_env(env), _label(label), _domain(domain), _updater(updater),
|
||||
_shape_ds(_env, rom.string())
|
||||
{
|
||||
_import_shape();
|
||||
|
||||
_shape_ds.sigh(_shape_signal_handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return similarity of policy label and the passed label
|
||||
*/
|
||||
Genode::size_t match_label(String const &other) const
|
||||
{
|
||||
if (_label.length() > 1 && other.length() > 1) {
|
||||
/* length of string w/o null byte */
|
||||
Genode::size_t const len = _label.length() - 1;
|
||||
|
||||
if (Genode::strcmp(other.string(), _label.string(), len) == 0)
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if policy domain and passed domain match exactly
|
||||
*/
|
||||
bool match_domain(String const &other) const
|
||||
{
|
||||
return _domain.length() > 1 && _domain == other;
|
||||
}
|
||||
|
||||
/**********************
|
||||
** Policy interface **
|
||||
**********************/
|
||||
|
||||
Nitpicker::Area shape_size() const override { return _shape_size; }
|
||||
Nitpicker::Point shape_hot() const override { return _shape_hot; }
|
||||
|
||||
bool shape_visible() const override { return _shape_visible; }
|
||||
bool shape_valid() const override { return _shape_size.valid(); }
|
||||
|
||||
void draw_shape(Genode::Pixel_rgb565 *pixel) override
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
if (!_shape_size.valid())
|
||||
return;
|
||||
|
||||
Pixel_alpha8 *alpha =
|
||||
reinterpret_cast<Pixel_alpha8 *>(pixel + _shape_size.count());
|
||||
|
||||
Surface<Pixel_rgb565> pixel_surface(pixel, _shape_size);
|
||||
Surface<Pixel_alpha8> alpha_surface(alpha, _shape_size);
|
||||
|
||||
Texture<Pixel_rgb888>
|
||||
texture(_texture_pixel_ds.local_addr<Pixel_rgb888>(),
|
||||
_texture_alpha_ds.local_addr<unsigned char>(),
|
||||
_shape_size);
|
||||
|
||||
Dither_painter::paint(pixel_surface, texture);
|
||||
Dither_painter::paint(alpha_surface, texture);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**************
|
||||
** Registry **
|
||||
**************/
|
||||
|
||||
void Vbox_pointer::Policy_registry::update(Genode::Xml_node config)
|
||||
{
|
||||
/* TODO real update should flush at least */
|
||||
|
||||
config.for_each_sub_node("policy", [&] (Genode::Xml_node policy) {
|
||||
|
||||
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 (_alloc) Policy_entry(_env, label, domain, rom, _updater));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Vbox_pointer::Policy * Vbox_pointer::Policy_registry::lookup(String const &label,
|
||||
String const &domain)
|
||||
{
|
||||
/* try label similarity matching first */
|
||||
unsigned similarity = 0;
|
||||
Policy_entry *match = nullptr;
|
||||
for (Policy_entry *p = first(); p; p = p->next()) {
|
||||
unsigned s = p->match_label(label);
|
||||
if (s > similarity) {
|
||||
similarity = s;
|
||||
match = p;
|
||||
}
|
||||
}
|
||||
if (match) return match;
|
||||
|
||||
/* then match domains */
|
||||
for (Policy_entry *p = first(); p; p = p->next())
|
||||
if (p->match_domain(domain))
|
||||
return p;
|
||||
|
||||
return nullptr;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* \brief VirtualBox pointer policies
|
||||
* \author Christian Helmuth
|
||||
* \date 2015-06-08
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _VBOX_POINTER_POLICY_H_
|
||||
#define _VBOX_POINTER_POLICY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/pixel_rgb565.h>
|
||||
#include <nitpicker_session/nitpicker_session.h>
|
||||
#include <vbox_pointer/shape_report.h>
|
||||
#include <util/list.h>
|
||||
|
||||
/* local includes */
|
||||
#include "util.h"
|
||||
|
||||
|
||||
namespace Vbox_pointer {
|
||||
struct Pointer_updater;
|
||||
struct Policy;
|
||||
struct Policy_entry;
|
||||
struct Policy_registry;
|
||||
}
|
||||
|
||||
|
||||
struct Vbox_pointer::Pointer_updater
|
||||
{
|
||||
virtual void update_pointer(Policy &initiator) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct Vbox_pointer::Policy
|
||||
{
|
||||
virtual Nitpicker::Area shape_size() const = 0;
|
||||
virtual Nitpicker::Point shape_hot() const = 0;
|
||||
virtual bool shape_visible() const = 0;
|
||||
virtual bool shape_valid() const = 0;
|
||||
|
||||
virtual void draw_shape(Genode::Pixel_rgb565 *pixel) = 0;
|
||||
};
|
||||
|
||||
|
||||
class Vbox_pointer::Policy_registry : private Genode::List<Policy_entry>
|
||||
{
|
||||
private:
|
||||
|
||||
Pointer_updater &_updater;
|
||||
Genode::Env &_env;
|
||||
Genode::Allocator &_alloc;
|
||||
|
||||
public:
|
||||
|
||||
Policy_registry(Pointer_updater &updater, Genode::Env &env,
|
||||
Genode::Allocator &alloc)
|
||||
: _updater(updater), _env(env), _alloc(alloc) { }
|
||||
|
||||
void update(Genode::Xml_node config);
|
||||
|
||||
Policy * lookup(String const &label, String const &domain);
|
||||
};
|
||||
|
||||
#endif /* _VBOX_POINTER_POLICY_H_ */
|
137
repos/ports/src/app/vbox_pointer/rom_registry.h
Normal file
137
repos/ports/src/app/vbox_pointer/rom_registry.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* \brief Registry of ROM modules
|
||||
* \author Norman Feske
|
||||
* \date 2014-01-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _ROM_REGISTRY_H_
|
||||
#define _ROM_REGISTRY_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <report_rom/rom_registry.h>
|
||||
#include <os/session_policy.h>
|
||||
|
||||
namespace Rom { struct Registry; }
|
||||
|
||||
|
||||
struct Rom::Registry : Registry_for_reader, Registry_for_writer, Genode::Noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Allocator &_md_alloc;
|
||||
Genode::Ram_session &_ram;
|
||||
Genode::Region_map &_rm;
|
||||
Reader &_reader;
|
||||
|
||||
Module_list _modules;
|
||||
|
||||
struct Read_write_policy : Module::Read_policy, Module::Write_policy
|
||||
{
|
||||
bool read_permitted(Module const &,
|
||||
Writer const &,
|
||||
Reader const &) const override
|
||||
{
|
||||
/*
|
||||
* The pointer application is always allowed to read the ROM content.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
bool write_permitted(Module const &, Writer const &) const override
|
||||
{
|
||||
/*
|
||||
* Because the report-session label is used as the module name
|
||||
* for the writer, each report session refers to a distinct
|
||||
* module. Report client can write to their respective modules
|
||||
* at any time.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
} _read_write_policy;
|
||||
|
||||
Module &_lookup(Module::Name const name, bool create_if_not_found)
|
||||
{
|
||||
for (Module *m = _modules.first(); m; m = m->next())
|
||||
if (m->_has_name(name))
|
||||
return *m;
|
||||
|
||||
if (!create_if_not_found)
|
||||
throw Genode::Service_denied();
|
||||
|
||||
/* module does not exist yet, create one */
|
||||
|
||||
/* XXX proper accounting for the used memory is missing */
|
||||
/* XXX if we run out of memory, the server will abort */
|
||||
|
||||
Module * const module = new (&_md_alloc)
|
||||
Module(_ram, _rm, name, _read_write_policy, _read_write_policy);
|
||||
|
||||
_modules.insert(module);
|
||||
return *module;
|
||||
}
|
||||
|
||||
void _try_to_destroy(Module const &module)
|
||||
{
|
||||
if (module._in_use())
|
||||
return;
|
||||
|
||||
_modules.remove(&module);
|
||||
Genode::destroy(&_md_alloc, const_cast<Module *>(&module));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Registry(Genode::Allocator &md_alloc,
|
||||
Genode::Ram_session &ram, Genode::Region_map &rm,
|
||||
Reader &reader)
|
||||
:
|
||||
_md_alloc(md_alloc), _ram(ram), _rm(rm), _reader(reader)
|
||||
{ }
|
||||
|
||||
Module &lookup(Writer &writer, Module::Name const &name) override
|
||||
{
|
||||
Module &module = _lookup(name, true);
|
||||
|
||||
module._register(writer);
|
||||
|
||||
/*
|
||||
* Enforce invariant that each module can have only one writer at a
|
||||
* time.
|
||||
*/
|
||||
if (module._num_writers() > 1) {
|
||||
release(writer, module);
|
||||
throw Genode::Service_denied();
|
||||
}
|
||||
|
||||
module._register(_reader);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
void release(Writer &writer, Module &module) override
|
||||
{
|
||||
module._unregister(_reader);
|
||||
module._unregister(writer);
|
||||
_try_to_destroy(module);
|
||||
}
|
||||
|
||||
Readable_module &lookup(Reader &reader, Module::Name const &rom_label) override
|
||||
{
|
||||
return _lookup(rom_label, false);
|
||||
}
|
||||
|
||||
void release(Reader &reader, Readable_module &module) override
|
||||
{
|
||||
_try_to_destroy(static_cast<Module&>(module));
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _ROM_REGISTRY_H_ */
|
@ -1,3 +1,3 @@
|
||||
TARGET = vbox_pointer
|
||||
SRC_CC = main.cc policy.cc
|
||||
SRC_CC = main.cc
|
||||
LIBS += base
|
||||
|
Loading…
Reference in New Issue
Block a user