sculpt_manager: fb unplug, sanitize conn. model

This patch explicitly handles the unplugging of displays, avoiding the
use of stale connectors for defining the panorama. It also makes the
import of the connectors model robust against intermediate states
reported by the driver (a connector reported as connector but without
any mode), and discards the use of any information of non-present
connectors as merge info.

Issue #5286
This commit is contained in:
Norman Feske 2024-10-29 12:13:44 +01:00 committed by Christian Helmuth
parent e1909da501
commit baedd79f62
2 changed files with 21 additions and 18 deletions

View File

@ -218,6 +218,14 @@ struct Sculpt::Fb_config
}); });
}); });
/* detect unplugging */
for (Entry &entry : _entries) {
bool connected = false;
connectors.with_connector(entry.name, [&] (auto &) { connected = true; });
if (!connected)
entry.present = false;
}
connectors._merged.for_each([&] (Fb_connectors::Connector const &conn) { connectors._merged.for_each([&] (Fb_connectors::Connector const &conn) {
if (!_known(conn.name)) if (!_known(conn.name))
_add_unknown_merged(Entry::from_connector(conn)); }); _add_unknown_merged(Entry::from_connector(conn)); });
@ -328,28 +336,22 @@ struct Sculpt::Fb_config
void with_merge_info(auto const &fn) const void with_merge_info(auto const &fn) const
{ {
Merge_info info { };
/* merged screen size and name corresponds to first enabled connector */ /* merged screen size and name corresponds to first enabled connector */
for (unsigned i = 0; i < _num_merged; i++) { for (unsigned i = 0; i < _num_merged; i++) {
info = { .name = _entries[i].name, if (_entries[i].present && _entries[i].mode_attr.px.valid()) {
.px = _entries[i].mode_attr.px }; fn({ .name = _entries[i].name,
if (info.px.valid() && _entries[i].present) .px = _entries[i].mode_attr.px });
break; return;
}
/* if all merged connectors are switched of, use name of first one */
if (!info.px.valid()) {
for (unsigned i = 0; i < _num_merged; i++) {
info = { .name = _entries[i].name,
.px = _entries[i].mode_attr.px };
if (_entries[i].present)
break;
} }
} }
if (info.name.length() > 1) /* if all merged connectors are switched off, use name of first present one */
fn(info); for (unsigned i = 0; i < _num_merged; i++) {
if (_entries[i].present) {
fn({ .name = _entries[i].name, .px = { }});
return;
}
}
}; };
void _gen_merge_node(Xml_generator &xml) const void _gen_merge_node(Xml_generator &xml) const

View File

@ -207,7 +207,8 @@ struct Sculpt::Fb_connectors : private Noncopyable
static bool type_matches(Xml_node const &node) static bool type_matches(Xml_node const &node)
{ {
return node.has_type("connector") return node.has_type("connector")
&& node.attribute_value("connected", false); && node.attribute_value("connected", false)
&& node.has_sub_node("mode");
} }
}; };