diff --git a/Cargo.lock b/Cargo.lock index 0ecace0d..a68a5bf4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ab_glyph" @@ -91,7 +91,7 @@ dependencies = [ "ndk-context", "ndk-sys 0.6.0+11769913", "num_enum", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -508,7 +508,7 @@ dependencies = [ "polling", "rustix", "slab", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -553,6 +553,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cfg-expr" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d4ba6e40bd1184518716a6e1a781bf9160e286d219ccdb8ab2612e74cfe4789" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -630,7 +640,7 @@ name = "clipboard_x11" version = "0.4.2" source = "git+https://github.com/pop-os/window_clipboard.git?tag=pop-0.13#a83bf83784276aaa882ef13555295a2ad9edd265" dependencies = [ - "thiserror", + "thiserror 1.0.69", "x11rb", ] @@ -803,7 +813,6 @@ dependencies = [ "cosmic-protocols", "cosmic-settings-config", "drm-ffi 0.8.0", - "edid-rs", "egui", "egui_plot", "glow 0.12.3", @@ -816,6 +825,7 @@ dependencies = [ "lazy_static", "libc", "libcosmic", + "libdisplay-info", "libsystemd", "log-panics", "once_cell", @@ -835,7 +845,7 @@ dependencies = [ "smallvec", "smithay", "smithay-egui", - "thiserror", + "thiserror 1.0.69", "time", "tiny-skia", "tracing", @@ -908,7 +918,7 @@ dependencies = [ "cosmic-config", "serde", "serde_with", - "thiserror", + "thiserror 1.0.69", "tracing", "xkbcommon 0.7.0", ] @@ -950,7 +960,7 @@ dependencies = [ "ron", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1338,12 +1348,6 @@ dependencies = [ "emath", ] -[[package]] -name = "edid-rs" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab5fa33485cd85ac354df485819a63360fefa312fe04cffe65e6f175be1522c" - [[package]] name = "egui" version = "0.29.0" @@ -1674,7 +1678,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d" dependencies = [ - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1783,7 +1787,7 @@ dependencies = [ "dirs", "once_cell", "rust-ini", - "thiserror", + "thiserror 1.0.69", "xdg", ] @@ -2070,7 +2074,7 @@ checksum = "fdd4240fc91d3433d5e5b0fc5b67672d771850dc19bbee03c1381e19322803d7" dependencies = [ "log", "presser", - "thiserror", + "thiserror 1.0.69", "winapi", "windows 0.52.0", ] @@ -2147,7 +2151,7 @@ dependencies = [ "com", "libc", "libloading", - "thiserror", + "thiserror 1.0.69", "widestring", "winapi", ] @@ -2158,6 +2162,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -2209,7 +2219,7 @@ dependencies = [ "log", "serde", "serde_derive", - "thiserror", + "thiserror 1.0.69", "toml 0.8.19", "unic-langid", ] @@ -2231,7 +2241,7 @@ dependencies = [ "log", "parking_lot 0.12.3", "rust-embed", - "thiserror", + "thiserror 1.0.69", "unic-langid", "walkdir", ] @@ -2305,7 +2315,7 @@ dependencies = [ "iced_widget", "image", "mime 0.1.0", - "thiserror", + "thiserror 1.0.69", "window_clipboard", ] @@ -2327,7 +2337,7 @@ dependencies = [ "rustc-hash 2.0.0", "serde", "smol_str", - "thiserror", + "thiserror 1.0.69", "web-time", "window_clipboard", ] @@ -2375,7 +2385,7 @@ dependencies = [ "once_cell", "raw-window-handle", "rustc-hash 2.0.0", - "thiserror", + "thiserror 1.0.69", "unicode-segmentation", ] @@ -2388,7 +2398,7 @@ dependencies = [ "iced_tiny_skia", "iced_wgpu", "log", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2401,7 +2411,7 @@ dependencies = [ "iced_core", "iced_futures", "raw-window-handle", - "thiserror", + "thiserror 1.0.69", "window_clipboard", ] @@ -2442,7 +2452,7 @@ dependencies = [ "rustc-hash 2.0.0", "rustix", "smithay-client-toolkit", - "thiserror", + "thiserror 1.0.69", "tiny-xlib", "wayland-backend", "wayland-client", @@ -2464,7 +2474,7 @@ dependencies = [ "once_cell", "ouroboros", "rustc-hash 2.0.0", - "thiserror", + "thiserror 1.0.69", "unicode-segmentation", "window_clipboard", ] @@ -2472,7 +2482,7 @@ dependencies = [ [[package]] name = "id_tree" version = "1.8.0" -source = "git+https://github.com/Drakulix/id-tree.git?branch=feature/copy_clone#632a57d6d49160e18d7300fa7edae52281ec5482" +source = "git+https://github.com/Drakulix/id-tree.git?branch=feature%2Fcopy_clone#632a57d6d49160e18d7300fa7edae52281ec5482" dependencies = [ "snowflake", ] @@ -2649,7 +2659,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] @@ -2823,13 +2833,47 @@ dependencies = [ "serde", "slotmap", "taffy", - "thiserror", + "thiserror 1.0.69", "tracing", "unicode-segmentation", "url", "ustr", ] +[[package]] +name = "libdisplay-info" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6935962382041461121f7989421174ad72f157aca74706d46bd302563246f5cf" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libdisplay-info-derive", + "libdisplay-info-sys", + "thiserror 2.0.9", +] + +[[package]] +name = "libdisplay-info-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea1cd31036b732a546d845f9485c56b1b606b5e476b0821c680dd66c8cd6fcee" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + +[[package]] +name = "libdisplay-info-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b86dd88c4008cfe67bafd1e65827a380df933a00e50bc497cf2474ca723863d" +dependencies = [ + "semver", + "system-deps", +] + [[package]] name = "libloading" version = "0.8.5" @@ -2901,7 +2945,7 @@ dependencies = [ "once_cell", "serde", "sha2", - "thiserror", + "thiserror 1.0.69", "uuid", ] @@ -3190,7 +3234,7 @@ dependencies = [ "rustc-hash 1.1.0", "spirv", "termcolor", - "thiserror", + "thiserror 1.0.69", "unicode-xid", ] @@ -3206,7 +3250,7 @@ dependencies = [ "ndk-sys 0.6.0+11769913", "num_enum", "raw-window-handle", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3667,7 +3711,7 @@ version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39b0deead1528fd0e5947a8546a9642a9777c25f6e1e26f34c97b204bbb465bd" dependencies = [ - "heck", + "heck 0.4.1", "itertools", "proc-macro2", "proc-macro2-diagnostics", @@ -3881,7 +3925,7 @@ dependencies = [ "drm-fourcc", "paste", "pixman-sys", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4166,7 +4210,7 @@ checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox 0.1.3", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -4442,6 +4486,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" +[[package]] +name = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + [[package]] name = "sendfd" version = "0.4.3" @@ -4670,7 +4720,7 @@ dependencies = [ "scopeguard", "smallvec", "tempfile", - "thiserror", + "thiserror 1.0.69", "tracing", "udev", "wayland-client", @@ -4701,7 +4751,7 @@ dependencies = [ "memmap2 0.9.4", "pkg-config", "rustix", - "thiserror", + "thiserror 1.0.69", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -4904,6 +4954,19 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "7.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d23aaf9f331227789a99e8de4c91bf46703add012bdfd45fdecdfb2975a005" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml 0.8.19", + "version-compare", +] + [[package]] name = "taffy" version = "0.3.11" @@ -4915,6 +4978,12 @@ dependencies = [ "slotmap", ] +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "tempfile" version = "3.10.1" @@ -4942,7 +5011,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +dependencies = [ + "thiserror-impl 2.0.9", ] [[package]] @@ -4956,6 +5034,17 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "thiserror-impl" +version = "2.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -5498,6 +5587,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" @@ -5821,7 +5916,7 @@ dependencies = [ "raw-window-handle", "rustc-hash 1.1.0", "smallvec", - "thiserror", + "thiserror 1.0.69", "wgpu-hal", "wgpu-types", ] @@ -5864,7 +5959,7 @@ dependencies = [ "renderdoc-sys", "rustc-hash 1.1.0", "smallvec", - "thiserror", + "thiserror 1.0.69", "wasm-bindgen", "web-sys", "wgpu-types", @@ -5931,7 +6026,7 @@ dependencies = [ "dnd", "mime 0.1.0", "raw-window-handle", - "thiserror", + "thiserror 1.0.69", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6cb86229..6fabcced 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ cosmic-comp-config = {path = "cosmic-comp-config"} cosmic-config = {git = "https://github.com/pop-os/libcosmic/", features = ["calloop", "macro"]} cosmic-protocols = {git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"]} cosmic-settings-config = { git = "https://github.com/pop-os/cosmic-settings-daemon" } -edid-rs = {version = "0.1"} +libdisplay-info = "0.2.0" egui = {version = "0.29.0", optional = true} egui_plot = {version = "0.29.0", optional = true} glow = "0.12.0" diff --git a/src/backend/kms/device.rs b/src/backend/kms/device.rs index f5a0e725..57123d9b 100644 --- a/src/backend/kms/device.rs +++ b/src/backend/kms/device.rs @@ -677,7 +677,9 @@ fn create_output_for_conn(drm: &mut DrmDevice, conn: connector::Handle) -> Resul .get_connector(conn, false) .with_context(|| "Failed to query connector info")?; let interface = drm_helpers::interface_name(drm, conn)?; - let edid_info = drm_helpers::edid_info(drm, conn); + let edid_info = drm_helpers::edid_info(drm, conn) + .inspect_err(|err| warn!(?err, "failed to get EDID for {}", interface)) + .ok(); let (phys_w, phys_h) = conn_info.size().unwrap_or((0, 0)); Ok(Output::new( @@ -694,12 +696,12 @@ fn create_output_for_conn(drm: &mut DrmDevice, conn: connector::Handle) -> Resul }, make: edid_info .as_ref() - .map(|info| info.manufacturer.clone()) - .unwrap_or_else(|_| String::from("Unknown")), + .and_then(|info| info.make()) + .unwrap_or_else(|| String::from("Unknown")), model: edid_info .as_ref() - .map(|info| info.model.clone()) - .unwrap_or_else(|_| String::from("Unknown")), + .and_then(|info| info.model()) + .unwrap_or_else(|| String::from("Unknown")), }, )) } diff --git a/src/backend/kms/drm_helpers.rs b/src/backend/kms/drm_helpers.rs index 0b7cdc3b..3cc90592 100644 --- a/src/backend/kms/drm_helpers.rs +++ b/src/backend/kms/drm_helpers.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-only -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; +use libdisplay_info::{edid::DisplayDescriptorTag, info::Info}; use smithay::{ reexports::drm::control::{ atomic::AtomicModeReq, @@ -12,11 +13,7 @@ use smithay::{ }, utils::Transform, }; -use std::{ - collections::HashMap, - ops::Range, - panic::{catch_unwind, AssertUnwindSafe}, -}; +use std::{collections::HashMap, ops::Range}; pub fn display_configuration( device: &mut impl ControlDevice, @@ -169,59 +166,24 @@ pub fn interface_name(device: &impl ControlDevice, connector: connector::Handle) )) } -pub struct EdidInfo { - pub model: String, - pub manufacturer: String, -} - -pub fn edid_info(device: &impl ControlDevice, connector: connector::Handle) -> Result { - use edid_rs::{parse as edid_parse, MonitorDescriptor}; - +pub fn edid_info(device: &impl ControlDevice, connector: connector::Handle) -> Result { let edid_prop = get_prop(device, connector, "EDID")?; let edid_info = device.get_property(edid_prop)?; - let mut manufacturer = "Unknown".into(); - let mut model = "Unknown".into(); + + let mut edid = None; let props = device.get_properties(connector)?; let (ids, vals) = props.as_props_and_values(); for (&id, &val) in ids.iter().zip(vals.iter()) { if id == edid_prop { if let property::Value::Blob(edid_blob) = edid_info.value_type().convert_value(val) { let blob = device.get_property_blob(edid_blob)?; - let mut reader = std::io::Cursor::new(blob); - if let Some(edid) = - catch_unwind(AssertUnwindSafe(move || edid_parse(&mut reader).ok())) - .ok() - .flatten() - { - manufacturer = { - let id = edid.product.manufacturer_id; - let code = [id.0, id.1, id.2]; - get_manufacturer(&code).into() - }; - model = if let Some(MonitorDescriptor::MonitorName(name)) = edid - .descriptors - .0 - .iter() - .find(|x| matches!(x, MonitorDescriptor::MonitorName(_))) - { - let mut name = name.clone(); - if let Some(idx) = name.find('\0') { - name.truncate(idx); - } - name - } else { - format!("{}", edid.product.product_code) - }; - } + edid = Some(Info::parse_edid(&blob).context("Unable to parse edid")?); } break; } } - Ok(EdidInfo { - model, - manufacturer, - }) + edid.ok_or(anyhow!("No EDID found")) } pub fn get_prop( @@ -257,78 +219,6 @@ pub fn get_property_val( anyhow::bail!("No prop found for {}", name) } -fn get_manufacturer(vendor: &[char; 3]) -> &'static str { - match vendor { - ['A', 'A', 'A'] => "Avolites Ltd", - ['A', 'C', 'I'] => "Ancor Communications Inc", - ['A', 'C', 'R'] => "Acer Technologies", - ['A', 'D', 'A'] => "Addi-Data GmbH", - ['A', 'P', 'P'] => "Apple Computer Inc", - ['A', 'S', 'K'] => "Ask A/S", - ['A', 'V', 'T'] => "Avtek (Electronics) Pty Ltd", - ['B', 'N', 'O'] => "Bang & Olufsen", - ['B', 'N', 'Q'] => "BenQ Corporation", - ['C', 'M', 'N'] => "Chimei Innolux Corporation", - ['C', 'M', 'O'] => "Chi Mei Optoelectronics corp.", - ['C', 'R', 'O'] => "Extraordinary Technologies PTY Limited", - ['D', 'E', 'L'] => "Dell Inc.", - ['D', 'G', 'C'] => "Data General Corporation", - ['D', 'O', 'N'] => "DENON, Ltd.", - ['E', 'N', 'C'] => "Eizo Nanao Corporation", - ['E', 'P', 'H'] => "Epiphan Systems Inc.", - ['E', 'X', 'P'] => "Data Export Corporation", - ['F', 'N', 'I'] => "Funai Electric Co., Ltd.", - ['F', 'U', 'S'] => "Fujitsu Siemens Computers GmbH", - ['G', 'S', 'M'] => "Goldstar Company Ltd", - ['H', 'I', 'Q'] => "Kaohsiung Opto Electronics Americas, Inc.", - ['H', 'S', 'D'] => "HannStar Display Corp", - ['H', 'T', 'C'] => "Hitachi Ltd", - ['H', 'W', 'P'] => "Hewlett Packard", - ['I', 'N', 'T'] => "Interphase Corporation", - ['I', 'N', 'X'] => "Communications Supply Corporation (A division of WESCO)", - ['I', 'T', 'E'] => "Integrated Tech Express Inc", - ['I', 'V', 'M'] => "Iiyama North America", - ['L', 'E', 'N'] => "Lenovo Group Limited", - ['M', 'A', 'X'] => "Rogen Tech Distribution Inc", - ['M', 'E', 'G'] => "Abeam Tech Ltd", - ['M', 'E', 'I'] => "Panasonic Industry Company", - ['M', 'T', 'C'] => "Mars-Tech Corporation", - ['M', 'T', 'X'] => "Matrox", - ['N', 'E', 'C'] => "NEC Corporation", - ['N', 'E', 'X'] => "Nexgen Mediatech Inc.", - ['O', 'N', 'K'] => "ONKYO Corporation", - ['O', 'R', 'N'] => "ORION ELECTRIC CO., LTD.", - ['O', 'T', 'M'] => "Optoma Corporation", - ['O', 'V', 'R'] => "Oculus VR, Inc.", - ['P', 'H', 'L'] => "Philips Consumer Electronics Company", - ['P', 'I', 'O'] => "Pioneer Electronic Corporation", - ['P', 'N', 'R'] => "Planar Systems, Inc.", - ['Q', 'D', 'S'] => "Quanta Display Inc.", - ['R', 'A', 'T'] => "Rent-A-Tech", - ['R', 'E', 'N'] => "Renesas Technology Corp.", - ['S', 'A', 'M'] => "Samsung Electric Company", - ['S', 'A', 'N'] => "Sanyo Electric Co., Ltd.", - ['S', 'E', 'C'] => "Seiko Epson Corporation", - ['S', 'H', 'P'] => "Sharp Corporation", - ['S', 'I', 'I'] => "Silicon Image, Inc.", - ['S', 'N', 'Y'] => "Sony", - ['S', 'T', 'D'] => "STD Computer Inc", - ['S', 'V', 'S'] => "SVSI", - ['S', 'Y', 'N'] => "Synaptics Inc", - ['T', 'C', 'L'] => "Technical Concepts Ltd", - ['T', 'O', 'P'] => "Orion Communications Co., Ltd.", - ['T', 'S', 'B'] => "Toshiba America Info Systems Inc", - ['T', 'S', 'T'] => "Transtream Inc", - ['U', 'N', 'K'] => "Unknown", - ['V', 'E', 'S'] => "Vestel Elektronik Sanayi ve Ticaret A. S.", - ['V', 'I', 'T'] => "Visitech AS", - ['V', 'I', 'Z'] => "VIZIO, Inc", - ['V', 'S', 'C'] => "ViewSonic Corporation", - ['Y', 'M', 'H'] => "Yamaha Corporation", - _ => "Unknown", - } -} - // Returns refresh rate in milliherz pub fn calculate_refresh_rate(mode: Mode) -> u32 { let htotal = mode.hsync().2 as u32;