mirror of
https://github.com/Devolutions/IronRDP.git
synced 2025-08-04 15:18:17 +00:00

- Remove Tauri client. It was useful when initially prototyping the Web Component, but now it’s more of a maintenance burden. It’s notably not convenient to check in CI. Since we now have another native alternative that does not require any GPU (`ironrdp-client`), it’s probably a good time to part ways. - Move wasm package into the workspace. - Move Rust crates into a `crates` subfolder. - Introduce `xtask` crate for free-form automation.
130 lines
4.2 KiB
Rust
130 lines
4.2 KiB
Rust
#[cfg(test)]
|
|
pub mod test;
|
|
|
|
use std::io;
|
|
|
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
|
use num_derive::{FromPrimitive, ToPrimitive};
|
|
use num_traits::{FromPrimitive, ToPrimitive};
|
|
use thiserror::Error;
|
|
|
|
use crate::PduParsing;
|
|
|
|
const MONITOR_COUNT_MAX: usize = 16;
|
|
const MONITOR_ATTRIBUTE_SIZE: u32 = 20;
|
|
|
|
const FLAGS_SIZE: usize = 4;
|
|
const MONITOR_ATTRIBUTE_SIZE_FIELD_SIZE: usize = 4;
|
|
const MONITOR_COUNT: usize = 4;
|
|
const MONITOR_SIZE: usize = 20;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct ClientMonitorExtendedData {
|
|
pub extended_monitors_info: Vec<ExtendedMonitorInfo>,
|
|
}
|
|
|
|
impl PduParsing for ClientMonitorExtendedData {
|
|
type Error = MonitorExtendedDataError;
|
|
|
|
fn from_buffer(mut buffer: impl io::Read) -> Result<Self, Self::Error> {
|
|
let _flags = buffer.read_u32::<LittleEndian>()?; // is unused
|
|
|
|
let monitor_attribute_size = buffer.read_u32::<LittleEndian>()?;
|
|
if monitor_attribute_size != MONITOR_ATTRIBUTE_SIZE {
|
|
return Err(MonitorExtendedDataError::InvalidMonitorAttributeSize);
|
|
}
|
|
|
|
let monitor_count = buffer.read_u32::<LittleEndian>()?;
|
|
|
|
if monitor_count > MONITOR_COUNT_MAX as u32 {
|
|
return Err(MonitorExtendedDataError::InvalidMonitorCount);
|
|
}
|
|
|
|
let mut extended_monitors_info = Vec::with_capacity(monitor_count as usize);
|
|
for _ in 0..monitor_count {
|
|
extended_monitors_info.push(ExtendedMonitorInfo::from_buffer(&mut buffer)?);
|
|
}
|
|
|
|
Ok(Self { extended_monitors_info })
|
|
}
|
|
fn to_buffer(&self, mut buffer: impl io::Write) -> Result<(), Self::Error> {
|
|
buffer.write_u32::<LittleEndian>(0)?; // flags
|
|
buffer.write_u32::<LittleEndian>(MONITOR_ATTRIBUTE_SIZE)?; // flags
|
|
buffer.write_u32::<LittleEndian>(self.extended_monitors_info.len() as u32)?;
|
|
|
|
for extended_monitor_info in self.extended_monitors_info.iter().take(MONITOR_COUNT_MAX) {
|
|
extended_monitor_info.to_buffer(&mut buffer)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn buffer_length(&self) -> usize {
|
|
FLAGS_SIZE
|
|
+ MONITOR_ATTRIBUTE_SIZE_FIELD_SIZE
|
|
+ MONITOR_COUNT
|
|
+ self.extended_monitors_info.len() * MONITOR_SIZE
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct ExtendedMonitorInfo {
|
|
pub physical_width: u32,
|
|
pub physical_height: u32,
|
|
pub orientation: MonitorOrientation,
|
|
pub desktop_scale_factor: u32,
|
|
pub device_scale_factor: u32,
|
|
}
|
|
|
|
impl PduParsing for ExtendedMonitorInfo {
|
|
type Error = MonitorExtendedDataError;
|
|
|
|
fn from_buffer(mut buffer: impl io::Read) -> Result<Self, Self::Error> {
|
|
let physical_width = buffer.read_u32::<LittleEndian>()?;
|
|
let physical_height = buffer.read_u32::<LittleEndian>()?;
|
|
let orientation = MonitorOrientation::from_u32(buffer.read_u32::<LittleEndian>()?)
|
|
.ok_or(MonitorExtendedDataError::InvalidMonitorOrientation)?;
|
|
let desktop_scale_factor = buffer.read_u32::<LittleEndian>()?;
|
|
let device_scale_factor = buffer.read_u32::<LittleEndian>()?;
|
|
|
|
Ok(Self {
|
|
physical_width,
|
|
physical_height,
|
|
orientation,
|
|
desktop_scale_factor,
|
|
device_scale_factor,
|
|
})
|
|
}
|
|
fn to_buffer(&self, mut buffer: impl io::Write) -> Result<(), Self::Error> {
|
|
buffer.write_u32::<LittleEndian>(self.physical_width)?;
|
|
buffer.write_u32::<LittleEndian>(self.physical_height)?;
|
|
buffer.write_u32::<LittleEndian>(self.orientation.to_u32().unwrap())?;
|
|
buffer.write_u32::<LittleEndian>(self.desktop_scale_factor)?;
|
|
buffer.write_u32::<LittleEndian>(self.device_scale_factor)?;
|
|
|
|
Ok(())
|
|
}
|
|
fn buffer_length(&self) -> usize {
|
|
MONITOR_SIZE
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
|
pub enum MonitorOrientation {
|
|
Landscape = 0,
|
|
Portrait = 90,
|
|
LandscapeFlipped = 180,
|
|
PortraitFlipped = 270,
|
|
}
|
|
|
|
#[derive(Debug, Error)]
|
|
pub enum MonitorExtendedDataError {
|
|
#[error("IO error")]
|
|
IOError(#[from] io::Error),
|
|
#[error("Invalid monitor attribute size field")]
|
|
InvalidMonitorAttributeSize,
|
|
#[error("Invalid monitor orientation field")]
|
|
InvalidMonitorOrientation,
|
|
#[error("Invalid monitor count field")]
|
|
InvalidMonitorCount,
|
|
}
|