ironrdp_pdu/gcc/
monitor_data.rs

1use bitflags::bitflags;
2use ironrdp_core::{
3    cast_length, ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
4    WriteCursor,
5};
6
7pub const MONITOR_COUNT_SIZE: usize = 4;
8pub const MONITOR_SIZE: usize = 20;
9pub const MONITOR_FLAGS_SIZE: usize = 4;
10
11const MONITOR_COUNT_MAX: usize = 16;
12
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct ClientMonitorData {
15    pub monitors: Vec<Monitor>,
16}
17
18impl ClientMonitorData {
19    const NAME: &'static str = "ClientMonitorData";
20
21    const FIXED_PART_SIZE: usize = 4 /* flags */ + 4 /* count */;
22}
23
24impl Encode for ClientMonitorData {
25    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
26        ensure_fixed_part_size!(in: dst);
27
28        dst.write_u32(0); // flags
29        dst.write_u32(cast_length!("nMonitors", self.monitors.len())?);
30
31        for monitor in self.monitors.iter().take(MONITOR_COUNT_MAX) {
32            monitor.encode(dst)?;
33        }
34
35        Ok(())
36    }
37
38    fn name(&self) -> &'static str {
39        Self::NAME
40    }
41
42    fn size(&self) -> usize {
43        Self::FIXED_PART_SIZE + self.monitors.len() * Monitor::FIXED_PART_SIZE
44    }
45}
46
47impl<'de> Decode<'de> for ClientMonitorData {
48    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
49        ensure_fixed_part_size!(in: src);
50
51        let _flags = src.read_u32(); // is unused
52        let monitor_count = src.read_u32();
53
54        if monitor_count > MONITOR_COUNT_MAX as u32 {
55            return Err(invalid_field_err!("nMonitors", "too many monitors"));
56        }
57
58        let mut monitors = Vec::with_capacity(monitor_count as usize);
59        for _ in 0..monitor_count {
60            monitors.push(Monitor::decode(src)?);
61        }
62
63        Ok(Self { monitors })
64    }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq)]
68pub struct Monitor {
69    pub left: i32,
70    pub top: i32,
71    pub right: i32,
72    pub bottom: i32,
73    pub flags: MonitorFlags,
74}
75
76impl Monitor {
77    const NAME: &'static str = "Monitor";
78
79    const FIXED_PART_SIZE: usize = 4 /* left */ + 4 /* top */ + 4 /* right */ + 4 /* bottom */ + 4 /* flags */;
80}
81
82impl Encode for Monitor {
83    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
84        ensure_fixed_part_size!(in: dst);
85
86        dst.write_i32(self.left);
87        dst.write_i32(self.top);
88        dst.write_i32(self.right);
89        dst.write_i32(self.bottom);
90        dst.write_u32(self.flags.bits());
91
92        Ok(())
93    }
94
95    fn name(&self) -> &'static str {
96        Self::NAME
97    }
98
99    fn size(&self) -> usize {
100        Self::FIXED_PART_SIZE
101    }
102}
103
104impl<'de> Decode<'de> for Monitor {
105    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
106        ensure_fixed_part_size!(in: src);
107
108        let left = src.read_i32();
109        let top = src.read_i32();
110        let right = src.read_i32();
111        let bottom = src.read_i32();
112        let flags = MonitorFlags::from_bits(src.read_u32())
113            .ok_or_else(|| invalid_field_err!("flags", "invalid monitor flags"))?;
114
115        Ok(Self {
116            left,
117            top,
118            right,
119            bottom,
120            flags,
121        })
122    }
123}
124
125bitflags! {
126    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
127    pub struct MonitorFlags: u32 {
128        const PRIMARY = 1;
129    }
130}