From e74eafce2c45cffb7419e749aca58d921b47538a Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 24 Mar 2025 15:20:22 -0700 Subject: [PATCH] Add `EdidProduct`, as user data for kms `Output`s This is the same as `libdisplay_info::edid::VendorProduct`, but with implementations for `Serialize`, `Eq`, etc. --- src/backend/kms/device.rs | 12 +++++++++--- src/config/mod.rs | 23 +++++++++++++++++++++++ src/utils/prelude.rs | 8 +++++++- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/backend/kms/device.rs b/src/backend/kms/device.rs index 3409a954..19ed5818 100644 --- a/src/backend/kms/device.rs +++ b/src/backend/kms/device.rs @@ -2,7 +2,7 @@ use crate::{ backend::render::{output_elements, CursorMode, GlMultiRenderer, CLEAR_COLOR}, - config::{AdaptiveSync, OutputConfig, OutputState, ScreenFilter}, + config::{AdaptiveSync, EdidProduct, OutputConfig, OutputState, ScreenFilter}, shell::Shell, utils::prelude::*, wayland::protocols::screencopy::Frame as ScreencopyFrame, @@ -743,7 +743,7 @@ fn create_output_for_conn(drm: &mut DrmDevice, conn: connector::Handle) -> Resul .ok(); let (phys_w, phys_h) = conn_info.size().unwrap_or((0, 0)); - Ok(Output::new( + let output = Output::new( interface, PhysicalProperties { size: (phys_w as i32, phys_h as i32).into(), @@ -764,7 +764,13 @@ fn create_output_for_conn(drm: &mut DrmDevice, conn: connector::Handle) -> Resul .and_then(|info| info.model()) .unwrap_or_else(|| String::from("Unknown")), }, - )) + ); + if let Some(edid) = edid_info.as_ref().and_then(|x| x.edid()) { + output + .user_data() + .insert_if_missing(|| EdidProduct::from(edid.vendor_product())); + } + Ok(output) } fn populate_modes( diff --git a/src/config/mod.rs b/src/config/mod.rs index 6d33d955..bc72918e 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -94,6 +94,29 @@ impl From for OutputInfo { } } +#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct EdidProduct { + pub manufacturer: [char; 3], + pub product: u16, + pub serial: Option, + pub manufacture_week: i32, + pub manufacture_year: i32, + pub model_year: Option, +} + +impl From for EdidProduct { + fn from(vp: libdisplay_info::edid::VendorProduct) -> Self { + Self { + manufacturer: vp.manufacturer, + product: vp.product, + serial: vp.serial, + manufacture_week: vp.manufacture_week, + manufacture_year: vp.manufacture_year, + model_year: vp.model_year, + } + } +} + #[derive(Default, Debug, Deserialize, Serialize)] pub struct NumlockStateConfig { pub last_state: bool, diff --git a/src/utils/prelude.rs b/src/utils/prelude.rs index f7952459..bb30272a 100644 --- a/src/utils/prelude.rs +++ b/src/utils/prelude.rs @@ -9,7 +9,7 @@ pub use crate::shell::{SeatExt, Shell, Workspace}; pub use crate::state::{Common, State}; pub use crate::wayland::handlers::xdg_shell::popup::update_reactive_popups; use crate::{ - config::{AdaptiveSync, OutputConfig, OutputState}, + config::{AdaptiveSync, EdidProduct, OutputConfig, OutputState}, shell::zoom::OutputZoomState, }; @@ -35,6 +35,8 @@ pub trait OutputExt { fn is_enabled(&self) -> bool; fn config(&self) -> Ref<'_, OutputConfig>; fn config_mut(&self) -> RefMut<'_, OutputConfig>; + + fn edid(&self) -> Option<&EdidProduct>; } struct Vrr(AtomicU8); @@ -158,4 +160,8 @@ impl OutputExt for Output { .unwrap() .borrow_mut() } + + fn edid(&self) -> Option<&EdidProduct> { + self.user_data().get() + } }