ironrdp_displaycontrol/
client.rs1use ironrdp_core::{impl_as_any, Decode as _, EncodeResult, ReadCursor};
2use ironrdp_dvc::{encode_dvc_messages, DvcClientProcessor, DvcMessage, DvcProcessor};
3use ironrdp_pdu::{decode_err, PduResult};
4use ironrdp_svc::{ChannelFlags, SvcMessage};
5use tracing::debug;
6
7use crate::pdu::{DisplayControlCapabilities, DisplayControlMonitorLayout, DisplayControlPdu};
8use crate::CHANNEL_NAME;
9
10pub struct DisplayControlClient {
12 on_capabilities_received: OnCapabilitiesReceived,
14 ready: bool,
16}
17
18impl DisplayControlClient {
19 pub fn new<F>(callback: F) -> Self
25 where
26 F: Fn(DisplayControlCapabilities) -> PduResult<Vec<DvcMessage>> + Send + 'static,
27 {
28 Self {
29 on_capabilities_received: Box::new(callback),
30 ready: false,
31 }
32 }
33
34 pub fn ready(&self) -> bool {
35 self.ready
36 }
37
38 pub fn encode_single_primary_monitor(
52 &self,
53 channel_id: u32,
54 width: u32,
55 height: u32,
56 scale_factor: Option<u32>,
57 physical_dims: Option<(u32, u32)>,
58 ) -> EncodeResult<Vec<SvcMessage>> {
59 let pdu: DisplayControlPdu =
61 DisplayControlMonitorLayout::new_single_primary_monitor(width, height, scale_factor, physical_dims)?.into();
62 debug!(?pdu, "Sending monitor layout");
63 encode_dvc_messages(channel_id, vec![Box::new(pdu)], ChannelFlags::empty())
64 }
65}
66
67impl_as_any!(DisplayControlClient);
68
69impl DvcProcessor for DisplayControlClient {
70 fn channel_name(&self) -> &str {
71 CHANNEL_NAME
72 }
73
74 fn start(&mut self, _channel_id: u32) -> PduResult<Vec<DvcMessage>> {
75 Ok(Vec::new())
76 }
77
78 fn process(&mut self, _channel_id: u32, payload: &[u8]) -> PduResult<Vec<DvcMessage>> {
79 let caps = DisplayControlCapabilities::decode(&mut ReadCursor::new(payload)).map_err(|e| decode_err!(e))?;
80 debug!("Received {:?}", caps);
81 self.ready = true;
82 (self.on_capabilities_received)(caps)
83 }
84}
85
86impl DvcClientProcessor for DisplayControlClient {}
87
88type OnCapabilitiesReceived = Box<dyn Fn(DisplayControlCapabilities) -> PduResult<Vec<DvcMessage>> + Send>;