mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 13:26:27 +00:00
sculpt: generate panorama config
If the fb driver is configured to use discrete displays, sculpt now automatically generates a panorama configuration for nitpicker that shows all displays side by side. The effective nitpicker config is now located at config/managed/nitpicker. The automatism takes effect only when nitpicker's <capture> node in config/nitpicker is empty. Hence, the managed panorama can be overridden by a manually managed panorama. Issue #5286
This commit is contained in:
parent
8ed87dae71
commit
01c96cf537
@ -483,7 +483,7 @@ install_config {
|
||||
</provides>
|
||||
<route>
|
||||
<service name="ROM" label="config">
|
||||
<child name="config_fs_rom" label="nitpicker"/> </service>
|
||||
<child name="config_fs_rom" label="managed/nitpicker"/> </service>
|
||||
<service name="ROM" label="focus">
|
||||
<child name="nit_focus"/> </service>
|
||||
<service name="Report" label="panorama">
|
||||
@ -848,7 +848,7 @@ set fd [open [managed_config_path depot_query] w]
|
||||
puts $fd "<query/>"
|
||||
close $fd
|
||||
|
||||
foreach config { fonts wifi runtime event_filter system } {
|
||||
foreach config { fonts wifi runtime event_filter system nitpicker } {
|
||||
set ingredient [single_ingredient $config "default"]
|
||||
if {$ingredient != ""} {
|
||||
set from [ingredient_path $config $ingredient]
|
||||
|
@ -231,6 +231,8 @@
|
||||
<child name="config_fs_report" label="managed -> nic_router"/> </service>
|
||||
<service name="Report" label="fb_config">
|
||||
<child name="config_fs_report" label="managed -> fb"/> </service>
|
||||
<service name="Report" label="nitpicker_config">
|
||||
<child name="config_fs_report" label="managed -> nitpicker"/> </service>
|
||||
<service name="Report" label="usb_config">
|
||||
<child name="config_fs_report" label="managed -> usb"/> </service>
|
||||
<service name="Report" label="system_config">
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include <model/screensaver.h>
|
||||
#include <model/system_state.h>
|
||||
#include <model/fb_config.h>
|
||||
#include <model/panorama_config.h>
|
||||
#include <view/download_status_widget.h>
|
||||
#include <view/popup_dialog.h>
|
||||
#include <view/panel_dialog.h>
|
||||
@ -1609,6 +1610,32 @@ struct Sculpt::Main : Input_event_handler,
|
||||
** Display driver configuration **
|
||||
**********************************/
|
||||
|
||||
Managed_config<Main> _nitpicker_config {
|
||||
_env, "config", "nitpicker", *this, &Main::_handle_nitpicker_config };
|
||||
|
||||
void _handle_nitpicker_config(Xml_node const &node)
|
||||
{
|
||||
_nitpicker_config.generate([&] (Xml_generator &xml) {
|
||||
copy_attributes(xml, node);
|
||||
node.for_each_sub_node([&] (Xml_node const &sub_node) {
|
||||
if (sub_node.has_type("capture") && sub_node.num_sub_nodes() == 0) {
|
||||
xml.node("capture", [&] {
|
||||
|
||||
/* generate panorama of fb-driver sessions */
|
||||
Panorama_config(_fb_config).gen_policy_entries(xml);
|
||||
|
||||
/* default policy for capture applications like screenshot */
|
||||
xml.node("default-policy", [&] { });
|
||||
});
|
||||
} else {
|
||||
copy_node(xml, sub_node, { 5 });
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Panorama_config _panorama_config { };
|
||||
|
||||
Fb_connectors _fb_connectors { };
|
||||
|
||||
Rom_handler<Main> _manual_fb_handler { _env, "config -> fb", *this, &Main::_handle_manual_fb };
|
||||
@ -1621,12 +1648,16 @@ struct Sculpt::Main : Input_event_handler,
|
||||
{
|
||||
_managed_fb_reporter.generate([&] (Xml_generator &xml) {
|
||||
_fb_config.generate_managed_fb(xml); });
|
||||
|
||||
/* update nitpicker config if the new fb config affects the panorama */
|
||||
Panorama_config const orig = _panorama_config;
|
||||
_panorama_config = Panorama_config(_fb_config);
|
||||
if (orig != Panorama_config(_fb_config))
|
||||
_nitpicker_config.trigger_update();
|
||||
}
|
||||
|
||||
void _handle_manual_fb(Xml_node const &node)
|
||||
{
|
||||
log("_handle_manual_fb: ", node);
|
||||
|
||||
_fb_config = { };
|
||||
_fb_config.import_manual_config(node);
|
||||
_fb_config.apply_connectors(_fb_connectors);
|
||||
@ -1734,6 +1765,7 @@ struct Sculpt::Main : Input_event_handler,
|
||||
_gui.input.sigh(_input_handler);
|
||||
_gui.info_sigh(_gui_mode_handler);
|
||||
_handle_gui_mode();
|
||||
_nitpicker_config.trigger_update();
|
||||
|
||||
/*
|
||||
* Generate initial configurations
|
||||
|
@ -326,7 +326,7 @@ struct Sculpt::Fb_config
|
||||
|
||||
struct Merge_info { Entry::Name name; Area px; };
|
||||
|
||||
void _with_merge_info(auto const &fn) const
|
||||
void with_merge_info(auto const &fn) const
|
||||
{
|
||||
Merge_info info { };
|
||||
|
||||
@ -354,7 +354,7 @@ struct Sculpt::Fb_config
|
||||
|
||||
void _gen_merge_node(Xml_generator &xml) const
|
||||
{
|
||||
_with_merge_info([&] (Merge_info const &info) {
|
||||
with_merge_info([&] (Merge_info const &info) {
|
||||
xml.node("merge", [&] {
|
||||
xml.attribute("width", info.px.w);
|
||||
xml.attribute("height", info.px.h);
|
||||
@ -388,6 +388,15 @@ struct Sculpt::Fb_config
|
||||
connectors.with_connector(entry.name, fn);
|
||||
}
|
||||
|
||||
void for_each_discrete_entry(auto const &fn) const
|
||||
{
|
||||
for (unsigned i = _num_merged; i < MAX_ENTRIES; i++) {
|
||||
Entry const &entry = _entries[i];
|
||||
if (entry.defined && entry.present)
|
||||
fn(entry);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned num_present_merged() const
|
||||
{
|
||||
unsigned count = 0;
|
||||
|
100
repos/gems/src/app/sculpt_manager/model/panorama_config.h
Normal file
100
repos/gems/src/app/sculpt_manager/model/panorama_config.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* \brief Representation of nitpicker's <capture> configuration
|
||||
* \author Norman Feske
|
||||
* \date 2024-10-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2024 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 _MODEL__PANORAMA_CONFIG_H_
|
||||
#define _MODEL__PANORAMA_CONFIG_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <model/fb_config.h>
|
||||
|
||||
namespace Sculpt { struct Panorama_config; };
|
||||
|
||||
|
||||
struct Sculpt::Panorama_config
|
||||
{
|
||||
struct Entry
|
||||
{
|
||||
using Name = Fb_config::Entry::Name;
|
||||
|
||||
Name name;
|
||||
Rect rect;
|
||||
|
||||
bool operator != (Entry const &other) const
|
||||
{
|
||||
return (name != other.name) || (rect != other.rect);
|
||||
}
|
||||
|
||||
void gen_policy(Xml_generator &xml) const
|
||||
{
|
||||
xml.node("policy", [&] {
|
||||
xml.attribute("label_suffix", name);
|
||||
xml.attribute("xpos", rect.x1());
|
||||
xml.attribute("ypos", rect.y1());
|
||||
xml.attribute("width", rect.w());
|
||||
xml.attribute("height", rect.h());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr unsigned MAX_ENTRIES = 16;
|
||||
|
||||
Entry _entries[MAX_ENTRIES] { };
|
||||
|
||||
unsigned _num_entries = 0;
|
||||
|
||||
Panorama_config() { };
|
||||
|
||||
Panorama_config(Fb_config const &fb_config)
|
||||
{
|
||||
int xpos = 0;
|
||||
|
||||
auto append = [&] (auto const &name, auto const area)
|
||||
{
|
||||
if (_num_entries == MAX_ENTRIES)
|
||||
return;
|
||||
|
||||
_entries[_num_entries] = Entry {
|
||||
.name = name,
|
||||
.rect = { .at = { .x = xpos, .y = 0 }, .area = area } };
|
||||
|
||||
_num_entries++;
|
||||
xpos += area.w;
|
||||
};
|
||||
|
||||
fb_config.with_merge_info([&] (Fb_config::Merge_info const &info) {
|
||||
append(info.name, info.px); });
|
||||
|
||||
fb_config.for_each_discrete_entry([&] (Fb_config::Entry const &entry) {
|
||||
append(entry.name, entry.mode_attr.px); });
|
||||
}
|
||||
|
||||
void gen_policy_entries(Xml_generator &xml) const
|
||||
{
|
||||
for (unsigned i = 0; i < _num_entries; i++)
|
||||
_entries[i].gen_policy(xml);
|
||||
}
|
||||
|
||||
bool operator != (Panorama_config const &other) const
|
||||
{
|
||||
if (other._num_entries != _num_entries)
|
||||
return true;
|
||||
|
||||
for (unsigned i = 0; i < _num_entries; i++)
|
||||
if (other._entries[i] != _entries[i])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _MODEL__PANORAMA_CONFIG_H_ */
|
Loading…
Reference in New Issue
Block a user