nit_fb: support 'origin' attribute

This patch makes the specification of screen coordinates more flexible.
First, the 'origin' attribute allows one to refer to either of the four
screen corners without knowing the screen size. Second, the 'width'
and 'height' values now accept negative values, which are relative to
the screen size.
This commit is contained in:
Norman Feske 2017-10-18 16:48:40 +02:00 committed by Christian Helmuth
parent dd5b03671d
commit f3988a27d4
2 changed files with 51 additions and 7 deletions

View File

@ -5,5 +5,15 @@ virtual frame buffers on one physical screen. The size and screen position
of each 'nit_fb' instance can be defined via Genode's configuration mechansim
using the following attributes of the 'nit_fb' config node:
! <config xpos="100" ypos="150" width="300" height="200" />
! <config xpos="100" ypos="150" width="300" height="200" origin="top_left"/>
The 'origin' attribute denotes the coordinate origin of the values specified
in the 'xpos' and 'ypos' attributes. Supported origins are "top_left",
"top_right", "bottom_left", and "bottom_right". This attribute allows one to
align the nitpicker view at any of the four screen boundaries.
The 'width' and 'height' attribute values can be negative. If so, they are
relative to the physical screen size. E.g., when using a screen size of
640x480, the effective width for a 'width' attribute value of "-100" would
be 640 - 100 = 540.

View File

@ -26,6 +26,7 @@ namespace Nit_fb {
using Genode::Static_root;
using Genode::Signal_handler;
using Genode::Xml_node;
typedef Genode::Surface_base::Point Point;
typedef Genode::Surface_base::Area Area;
@ -258,18 +259,51 @@ struct Nit_fb::Main : View_updater
nitpicker.execute();
}
/**
* Return screen-coordinate origin, depening on the config and screen mode
*/
static Point _coordinate_origin(Framebuffer::Mode mode, Xml_node config)
{
char const * const attr = "origin";
if (!config.has_attribute(attr))
return Point(0, 0);
typedef Genode::String<32> Value;
Value const value = config.attribute_value(attr, Value());
if (value == "top_left") return Point(0, 0);
if (value == "top_right") return Point(mode.width(), 0);
if (value == "bottom_left") return Point(0, mode.height());
if (value == "bottom_right") return Point(mode.width(), mode.height());
warning("unsupported ", attr, " attribute value '", value, "'");
return Point(0, 0);
}
void handle_config_update()
{
config_rom.update();
Xml_node const config = config_rom.xml();
Framebuffer::Mode const nit_mode = nitpicker.mode();
position = Point(config_rom.xml().attribute_value("xpos", 0U),
config_rom.xml().attribute_value("ypos", 0U));
position = _coordinate_origin(nit_mode, config)
+ Point(config.attribute_value("xpos", 0L),
config.attribute_value("ypos", 0L));
fb_session.size(Area(
config_rom.xml().attribute_value("width", (unsigned)nit_mode.width()),
config_rom.xml().attribute_value("height", (unsigned)nit_mode.height())));
long width = config.attribute_value("width", (long)nit_mode.width()),
height = config.attribute_value("height", (long)nit_mode.height());
/*
* If configured width / height values are negative, the effective
* width / height is deduced from the screen size.
*/
if (width < 0) width = nit_mode.width() + width;
if (height < 0) height = nit_mode.height() + height;
fb_session.size(Area(width, height));
/*
* Simulate a client call Framebuffer::Session::mode to make the
@ -277,7 +311,7 @@ struct Nit_fb::Main : View_updater
*/
fb_session.mode();
Genode::log("using xywh=(", position.x(), ",", position.x(),
Genode::log("using xywh=(", position.x(), ",", position.y(),
",", fb_session.size().w(),
",", fb_session.size().h(), ")");