diff --git a/src/ifs/head_management.rs b/src/ifs/head_management.rs index 2333ff88..2ee688ce 100644 --- a/src/ifs/head_management.rs +++ b/src/ifs/head_management.rs @@ -219,6 +219,10 @@ impl HeadManagers { ext.send_connected(state); head.session.schedule_done(); } + if let Some(ext) = &head.ext.physical_display_info_v1 { + ext.send_info(state); + head.session.schedule_done(); + } if let Some(ext) = &head.ext.mode_info_v1 { ext.send_mode(state); head.session.schedule_done(); @@ -257,6 +261,10 @@ impl HeadManagers { ext.send_wl_output(state); head.session.schedule_done(); } + if let Some(ext) = &head.ext.physical_display_info_v1 { + ext.send_info(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 1149819a..30a78cd5 100644 --- a/src/ifs/head_management/head_management_macros.rs +++ b/src/ifs/head_management/head_management_macros.rs @@ -397,4 +397,5 @@ declare_extensions! { connector_info_v1: ConnectorInfoV1, mode_info_v1: ModeInfoV1, mode_setter_v1: ModeSetterV1, + physical_display_info_v1: PhysicalDisplayInfoV1, } diff --git a/src/ifs/head_management/jay_head_ext.rs b/src/ifs/head_management/jay_head_ext.rs index 427b5ea5..ac41e1c7 100644 --- a/src/ifs/head_management/jay_head_ext.rs +++ b/src/ifs/head_management/jay_head_ext.rs @@ -7,3 +7,4 @@ pub(super) mod jay_head_ext_connector_info_v1; pub(super) mod jay_head_ext_core_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_physical_display_info_v1; diff --git a/src/ifs/head_management/jay_head_ext/jay_head_ext_physical_display_info_v1.rs b/src/ifs/head_management/jay_head_ext/jay_head_ext_physical_display_info_v1.rs new file mode 100644 index 00000000..f927259f --- /dev/null +++ b/src/ifs/head_management/jay_head_ext/jay_head_ext_physical_display_info_v1.rs @@ -0,0 +1,125 @@ +use { + crate::{ + backend::{self, CONCAP_PHYSICAL_DISPLAY}, + ifs::head_management::{HeadCommon, HeadState}, + state::ConnectorData, + wire::{ + jay_head_ext_physical_display_info_v1::{ + JayHeadExtPhysicalDisplayInfoV1RequestHandler, Manufacturer, Mode, Model, + NonDesktop, PhysicalSize, Reset, SerialNumber, VrrCapable, + }, + jay_head_manager_ext_physical_display_info_v1::JayHeadManagerExtPhysicalDisplayInfoV1RequestHandler, + }, + }, + std::rc::Rc, +}; + +impl_physical_display_info_v1! { + version = 1, + filter = filter, + after_announce = after_announce, + after_transaction = after_transaction, +} + +impl MgrName { + fn filter(&self, connector: &ConnectorData, _common: &Rc) -> bool { + connector.connector.caps().contains(CONCAP_PHYSICAL_DISPLAY) + } +} + +impl HeadName { + fn after_announce(&self, shared: &HeadState) { + self.send_info(shared); + } + + fn after_transaction(&self, shared: &HeadState, tran: &HeadState) { + match (&shared.monitor_info, &tran.monitor_info) { + (Some(s), Some(t)) if s != t => {} + _ => return, + } + self.send_info(shared); + } + + pub(in super::super) fn send_info(&self, state: &HeadState) { + self.send_reset(); + if let Some(mi) = &state.monitor_info { + for mode in &mi.modes { + self.send_mode(mode); + } + self.send_manufacturer(&mi.output_id.manufacturer); + self.send_model(&mi.output_id.model); + self.send_serial_number(&mi.output_id.serial_number); + self.send_physical_size(mi.width_mm, mi.height_mm); + if mi.non_desktop { + self.send_non_desktop(); + } + if mi.vrr_capable { + self.send_vrr_capable(); + } + } + } + + fn send_reset(&self) { + self.client.event(Reset { self_id: self.id }); + } + + fn send_mode(&self, mode: &backend::Mode) { + self.client.event(Mode { + self_id: self.id, + width: mode.width, + height: mode.height, + refresh_mhz: mode.refresh_rate_millihz, + }); + } + + fn send_physical_size(&self, width_mm: i32, height_mm: i32) { + self.client.event(PhysicalSize { + self_id: self.id, + width_mm, + height_mm, + }); + } + + fn send_manufacturer(&self, manufacturer: &str) { + self.client.event(Manufacturer { + self_id: self.id, + manufacturer, + }); + } + + fn send_model(&self, model: &str) { + self.client.event(Model { + self_id: self.id, + model, + }); + } + + fn send_serial_number(&self, serial_number: &str) { + self.client.event(SerialNumber { + self_id: self.id, + serial_number, + }); + } + + fn send_non_desktop(&self) { + self.client.event(NonDesktop { self_id: self.id }); + } + + fn send_vrr_capable(&self) { + self.client.event(VrrCapable { self_id: self.id }); + } +} + +impl JayHeadManagerExtPhysicalDisplayInfoV1RequestHandler for MgrName { + type Error = ErrorName; + + mgr_common_req!(); +} + +impl JayHeadExtPhysicalDisplayInfoV1RequestHandler for HeadName { + type Error = ErrorName; + + head_common_req!(); +} + +error!(); diff --git a/wire/jay_head_ext_physical_display_info_v1.txt b/wire/jay_head_ext_physical_display_info_v1.txt new file mode 100644 index 00000000..af4e0a9f --- /dev/null +++ b/wire/jay_head_ext_physical_display_info_v1.txt @@ -0,0 +1,38 @@ +request destroy (destructor) { + +} + +event reset { + +} + +event mode { + width: i32, + height: i32, + refresh_mhz: u32, +} + +event physical_size { + width_mm: i32, + height_mm: i32, +} + +event manufacturer { + manufacturer: str, +} + +event model { + model: str, +} + +event serial_number { + serial_number: str, +} + +event non_desktop { + +} + +event vrr_capable { + +} diff --git a/wire/jay_head_manager_ext_physical_display_info_v1.txt b/wire/jay_head_manager_ext_physical_display_info_v1.txt new file mode 100644 index 00000000..1c99a82a --- /dev/null +++ b/wire/jay_head_manager_ext_physical_display_info_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { + +} + +event head { + head: id(jay_head_ext_physical_display_info_v1) (new), +}