ironrdp_pdu/rdp/
refresh_rectangle.rs

1use ironrdp_core::{
2    cast_length, ensure_fixed_part_size, ensure_size, read_padding, write_padding, Decode, DecodeResult, Encode,
3    EncodeResult, ReadCursor, WriteCursor,
4};
5
6use crate::geometry::InclusiveRectangle;
7
8/// [2.2.11.2.1] Refresh Rect PDU Data (TS_REFRESH_RECT_PDU)
9///
10/// The Refresh Rect PDU allows the client to request that the server redraw one
11/// or more rectangles of the session screen area. The client can use it to
12/// repaint sections of the client window that were obscured by local
13/// applications. Server support for this PDU is indicated in the General
14/// Capability Set (section [2.2.7.1.1].
15///
16/// [2.2.11.2.1]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/fe04a39d-dc10-489f-bea7-08dad5538547
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct RefreshRectanglePdu {
19    pub areas_to_refresh: Vec<InclusiveRectangle>,
20}
21
22impl RefreshRectanglePdu {
23    const NAME: &'static str = "RefreshRectanglePdu";
24
25    const FIXED_PART_SIZE: usize = 1 /* numberOfAreas */ + 3 /* pad3Octets */;
26}
27
28impl Encode for RefreshRectanglePdu {
29    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
30        ensure_size!(in: dst, size: self.size());
31
32        let n_areas = cast_length!("nAreas", self.areas_to_refresh.len())?;
33
34        dst.write_u8(n_areas);
35        write_padding!(dst, 3);
36        for rectangle in self.areas_to_refresh.iter() {
37            rectangle.encode(dst)?;
38        }
39
40        Ok(())
41    }
42
43    fn name(&self) -> &'static str {
44        Self::NAME
45    }
46
47    fn size(&self) -> usize {
48        Self::FIXED_PART_SIZE + self.areas_to_refresh.iter().map(|r| r.size()).sum::<usize>()
49        // areasToRefresh
50    }
51}
52
53impl<'de> Decode<'de> for RefreshRectanglePdu {
54    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
55        ensure_fixed_part_size!(in: src);
56
57        let number_of_areas = src.read_u8();
58        read_padding!(src, 3);
59        let areas_to_refresh = (0..number_of_areas)
60            .map(|_| InclusiveRectangle::decode(src))
61            .collect::<Result<Vec<_>, _>>()?;
62
63        Ok(Self { areas_to_refresh })
64    }
65}