ironrdp_pdu/rdp/capability_sets/
input.rs1#[cfg(test)]
2mod tests;
3
4use bitflags::bitflags;
5use ironrdp_core::{
6 ensure_fixed_part_size, read_padding, write_padding, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
7 WriteCursor,
8};
9use num_traits::{FromPrimitive as _, ToPrimitive as _};
10
11use crate::gcc::{KeyboardType, IME_FILE_NAME_SIZE};
12use crate::utils;
13
14const INPUT_LENGTH: usize = 84;
15
16bitflags! {
17 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
18 pub struct InputFlags: u16 {
19 const SCANCODES = 0x0001;
20 const MOUSEX = 0x0004;
21 const FASTPATH_INPUT = 0x0008;
22 const UNICODE = 0x0010;
23 const FASTPATH_INPUT_2 = 0x0020;
24 const UNUSED_1 = 0x0040;
25 const MOUSE_RELATIVE = 0x0080;
26 const TS_MOUSE_HWHEEL = 0x0100;
27 const TS_QOE_TIMESTAMPS = 0x0200;
28 }
29}
30
31#[derive(Debug, PartialEq, Eq, Clone)]
32pub struct Input {
33 pub input_flags: InputFlags,
34 pub keyboard_layout: u32,
35 pub keyboard_type: Option<KeyboardType>,
36 pub keyboard_subtype: u32,
37 pub keyboard_function_key: u32,
38 pub keyboard_ime_filename: String,
39}
40
41impl Input {
42 const NAME: &'static str = "Input";
43
44 const FIXED_PART_SIZE: usize = INPUT_LENGTH;
45}
46
47impl Encode for Input {
48 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
49 ensure_fixed_part_size!(in: dst);
50
51 dst.write_u16(self.input_flags.bits());
52 write_padding!(dst, 2);
53 dst.write_u32(self.keyboard_layout);
54
55 let type_buffer = match self.keyboard_type.as_ref() {
56 Some(value) => value.to_u32().unwrap_or(0),
57 None => 0,
58 };
59 dst.write_u32(type_buffer);
60
61 dst.write_u32(self.keyboard_subtype);
62 dst.write_u32(self.keyboard_function_key);
63
64 utils::encode_string(
65 dst.remaining_mut(),
66 &self.keyboard_ime_filename,
67 utils::CharacterSet::Unicode,
68 true,
69 )?;
70 dst.advance(IME_FILE_NAME_SIZE);
71
72 Ok(())
73 }
74
75 fn name(&self) -> &'static str {
76 Self::NAME
77 }
78
79 fn size(&self) -> usize {
80 Self::FIXED_PART_SIZE
81 }
82}
83
84impl<'de> Decode<'de> for Input {
85 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
86 ensure_fixed_part_size!(in: src);
87
88 let input_flags = InputFlags::from_bits_truncate(src.read_u16());
89 read_padding!(src, 2);
90 let keyboard_layout = src.read_u32();
91
92 let keyboard_type = KeyboardType::from_u32(src.read_u32());
93
94 let keyboard_subtype = src.read_u32();
95 let keyboard_function_key = src.read_u32();
96
97 let keyboard_ime_filename =
98 utils::decode_string(src.read_slice(IME_FILE_NAME_SIZE), utils::CharacterSet::Unicode, false)?;
99
100 Ok(Input {
101 input_flags,
102 keyboard_layout,
103 keyboard_type,
104 keyboard_subtype,
105 keyboard_function_key,
106 keyboard_ime_filename,
107 })
108 }
109}