vnc/client/
messages.rs

1use crate::{PixelFormat, Rect, VncEncoding, VncError};
2use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
3
4#[derive(Debug)]
5pub(super) enum ClientMsg {
6    SetPixelFormat(PixelFormat),
7    SetEncodings(Vec<VncEncoding>),
8    FramebufferUpdateRequest(Rect, u8),
9    KeyEvent(u32, bool),
10    PointerEvent(u16, u16, u8),
11    ClientCutText(String),
12}
13
14impl ClientMsg {
15    pub(super) async fn write<S>(self, writer: &mut S) -> Result<(), VncError>
16    where
17        S: AsyncWrite + Unpin,
18    {
19        match self {
20            ClientMsg::SetPixelFormat(pf) => {
21                // +--------------+--------------+--------------+
22                // | No. of bytes | Type [Value] | Description  |
23                // +--------------+--------------+--------------+
24                // | 1            | U8 [0]       | message-type |
25                // | 3            |              | padding      |
26                // | 16           | PIXEL_FORMAT | pixel-format |
27                // +--------------+--------------+--------------+
28                let mut payload = vec![0_u8, 0, 0, 0];
29                payload.extend(<PixelFormat as Into<Vec<u8>>>::into(pf));
30                writer.write_all(&payload).await?;
31                Ok(())
32            }
33            ClientMsg::SetEncodings(encodings) => {
34                //  +--------------+--------------+---------------------+
35                // | No. of bytes | Type [Value] | Description         |
36                // +--------------+--------------+---------------------+
37                // | 1            | U8 [2]       | message-type        |
38                // | 1            |              | padding             |
39                // | 2            | U16          | number-of-encodings |
40                // +--------------+--------------+---------------------+
41
42                // This is followed by number-of-encodings repetitions of the following:
43                // +--------------+--------------+---------------+
44                // | No. of bytes | Type [Value] | Description   |
45                // +--------------+--------------+---------------+
46                // | 4            | S32          | encoding-type |
47                // +--------------+--------------+---------------+
48                let mut payload = vec![2, 0];
49                payload.extend_from_slice(&(encodings.len() as u16).to_be_bytes());
50                for e in encodings {
51                    payload.write_u32(e.into()).await?;
52                }
53                writer.write_all(&payload).await?;
54                Ok(())
55            }
56            ClientMsg::FramebufferUpdateRequest(rect, incremental) => {
57                // +--------------+--------------+--------------+
58                // | No. of bytes | Type [Value] | Description  |
59                // +--------------+--------------+--------------+
60                // | 1            | U8 [3]       | message-type |
61                // | 1            | U8           | incremental  |
62                // | 2            | U16          | x-position   |
63                // | 2            | U16          | y-position   |
64                // | 2            | U16          | width        |
65                // | 2            | U16          | height       |
66                // +--------------+--------------+--------------+
67                let mut payload = vec![3, incremental];
68                payload.extend_from_slice(&rect.x.to_be_bytes());
69                payload.extend_from_slice(&rect.y.to_be_bytes());
70                payload.extend_from_slice(&rect.width.to_be_bytes());
71                payload.extend_from_slice(&rect.height.to_be_bytes());
72                writer.write_all(&payload).await?;
73                Ok(())
74            }
75            ClientMsg::KeyEvent(keycode, down) => {
76                // +--------------+--------------+--------------+
77                // | No. of bytes | Type [Value] | Description  |
78                // +--------------+--------------+--------------+
79                // | 1            | U8 [4]       | message-type |
80                // | 1            | U8           | down-flag    |
81                // | 2            |              | padding      |
82                // | 4            | U32          | key          |
83                // +--------------+--------------+--------------+
84                let mut payload = vec![4, down as u8, 0, 0];
85                payload.write_u32(keycode).await?;
86                writer.write_all(&payload).await?;
87                Ok(())
88            }
89            ClientMsg::PointerEvent(x, y, mask) => {
90                // +--------------+--------------+--------------+
91                // | No. of bytes | Type [Value] | Description  |
92                // +--------------+--------------+--------------+
93                // | 1            | U8 [5]       | message-type |
94                // | 1            | U8           | button-mask  |
95                // | 2            | U16          | x-position   |
96                // | 2            | U16          | y-position   |
97                // +--------------+--------------+--------------+
98                let mut payload = vec![5, mask];
99                payload.write_u16(x).await?;
100                payload.write_u16(y).await?;
101                writer.write_all(&payload).await?;
102                Ok(())
103            }
104            ClientMsg::ClientCutText(s) => {
105                //   +--------------+--------------+--------------+
106                //   | No. of bytes | Type [Value] | Description  |
107                //   +--------------+--------------+--------------+
108                //   | 1            | U8 [6]       | message-type |
109                //   | 3            |              | padding      |
110                //   | 4            | U32          | length       |
111                //   | length       | U8 array     | text         |
112                //   +--------------+--------------+--------------+
113                let mut payload = vec![6_u8, 0, 0, 0];
114                payload.write_u32(s.len() as u32).await?;
115                payload.write_all(s.as_bytes()).await?;
116                writer.write_all(&payload).await?;
117                Ok(())
118            }
119        }
120    }
121}
122
123#[derive(Debug)]
124pub(super) enum ServerMsg {
125    FramebufferUpdate(u16),
126    // SetColorMapEntries,
127    Bell,
128    ServerCutText(String),
129}
130
131impl ServerMsg {
132    pub(super) async fn read<S>(reader: &mut S) -> Result<Self, VncError>
133    where
134        S: AsyncRead + Unpin,
135    {
136        let server_msg = reader.read_u8().await?;
137
138        match server_msg {
139            0 => {
140                // FramebufferUpdate
141                //   +--------------+--------------+----------------------+
142                //   | No. of bytes | Type [Value] | Description          |
143                //   +--------------+--------------+----------------------+
144                //   | 1            | U8 [0]       | message-type         |
145                //   | 1            |              | padding              |
146                //   | 2            | U16          | number-of-rectangles |
147                //   +--------------+--------------+----------------------+
148                let _padding = reader.read_u8().await?;
149                let rects = reader.read_u16().await?;
150                Ok(ServerMsg::FramebufferUpdate(rects))
151            }
152            1 => {
153                // SetColorMapEntries
154                // +--------------+--------------+------------------+
155                // | No. of bytes | Type [Value] | Description      |
156                // +--------------+--------------+------------------+
157                // | 1            | U8 [1]       | message-type     |
158                // | 1            |              | padding          |
159                // | 2            | U16          | first-color      |
160                // | 2            | U16          | number-of-colors |
161                // +--------------+--------------+------------------+
162                unimplemented!()
163            }
164            2 => {
165                // Bell
166                //   +--------------+--------------+--------------+
167                //   | No. of bytes | Type [Value] | Description  |
168                //   +--------------+--------------+--------------+
169                //   | 1            | U8 [2]       | message-type |
170                //   +--------------+--------------+--------------+
171                Ok(ServerMsg::Bell)
172            }
173            3 => {
174                // ServerCutText
175                // +--------------+--------------+--------------+
176                // | No. of bytes | Type [Value] | Description  |
177                // +--------------+--------------+--------------+
178                // | 1            | U8 [3]       | message-type |
179                // | 3            |              | padding      |
180                // | 4            | U32          | length       |
181                // | length       | U8 array     | text         |
182                // +--------------+--------------+--------------+
183                let mut padding = [0; 3];
184                reader.read_exact(&mut padding).await?;
185                let len = reader.read_u32().await?;
186                let mut buffer_str = vec![0; len as usize];
187                reader.read_exact(&mut buffer_str).await?;
188                Ok(Self::ServerCutText(
189                    String::from_utf8_lossy(&buffer_str).to_string(),
190                ))
191            }
192            _ => Err(VncError::WrongServerMessage),
193        }
194    }
195}