diff --git a/Cargo.lock b/Cargo.lock index 8ae50305d6..02b13447ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -591,6 +591,7 @@ name = "driver-graphics" version = "0.1.0" dependencies = [ "common", + "drm-fourcc", "drm-sys", "edid", "inputd", diff --git a/drivers/graphics/driver-graphics/Cargo.toml b/drivers/graphics/driver-graphics/Cargo.toml index a830c4f840..93422cefff 100644 --- a/drivers/graphics/driver-graphics/Cargo.toml +++ b/drivers/graphics/driver-graphics/Cargo.toml @@ -5,6 +5,7 @@ version = "0.1.0" edition = "2021" [dependencies] +drm-fourcc = "2.2.0" drm-sys.workspace = true #TODO: edid is abandoned, fork it an maintain? edid = "0.3.0" diff --git a/drivers/graphics/driver-graphics/src/kms/properties.rs b/drivers/graphics/driver-graphics/src/kms/properties.rs index 732d77cec1..77e16275af 100644 --- a/drivers/graphics/driver-graphics/src/kms/properties.rs +++ b/drivers/graphics/driver-graphics/src/kms/properties.rs @@ -1,5 +1,6 @@ use std::ffi::c_char; use std::fmt::Debug; +use std::mem; use std::sync::Mutex; use drm_sys::{ @@ -19,28 +20,14 @@ impl KmsObjects { atomic: bool, kind: KmsPropertyKind, ) -> KmsObjectId { - if name.len() > DRM_PROP_NAME_LEN as usize { - panic!("Property name {name} is too long"); - } - match &kind { KmsPropertyKind::Range(start, end) => assert!(start < end), - KmsPropertyKind::Enum(variants) => { + KmsPropertyKind::Enum(_variants) => { // FIXME check duplicate variant numbers - for (variant_name, _) in variants { - if variant_name.len() > DRM_PROP_NAME_LEN as usize { - panic!("Property variant name {variant_name} is too long"); - } - } } KmsPropertyKind::Blob => {} - KmsPropertyKind::Bitmask(bitmask_flags) => { + KmsPropertyKind::Bitmask(_bitmask_flags) => { // FIXME check overlapping flag numbers - for (flag_name, _) in bitmask_flags { - if flag_name.len() > DRM_PROP_NAME_LEN as usize { - panic!("Property bitflag name {flag_name} is too long"); - } - } } KmsPropertyKind::Object => {} KmsPropertyKind::SignedRange(start, end) => assert!(start < end), @@ -52,7 +39,7 @@ impl KmsObjects { } self.add(KmsProperty { - name: name_bytes, + name: KmsPropertyName::new("Property name", name), immutable, atomic, kind, @@ -96,9 +83,34 @@ impl KmsObjects { } } +#[derive(Copy, Clone)] +pub struct KmsPropertyName(pub [c_char; DRM_PROP_NAME_LEN as usize]); + +impl KmsPropertyName { + fn new(context: &str, name: &str) -> KmsPropertyName { + if name.len() > DRM_PROP_NAME_LEN as usize { + panic!("{context} {name} is too long"); + } + + let mut name_bytes = [0; DRM_PROP_NAME_LEN as usize]; + for (to, &from) in name_bytes.iter_mut().zip(name.as_bytes()) { + *to = from as c_char; + } + + KmsPropertyName(name_bytes) + } +} + +impl Debug for KmsPropertyName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let u8_bytes = unsafe { mem::transmute::<&[c_char], &[u8]>(&self.0) }; + f.write_str(&String::from_utf8_lossy(u8_bytes).trim_end_matches('\0')) + } +} + #[derive(Debug)] pub struct KmsProperty { - pub name: [c_char; DRM_PROP_NAME_LEN as usize], + pub name: KmsPropertyName, pub immutable: bool, pub atomic: bool, pub kind: KmsPropertyKind, @@ -107,9 +119,9 @@ pub struct KmsProperty { #[derive(Debug)] pub enum KmsPropertyKind { Range(u64, u64), - Enum(Vec<(&'static str, u64)>), + Enum(Vec<(KmsPropertyName, u64)>), Blob, - Bitmask(Vec<(&'static str, u64)>), + Bitmask(Vec<(KmsPropertyName, u64)>), Object, SignedRange(i64, i64), } @@ -146,7 +158,9 @@ macro_rules! define_properties { KmsPropertyKind::Range($start, $end) }; (@prop_kind enum { $($variant:ident = $value:expr,)* }) => { - KmsPropertyKind::Enum(vec![$((stringify!($variant), $value)),*]) + KmsPropertyKind::Enum(vec![ + $((KmsPropertyName::new("Property variant name", stringify!($variant)), $value)),*] + ) }; (@prop_kind blob) => { KmsPropertyKind::Blob diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 62bdaed27f..9a1086d0e6 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -1,7 +1,6 @@ #![feature(macro_metavar_expr)] use std::collections::{BTreeMap, HashMap}; -use std::ffi::c_char; use std::fmt::Debug; use std::fs::File; use std::io::{self, Write}; @@ -9,11 +8,11 @@ use std::os::fd::BorrowedFd; use std::sync::{Arc, Mutex}; use std::{cmp, mem}; +use drm_fourcc::DrmFourcc; use drm_sys::{ drm_mode_modeinfo, drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE, DRM_MODE_PROP_ATOMIC, DRM_MODE_PROP_BITMASK, DRM_MODE_PROP_BLOB, DRM_MODE_PROP_ENUM, DRM_MODE_PROP_IMMUTABLE, DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE, - DRM_PROP_NAME_LEN, }; use inputd::{DisplayHandle, VtEventKind}; use libredox::Fd; @@ -447,8 +446,6 @@ impl SchemeSync for GraphicsSchemeInner { ) -> Result { use redox_ioctl::drm as ipc; - const DRM_FORMAT_ARGB8888: u32 = 0x34325241; // 'AR24' fourcc code, for ARGB8888 - fn id_index(id: u32) -> u32 { id & 0xFF } @@ -656,7 +653,7 @@ impl SchemeSync for GraphicsSchemeInner { }), ipc::MODE_GET_PROPERTY => ipc::DrmModeGetProperty::with(payload, |mut data| { let property = self.objects.get_property(KmsObjectId(data.prop_id()))?; - data.set_name(property.name); + data.set_name(property.name.0); let mut flags = 0; if property.immutable { flags |= DRM_MODE_PROP_IMMUTABLE; @@ -678,17 +675,9 @@ impl SchemeSync for GraphicsSchemeInner { data.set_enum_blob_ptr( &variants .iter() - .map(|&(name, value)| { - let mut name_bytes = [0; DRM_PROP_NAME_LEN as usize]; - for (to, &from) in - name_bytes.iter_mut().zip(name.as_bytes()) - { - *to = from as c_char; - } - drm_mode_property_enum { - name: name_bytes, - value, - } + .map(|&(name, value)| drm_mode_property_enum { + name: name.0, + value, }) .collect::>(), ); @@ -709,17 +698,9 @@ impl SchemeSync for GraphicsSchemeInner { data.set_enum_blob_ptr( &bitmask_flags .iter() - .map(|&(name, value)| { - let mut name_bytes = [0; DRM_PROP_NAME_LEN as usize]; - for (to, &from) in - name_bytes.iter_mut().zip(name.as_bytes()) - { - *to = from as c_char; - } - drm_mode_property_enum { - name: name_bytes, - value, - } + .map(|&(name, value)| drm_mode_property_enum { + name: name.0, + value, }) .collect::>(), ); @@ -906,7 +887,7 @@ impl SchemeSync for GraphicsSchemeInner { data.set_crtc_id(crtc_id.0); data.set_fb_id(crtc.lock().unwrap().fb_id.0); data.set_possible_crtcs(1 << i); - data.set_format_type_ptr(&[DRM_FORMAT_ARGB8888]); + data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]); Ok(0) }), ipc::MODE_OBJ_GET_PROPERTIES => { @@ -966,7 +947,7 @@ impl SchemeSync for GraphicsSchemeInner { data.set_width(fb.width); data.set_height(fb.height); - data.set_pixel_format(DRM_FORMAT_ARGB8888); + data.set_pixel_format(DrmFourcc::Argb8888 as u32); data.set_handles([*next_id, 0, 0, 0]); data.set_pitches([fb.width * 4, 0, 0, 0]); data.set_offsets([0; 4]);