ironrdp_pdu/gcc/
monitor_extended_data.rs1use ironrdp_core::{
2 cast_length, ensure_fixed_part_size, ensure_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult,
3 ReadCursor, WriteCursor,
4};
5use num_derive::{FromPrimitive, ToPrimitive};
6use num_traits::{FromPrimitive as _, ToPrimitive as _};
7
8const MONITOR_COUNT_MAX: usize = 16;
9const MONITOR_ATTRIBUTE_SIZE: u32 = 20;
10
11const FLAGS_SIZE: usize = 4;
12const MONITOR_ATTRIBUTE_SIZE_FIELD_SIZE: usize = 4;
13const MONITOR_COUNT: usize = 4;
14const MONITOR_SIZE: usize = 20;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct ClientMonitorExtendedData {
18 pub extended_monitors_info: Vec<ExtendedMonitorInfo>,
19}
20
21impl ClientMonitorExtendedData {
22 const NAME: &'static str = "ClientMonitorExtendedData";
23
24 const FIXED_PART_SIZE: usize = FLAGS_SIZE + MONITOR_ATTRIBUTE_SIZE_FIELD_SIZE + MONITOR_COUNT;
25}
26
27impl Encode for ClientMonitorExtendedData {
28 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
29 ensure_size!(in: dst, size: self.size());
30
31 dst.write_u32(0); dst.write_u32(MONITOR_ATTRIBUTE_SIZE); dst.write_u32(cast_length!("nMonitors", self.extended_monitors_info.len())?);
34
35 for extended_monitor_info in self.extended_monitors_info.iter().take(MONITOR_COUNT_MAX) {
36 extended_monitor_info.encode(dst)?;
37 }
38
39 Ok(())
40 }
41
42 fn name(&self) -> &'static str {
43 Self::NAME
44 }
45
46 fn size(&self) -> usize {
47 Self::FIXED_PART_SIZE + self.extended_monitors_info.len() * MONITOR_SIZE
48 }
49}
50
51impl<'de> Decode<'de> for ClientMonitorExtendedData {
52 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
53 ensure_fixed_part_size!(in: src);
54
55 let _flags = src.read_u32(); let monitor_attribute_size = src.read_u32();
58 if monitor_attribute_size != MONITOR_ATTRIBUTE_SIZE {
59 return Err(invalid_field_err!("monitorAttributeSize", "invalid size"));
60 }
61
62 let monitor_count = cast_length!("monitorCount", src.read_u32())?;
63
64 if monitor_count > MONITOR_COUNT_MAX {
65 return Err(invalid_field_err!("monitorCount", "invalid monitor count"));
66 }
67
68 let mut extended_monitors_info = Vec::with_capacity(monitor_count);
69 for _ in 0..monitor_count {
70 extended_monitors_info.push(ExtendedMonitorInfo::decode(src)?);
71 }
72
73 Ok(Self { extended_monitors_info })
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct ExtendedMonitorInfo {
79 pub physical_width: u32,
80 pub physical_height: u32,
81 pub orientation: MonitorOrientation,
82 pub desktop_scale_factor: u32,
83 pub device_scale_factor: u32,
84}
85
86impl ExtendedMonitorInfo {
87 const NAME: &'static str = "ExtendedMonitorInfo";
88
89 const FIXED_PART_SIZE: usize = MONITOR_SIZE;
90}
91
92impl Encode for ExtendedMonitorInfo {
93 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
94 ensure_fixed_part_size!(in: dst);
95
96 dst.write_u32(self.physical_width);
97 dst.write_u32(self.physical_height);
98 dst.write_u32(self.orientation.to_u32().unwrap());
99 dst.write_u32(self.desktop_scale_factor);
100 dst.write_u32(self.device_scale_factor);
101
102 Ok(())
103 }
104
105 fn name(&self) -> &'static str {
106 Self::NAME
107 }
108
109 fn size(&self) -> usize {
110 Self::FIXED_PART_SIZE
111 }
112}
113
114impl<'de> Decode<'de> for ExtendedMonitorInfo {
115 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
116 ensure_fixed_part_size!(in: src);
117
118 let physical_width = src.read_u32();
119 let physical_height = src.read_u32();
120 let orientation = MonitorOrientation::from_u32(src.read_u32())
121 .ok_or_else(|| invalid_field_err!("orientation", "invalid monitor orientation"))?;
122 let desktop_scale_factor = src.read_u32();
123 let device_scale_factor = src.read_u32();
124
125 Ok(Self {
126 physical_width,
127 physical_height,
128 orientation,
129 desktop_scale_factor,
130 device_scale_factor,
131 })
132 }
133}
134
135#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
136pub enum MonitorOrientation {
137 Landscape = 0,
138 Portrait = 90,
139 LandscapeFlipped = 180,
140 PortraitFlipped = 270,
141}