1use crate::VncError;
2use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
3
4#[allow(dead_code)]
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[repr(i32)]
8pub enum VncEncoding {
9 Raw = 0,
10 CopyRect = 1,
11 Tight = 7,
14 Trle = 15,
15 Zrle = 16,
16 CursorPseudo = -239,
17 DesktopSizePseudo = -223,
18 LastRectPseudo = -224,
19}
20
21impl From<u32> for VncEncoding {
22 fn from(num: u32) -> Self {
23 match num as i32 {
27 0 => VncEncoding::Raw,
28 1 => VncEncoding::CopyRect,
29 7 => VncEncoding::Tight,
30 15 => VncEncoding::Trle,
31 16 => VncEncoding::Zrle,
32 -239 => VncEncoding::CursorPseudo,
33 -223 => VncEncoding::DesktopSizePseudo,
34 -224 => VncEncoding::LastRectPseudo,
35 _ => VncEncoding::Raw,
36 }
37 }
38}
39
40impl From<VncEncoding> for u32 {
41 fn from(e: VncEncoding) -> Self {
42 e as u32
43 }
44}
45
46#[allow(dead_code)]
48#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq)]
49#[repr(u8)]
50pub enum VncVersion {
51 RFB33,
52 RFB37,
53 RFB38,
54}
55
56impl From<[u8; 12]> for VncVersion {
57 fn from(version: [u8; 12]) -> Self {
58 match &version {
59 b"RFB 003.003\n" => VncVersion::RFB33,
60 b"RFB 003.007\n" => VncVersion::RFB37,
61 b"RFB 003.008\n" => VncVersion::RFB38,
62 _ => VncVersion::RFB33,
67 }
68 }
69}
70
71impl From<VncVersion> for &[u8; 12] {
72 fn from(version: VncVersion) -> Self {
73 match version {
74 VncVersion::RFB33 => b"RFB 003.003\n",
75 VncVersion::RFB37 => b"RFB 003.007\n",
76 VncVersion::RFB38 => b"RFB 003.008\n",
77 }
78 }
79}
80
81impl VncVersion {
82 pub(crate) async fn read<S>(reader: &mut S) -> Result<Self, VncError>
83 where
84 S: AsyncRead + Unpin,
85 {
86 let mut buffer = [0_u8; 12];
87 reader.read_exact(&mut buffer).await?;
88 Ok(buffer.into())
89 }
90
91 pub(crate) async fn write<S>(self, writer: &mut S) -> Result<(), VncError>
92 where
93 S: AsyncWrite + Unpin,
94 {
95 writer
96 .write_all(&<VncVersion as Into<&[u8; 12]>>::into(self)[..])
97 .await?;
98 Ok(())
99 }
100}
101
102#[derive(Debug, Clone, Copy)]
122pub struct PixelFormat {
123 pub bits_per_pixel: u8,
128 pub depth: u8,
135 pub big_endian_flag: u8,
138 pub true_color_flag: u8,
141 pub red_max: u16,
145 pub green_max: u16,
146 pub blue_max: u16,
147 pub red_shift: u8,
150 pub green_shift: u8,
151 pub blue_shift: u8,
152 _padding_1: u8,
153 _padding_2: u8,
154 _padding_3: u8,
155}
156
157impl From<PixelFormat> for Vec<u8> {
158 fn from(pf: PixelFormat) -> Vec<u8> {
159 vec![
160 pf.bits_per_pixel,
161 pf.depth,
162 pf.big_endian_flag,
163 pf.true_color_flag,
164 (pf.red_max >> 8) as u8,
165 pf.red_max as u8,
166 (pf.green_max >> 8) as u8,
167 pf.green_max as u8,
168 (pf.blue_max >> 8) as u8,
169 pf.blue_max as u8,
170 pf.red_shift,
171 pf.green_shift,
172 pf.blue_shift,
173 pf._padding_1,
174 pf._padding_2,
175 pf._padding_3,
176 ]
177 }
178}
179
180impl TryFrom<[u8; 16]> for PixelFormat {
181 type Error = VncError;
182
183 fn try_from(pf: [u8; 16]) -> Result<Self, Self::Error> {
184 let bits_per_pixel = pf[0];
185 if bits_per_pixel != 8 && bits_per_pixel != 16 && bits_per_pixel != 32 {
186 return Err(VncError::WrongPixelFormat);
187 }
188 let depth = pf[1];
189 let big_endian_flag = pf[2];
190 let true_color_flag = pf[3];
191 let red_max = u16::from_be_bytes(pf[4..6].try_into().unwrap());
192 let green_max = u16::from_be_bytes(pf[6..8].try_into().unwrap());
193 let blue_max = u16::from_be_bytes(pf[8..10].try_into().unwrap());
194 let red_shift = pf[10];
195 let green_shift = pf[11];
196 let blue_shift = pf[12];
197 let _padding_1 = pf[13];
198 let _padding_2 = pf[14];
199 let _padding_3 = pf[15];
200 Ok(PixelFormat {
201 bits_per_pixel,
202 depth,
203 big_endian_flag,
204 true_color_flag,
205 red_max,
206 green_max,
207 blue_max,
208 red_shift,
209 green_shift,
210 blue_shift,
211 _padding_1,
212 _padding_2,
213 _padding_3,
214 })
215 }
216}
217
218impl Default for PixelFormat {
219 fn default() -> Self {
222 Self {
223 bits_per_pixel: 32,
224 depth: 24,
225 big_endian_flag: 0,
226 true_color_flag: 1,
227 red_max: 255,
228 green_max: 255,
229 blue_max: 255,
230 red_shift: 16,
231 green_shift: 8,
232 blue_shift: 0,
233 _padding_1: 0,
234 _padding_2: 0,
235 _padding_3: 0,
236 }
237 }
238}
239
240impl PixelFormat {
241 pub fn bgra() -> PixelFormat {
244 PixelFormat::default()
245 }
246
247 pub fn rgba() -> PixelFormat {
250 Self {
251 red_shift: 0,
252 blue_shift: 16,
253 ..Default::default()
254 }
255 }
256
257 pub(crate) async fn read<S>(reader: &mut S) -> Result<Self, VncError>
258 where
259 S: AsyncRead + Unpin,
260 {
261 let mut pixel_buffer = [0_u8; 16];
262 reader.read_exact(&mut pixel_buffer).await?;
263 pixel_buffer.try_into()
264 }
265}