diff --git a/src/ifs/head_management.rs b/src/ifs/head_management.rs index 7ce6b5cd..0d691b5f 100644 --- a/src/ifs/head_management.rs +++ b/src/ifs/head_management.rs @@ -128,6 +128,7 @@ enum HeadOp { SetMode(usize), SetNonDesktopOverride(Option), SetVrrMode(VrrMode), + SetTearingMode(TearingMode), } #[derive(Copy, Clone, Debug, Eq, PartialEq, Default)] diff --git a/src/ifs/head_management/head_management_macros.rs b/src/ifs/head_management/head_management_macros.rs index c4b36d3b..5b7dfcfa 100644 --- a/src/ifs/head_management/head_management_macros.rs +++ b/src/ifs/head_management/head_management_macros.rs @@ -407,4 +407,5 @@ declare_extensions! { jay_vrr_mode_info_v1: JayVrrModeInfoV1, jay_tearing_mode_info_v1: JayTearingModeInfoV1, jay_vrr_mode_setter_v1: JayVrrModeSetterV1, + jay_tearing_mode_setter_v1: JayTearingModeSetterV1, } diff --git a/src/ifs/head_management/jay_head_ext.rs b/src/ifs/head_management/jay_head_ext.rs index 345e5a24..e5ca8933 100644 --- a/src/ifs/head_management/jay_head_ext.rs +++ b/src/ifs/head_management/jay_head_ext.rs @@ -8,6 +8,7 @@ pub(super) mod jay_head_ext_core_info_v1; pub(super) mod jay_head_ext_drm_color_space_info_v1; pub(super) mod jay_head_ext_format_info_v1; pub(super) mod jay_head_ext_jay_tearing_mode_info_v1; +pub(super) mod jay_head_ext_jay_tearing_mode_setter_v1; pub(super) mod jay_head_ext_jay_vrr_mode_info_v1; pub(super) mod jay_head_ext_jay_vrr_mode_setter_v1; pub(super) mod jay_head_ext_mode_info_v1; diff --git a/src/ifs/head_management/jay_head_ext/jay_head_ext_jay_tearing_mode_setter_v1.rs b/src/ifs/head_management/jay_head_ext/jay_head_ext_jay_tearing_mode_setter_v1.rs new file mode 100644 index 00000000..4c8a5f96 --- /dev/null +++ b/src/ifs/head_management/jay_head_ext/jay_head_ext_jay_tearing_mode_setter_v1.rs @@ -0,0 +1,61 @@ +use { + crate::{ + ifs::head_management::{HeadOp, HeadState}, + wire::{ + jay_head_ext_jay_tearing_mode_setter_v1::{ + JayHeadExtJayTearingModeSetterV1RequestHandler, SetMode, SupportedMode, + }, + jay_head_manager_ext_jay_tearing_mode_setter_v1::JayHeadManagerExtJayTearingModeSetterV1RequestHandler, + }, + }, + jay_config::video::TearingMode, + std::rc::Rc, +}; + +impl_jay_tearing_mode_setter_v1! { + version = 1, + after_announce = after_announce, +} + +impl HeadName { + fn after_announce(&self, _shared: &HeadState) { + self.send_supported_mode(TearingMode::NEVER); + self.send_supported_mode(TearingMode::ALWAYS); + self.send_supported_mode(TearingMode::VARIANT_1); + self.send_supported_mode(TearingMode::VARIANT_2); + self.send_supported_mode(TearingMode::VARIANT_3); + } + + pub(in super::super) fn send_supported_mode(&self, mode: TearingMode) { + self.client.event(SupportedMode { + self_id: self.id, + mode: mode.0, + }); + } +} + +impl JayHeadManagerExtJayTearingModeSetterV1RequestHandler for MgrName { + type Error = ErrorName; + + mgr_common_req!(); +} + +impl JayHeadExtJayTearingModeSetterV1RequestHandler for HeadName { + type Error = ErrorName; + + head_common_req!(); + + fn set_mode(&self, req: SetMode, _slf: &Rc) -> Result<(), Self::Error> { + if req.mode > TearingMode::VARIANT_3.0 { + return Err(ErrorName::UnknownMode(req.mode)); + } + self.common + .push_op(HeadOp::SetTearingMode(TearingMode(req.mode)))?; + Ok(()) + } +} + +error! { + #[error("Unknown tearing mode {0}")] + UnknownMode(u32), +} diff --git a/src/ifs/head_management/jay_head_manager_session_v1.rs b/src/ifs/head_management/jay_head_manager_session_v1.rs index 9d098579..c049c315 100644 --- a/src/ifs/head_management/jay_head_manager_session_v1.rs +++ b/src/ifs/head_management/jay_head_manager_session_v1.rs @@ -386,6 +386,7 @@ impl JayHeadManagerSessionV1RequestHandler for JayHeadManagerSessionV1 { MODE_INFO = 1 << 6, NON_DESKTOP_INFO = 1 << 7, VRR_MODE_INFO = 1 << 8, + TEARING_MODE_INFO = 1 << 9, COMPOSITOR_SPACE_INFO_ENABLED = 1 << 13, } for head in self.heads.lock().values() { @@ -435,6 +436,10 @@ impl JayHeadManagerSessionV1RequestHandler for JayHeadManagerSessionV1 { state.vrr_mode = m; to_send |= VRR_MODE_INFO; } + HeadOp::SetTearingMode(m) => { + state.tearing_mode = m; + to_send |= TEARING_MODE_INFO; + } } } if to_send.contains(CORE_INFO) @@ -478,6 +483,11 @@ impl JayHeadManagerSessionV1RequestHandler for JayHeadManagerSessionV1 { { i.send_mode(state); } + if to_send.contains(TEARING_MODE_INFO) + && let Some(i) = &head.ext.jay_tearing_mode_info_v1 + { + i.send_mode(state); + } } slf.schedule_transaction_result(req.result, None)?; Ok(()) @@ -514,6 +524,7 @@ impl JayHeadManagerSessionV1RequestHandler for JayHeadManagerSessionV1 { node.set_preferred_scale(desired.scale); node.update_transform(desired.transform); node.set_vrr_mode(VrrMode::from_config(desired.vrr_mode).unwrap()); + node.set_tearing_mode(TearingMode::from_config(desired.tearing_mode).unwrap()); } else if let Some(mi) = &desired.monitor_info { let pos = &self.client.state.persistent_output_states; let pos = match pos.get(&mi.output_id) { @@ -537,6 +548,8 @@ impl JayHeadManagerSessionV1RequestHandler for JayHeadManagerSessionV1 { pos.transform.set(desired.transform); pos.vrr_mode .set(VrrMode::from_config(desired.vrr_mode).unwrap()); + pos.tearing_mode + .set(TearingMode::from_config(desired.tearing_mode).unwrap()); } } slf.schedule_transaction_result(req.result, None)?; diff --git a/wire/jay_head_ext_jay_tearing_mode_setter_v1.txt b/wire/jay_head_ext_jay_tearing_mode_setter_v1.txt new file mode 100644 index 00000000..34288cf8 --- /dev/null +++ b/wire/jay_head_ext_jay_tearing_mode_setter_v1.txt @@ -0,0 +1,15 @@ +request destroy (destructor) { + +} + +event reset { + +} + +event supported_mode { + mode: u32, +} + +request set_mode { + mode: u32, +} diff --git a/wire/jay_head_manager_ext_jay_tearing_mode_setter_v1.txt b/wire/jay_head_manager_ext_jay_tearing_mode_setter_v1.txt new file mode 100644 index 00000000..1f5e9efa --- /dev/null +++ b/wire/jay_head_manager_ext_jay_tearing_mode_setter_v1.txt @@ -0,0 +1,7 @@ +request destroy (destructor) { + +} + +event head { + head: id(jay_head_ext_jay_tearing_mode_setter_v1) (new), +}