mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 06:07:59 +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>
|
</provides>
|
||||||
<route>
|
<route>
|
||||||
<service name="ROM" label="config">
|
<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">
|
<service name="ROM" label="focus">
|
||||||
<child name="nit_focus"/> </service>
|
<child name="nit_focus"/> </service>
|
||||||
<service name="Report" label="panorama">
|
<service name="Report" label="panorama">
|
||||||
@ -848,7 +848,7 @@ set fd [open [managed_config_path depot_query] w]
|
|||||||
puts $fd "<query/>"
|
puts $fd "<query/>"
|
||||||
close $fd
|
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"]
|
set ingredient [single_ingredient $config "default"]
|
||||||
if {$ingredient != ""} {
|
if {$ingredient != ""} {
|
||||||
set from [ingredient_path $config $ingredient]
|
set from [ingredient_path $config $ingredient]
|
||||||
|
@ -231,6 +231,8 @@
|
|||||||
<child name="config_fs_report" label="managed -> nic_router"/> </service>
|
<child name="config_fs_report" label="managed -> nic_router"/> </service>
|
||||||
<service name="Report" label="fb_config">
|
<service name="Report" label="fb_config">
|
||||||
<child name="config_fs_report" label="managed -> fb"/> </service>
|
<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">
|
<service name="Report" label="usb_config">
|
||||||
<child name="config_fs_report" label="managed -> usb"/> </service>
|
<child name="config_fs_report" label="managed -> usb"/> </service>
|
||||||
<service name="Report" label="system_config">
|
<service name="Report" label="system_config">
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <model/screensaver.h>
|
#include <model/screensaver.h>
|
||||||
#include <model/system_state.h>
|
#include <model/system_state.h>
|
||||||
#include <model/fb_config.h>
|
#include <model/fb_config.h>
|
||||||
|
#include <model/panorama_config.h>
|
||||||
#include <view/download_status_widget.h>
|
#include <view/download_status_widget.h>
|
||||||
#include <view/popup_dialog.h>
|
#include <view/popup_dialog.h>
|
||||||
#include <view/panel_dialog.h>
|
#include <view/panel_dialog.h>
|
||||||
@ -1609,6 +1610,32 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
** Display driver configuration **
|
** 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 { };
|
Fb_connectors _fb_connectors { };
|
||||||
|
|
||||||
Rom_handler<Main> _manual_fb_handler { _env, "config -> fb", *this, &Main::_handle_manual_fb };
|
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) {
|
_managed_fb_reporter.generate([&] (Xml_generator &xml) {
|
||||||
_fb_config.generate_managed_fb(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)
|
void _handle_manual_fb(Xml_node const &node)
|
||||||
{
|
{
|
||||||
log("_handle_manual_fb: ", node);
|
|
||||||
|
|
||||||
_fb_config = { };
|
_fb_config = { };
|
||||||
_fb_config.import_manual_config(node);
|
_fb_config.import_manual_config(node);
|
||||||
_fb_config.apply_connectors(_fb_connectors);
|
_fb_config.apply_connectors(_fb_connectors);
|
||||||
@ -1734,6 +1765,7 @@ struct Sculpt::Main : Input_event_handler,
|
|||||||
_gui.input.sigh(_input_handler);
|
_gui.input.sigh(_input_handler);
|
||||||
_gui.info_sigh(_gui_mode_handler);
|
_gui.info_sigh(_gui_mode_handler);
|
||||||
_handle_gui_mode();
|
_handle_gui_mode();
|
||||||
|
_nitpicker_config.trigger_update();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate initial configurations
|
* Generate initial configurations
|
||||||
|
@ -326,7 +326,7 @@ struct Sculpt::Fb_config
|
|||||||
|
|
||||||
struct Merge_info { Entry::Name name; Area px; };
|
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 { };
|
Merge_info info { };
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ struct Sculpt::Fb_config
|
|||||||
|
|
||||||
void _gen_merge_node(Xml_generator &xml) const
|
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.node("merge", [&] {
|
||||||
xml.attribute("width", info.px.w);
|
xml.attribute("width", info.px.w);
|
||||||
xml.attribute("height", info.px.h);
|
xml.attribute("height", info.px.h);
|
||||||
@ -388,6 +388,15 @@ struct Sculpt::Fb_config
|
|||||||
connectors.with_connector(entry.name, fn);
|
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 num_present_merged() const
|
||||||
{
|
{
|
||||||
unsigned count = 0;
|
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