From 1195613fc633ea0f8956f0fdc200322d9f43b159 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sun, 13 Jul 2025 14:09:50 +0200 Subject: [PATCH] head-management: add format-info-v1 extension --- src/compositor.rs | 1 + src/ifs/head_management.rs | 14 ++++++ .../head_management/head_management_macros.rs | 1 + src/ifs/head_management/jay_head_ext.rs | 1 + .../jay_head_ext_format_info_v1.rs | 49 +++++++++++++++++++ src/state.rs | 3 ++ src/tasks/connector.rs | 1 + wire/jay_head_ext_format_info_v1.txt | 7 +++ wire/jay_head_manager_ext_format_info_v1.txt | 7 +++ 9 files changed, 84 insertions(+) create mode 100644 src/ifs/head_management/jay_head_ext/jay_head_ext_format_info_v1.rs create mode 100644 wire/jay_head_ext_format_info_v1.txt create mode 100644 wire/jay_head_manager_ext_format_info_v1.txt diff --git a/src/compositor.rs b/src/compositor.rs index 7ae496f6..47df6469 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -656,6 +656,7 @@ fn create_dummy_output(state: &Rc) { vrr: false, tearing_enabled: backend_state.tearing, tearing_active: false, + format: XRGB8888, }; let connector_data = Rc::new(ConnectorData { id, diff --git a/src/ifs/head_management.rs b/src/ifs/head_management.rs index 77e1e528..0ffba943 100644 --- a/src/ifs/head_management.rs +++ b/src/ifs/head_management.rs @@ -2,6 +2,7 @@ use { crate::{ backend::{ConnectorId, Mode, MonitorInfo, transaction::BackendConnectorTransactionError}, client::ClientId, + format::Format, globals::GlobalName, ifs::head_management::{ head_management_macros::HeadExts, jay_head_manager_session_v1::JayHeadManagerSessionV1, @@ -82,6 +83,7 @@ pub struct HeadState { pub vrr: bool, pub tearing_enabled: bool, pub tearing_active: bool, + pub format: &'static Format, } impl HeadState { @@ -406,4 +408,16 @@ impl HeadManagers { } } } + + pub fn handle_format_change(&self, format: &'static Format) { + let state = &mut *self.state.borrow_mut(); + state.format = format; + for head in self.managers.lock().values() { + skip_in_transaction!(head); + if let Some(ext) = &head.ext.format_info_v1 { + ext.send_format(state); + head.session.schedule_done(); + } + } + } } diff --git a/src/ifs/head_management/head_management_macros.rs b/src/ifs/head_management/head_management_macros.rs index b52b0d5c..92371a3e 100644 --- a/src/ifs/head_management/head_management_macros.rs +++ b/src/ifs/head_management/head_management_macros.rs @@ -401,4 +401,5 @@ declare_extensions! { non_desktop_info_v1: NonDesktopInfoV1, vrr_state_v1: VrrStateV1, tearing_state_v1: TearingStateV1, + format_info_v1: FormatInfoV1, } diff --git a/src/ifs/head_management/jay_head_ext.rs b/src/ifs/head_management/jay_head_ext.rs index c279a0f0..422b6511 100644 --- a/src/ifs/head_management/jay_head_ext.rs +++ b/src/ifs/head_management/jay_head_ext.rs @@ -5,6 +5,7 @@ pub(super) mod jay_head_ext_compositor_space_scaler_v1; pub(super) mod jay_head_ext_compositor_space_transformer_v1; pub(super) mod jay_head_ext_connector_info_v1; pub(super) mod jay_head_ext_core_info_v1; +pub(super) mod jay_head_ext_format_info_v1; pub(super) mod jay_head_ext_mode_info_v1; pub(super) mod jay_head_ext_mode_setter_v1; pub(super) mod jay_head_ext_non_desktop_info_v1; diff --git a/src/ifs/head_management/jay_head_ext/jay_head_ext_format_info_v1.rs b/src/ifs/head_management/jay_head_ext/jay_head_ext_format_info_v1.rs new file mode 100644 index 00000000..7f2605af --- /dev/null +++ b/src/ifs/head_management/jay_head_ext/jay_head_ext_format_info_v1.rs @@ -0,0 +1,49 @@ +use { + crate::{ + ifs::head_management::HeadState, + wire::{ + jay_head_ext_format_info_v1::{Format, JayHeadExtFormatInfoV1RequestHandler}, + jay_head_manager_ext_format_info_v1::JayHeadManagerExtFormatInfoV1RequestHandler, + }, + }, + std::rc::Rc, +}; + +impl_format_info_v1! { + version = 1, + after_announce = after_announce, + after_transaction = after_transaction, +} + +impl HeadName { + fn after_announce(&self, shared: &HeadState) { + self.send_format(shared); + } + + fn after_transaction(&self, shared: &HeadState, tran: &HeadState) { + if shared.format != tran.format { + self.send_format(shared); + } + } + + pub(in super::super) fn send_format(&self, state: &HeadState) { + self.client.event(Format { + self_id: self.id, + format: state.format.drm, + }); + } +} + +impl JayHeadManagerExtFormatInfoV1RequestHandler for MgrName { + type Error = ErrorName; + + mgr_common_req!(); +} + +impl JayHeadExtFormatInfoV1RequestHandler for HeadName { + type Error = ErrorName; + + head_common_req!(); +} + +error!(); diff --git a/src/state.rs b/src/state.rs index 2a651d0b..7da56328 100644 --- a/src/state.rs +++ b/src/state.rs @@ -459,6 +459,9 @@ impl ConnectorData { if old.tearing != s.tearing { self.head_managers.handle_tearing_enabled_change(s.tearing); } + if old.format != s.format { + self.head_managers.handle_format_change(s.format); + } if let Some(output) = state.outputs.get(&self.connector.id()) && let Some(node) = &output.node { diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index 9394d7ac..eb2f4ff5 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -62,6 +62,7 @@ pub fn handle(state: &Rc, connector: &Rc) { vrr: backend_state.vrr, tearing_enabled: backend_state.tearing, tearing_active: false, + format: backend_state.format, }; let data = Rc::new(ConnectorData { id, diff --git a/wire/jay_head_ext_format_info_v1.txt b/wire/jay_head_ext_format_info_v1.txt new file mode 100644 index 00000000..0e674f54 --- /dev/null +++ b/wire/jay_head_ext_format_info_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { + +} + +event format { + format: u32, +} diff --git a/wire/jay_head_manager_ext_format_info_v1.txt b/wire/jay_head_manager_ext_format_info_v1.txt new file mode 100644 index 00000000..04c360de --- /dev/null +++ b/wire/jay_head_manager_ext_format_info_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { + +} + +event head { + head: id(jay_head_ext_format_info_v1) (new), +}