xref: /illumos-gate/usr/src/cmd/bhyve/common/rfb_impl.h (revision 5c4a5fe16715fb423db76577a6883b5bbecdbe45)
1  /*
2   * This file and its contents are supplied under the terms of the
3   * Common Development and Distribution License ("CDDL"), version 1.0.
4   * You may only use this file in accordance with the terms of version
5   * 1.0 of the CDDL.
6   *
7   * A full copy of the text of the CDDL should have accompanied this
8   * source.  A copy of the CDDL is also available via the Internet at
9   * http://www.illumos.org/license/CDDL.
10   */
11  
12  /*
13   * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
14   */
15  
16  #ifndef _RFB_IMPL_H
17  #define	_RFB_IMPL_H
18  
19  #include <stdatomic.h>
20  #include <stdbool.h>
21  #include <zlib.h>
22  #include <sys/types.h>
23  #include <sys/list.h>
24  
25  #include "mevent.h"
26  
27  /*
28   * The ProtocolVersion message consists of 12 bytes interpreted as a string of
29   * ASCII characters in the format "RFB xxx.yyy\n" where xxx and yyy are the
30   * major and minor version numbers, padded with zeros.
31   */
32  #define	RFB_VERSION			"RFB 003.008\n"
33  #define	RFB_VERSION_LEN			(sizeof (RFB_VERSION) - 1)
34  
35  _Static_assert(RFB_VERSION_LEN == 12, "RFB_VERSION length incorrect");
36  
37  /* Keep synchronised with pci_fbuf.c */
38  #define	RFB_MAX_WIDTH			1920
39  #define	RFB_MAX_HEIGHT			1200
40  
41  #define	RFB_MAX_CLIENTS			10
42  
43  /* Framebuffer pixel format */
44  #define	RFB_PIX_BPP			32
45  #define	RFB_PIX_DEPTH			24
46  #define	RFB_PIX_RSHIFT			16
47  #define	RFB_PIX_GSHIFT			8
48  #define	RFB_PIX_BSHIFT			0
49  #define	RFB_PIX_RMAX			255
50  #define	RFB_PIX_GMAX			255
51  #define	RFB_PIX_BMAX			255
52  
53  #define	RFB_ZLIB_BUFSZ			(RFB_MAX_WIDTH * RFB_MAX_HEIGHT * 4)
54  
55  #define	RFB_PIX_PER_CELL		32
56  #define	RFB_PIXCELL_SHIFT		5
57  #define	RFB_PIXCELL_MASK		0x1f
58  #define	RFB_SENDALL_THRESH		25
59  
60  #define	RFB_SEL_DELAY_US		10000
61  #define	RFB_SCREEN_REFRESH_DELAY	33300   /* 30 Hz */
62  #define	RFB_SCREEN_POLL_DELAY		(RFB_SCREEN_REFRESH_DELAY / 2)
63  
64  /* Client-to-server message types */
65  #define	RFBP_CS_SET_PIXEL_FORMAT	0
66  #define	RFBP_CS_SET_ENCODINGS		2
67  #define	RFBP_CS_UPDATE_REQUEST		3
68  #define	RFBP_CS_KEY_EVENT		4
69  #define	RFBP_CS_POINTER_EVENT		5
70  #define	RFBP_CS_CUT_TEXT		6
71  #define	RFBP_CS_QEMU			255
72  #define	RFBP_CS_QEMU_KEVENT		0
73  
74  /* Server-to-client message types */
75  #define	RFBP_SC_UPDATE			0
76  #define	RFBP_SC_SET_COLOURMAP_ENTRIES	1
77  #define	RFBP_SC_BELL			2
78  #define	RFBP_SC_CUT_TEXT		3
79  
80  /* Encodings */
81  #define	RFBP_ENCODING_RAW		0
82  #define	RFBP_ENCODING_ZLIB		6
83  /* Pseudo-encodings */
84  #define	RFBP_ENCODING_RESIZE		-223
85  #define	RFBP_ENCODING_EXT_KEVENT	-258	/* QEMU ext. key event */
86  #define	RFBP_ENCODING_DESKTOP_NAME	-307
87  
88  /* Security types */
89  #define	RFBP_SECURITY_INVALID		0
90  #define	RFBP_SECURITY_NONE		1
91  #define	RFBP_SECURITY_VNC_AUTH		2
92  
93  #define	RFBP_SECURITY_VNC_AUTH_LEN	16
94  #define	RFBP_SECURITY_VNC_PASSWD_LEN	8
95  
96  typedef enum rfb_loglevel {
97  	RFB_LOGDEBUG,
98  	RFB_LOGWARN,
99  	RFB_LOGERR
100  } rfb_loglevel_t;
101  
102  typedef enum rfb_encodings {
103  	RFB_ENCODING_RAW		= (1ULL << 0),
104  	RFB_ENCODING_ZLIB		= (1ULL << 1),
105  	RFB_ENCODING_RESIZE		= (1ULL << 2),
106  	RFB_ENCODING_EXT_KEVENT		= (1ULL << 3),
107  	RFB_ENCODING_DESKTOP_NAME	= (1ULL << 4)
108  } rfb_encodings_t;
109  
110  typedef enum rfb_cver {
111  	RFB_CVER_3_3,
112  	RFB_CVER_3_7,
113  	RFB_CVER_3_8
114  } rfb_cver_t;
115  
116  typedef struct rfb_pixfmt {
117  	uint8_t			rp_bpp;
118  	uint8_t			rp_depth;
119  	uint8_t			rp_bigendian;
120  	uint8_t			rp_truecolour;
121  	uint16_t		rp_r_max;
122  	uint16_t		rp_g_max;
123  	uint16_t		rp_b_max;
124  	uint8_t			rp_r_shift;
125  	uint8_t			rp_g_shift;
126  	uint8_t			rp_b_shift;
127  	uint8_t			rp_pad[3];
128  } __packed rfb_pixfmt_t;
129  
130  /* Server-to-client message formats */
131  
132  typedef struct rfb_server_info {
133  	uint16_t		rsi_width;
134  	uint16_t		rsi_height;
135  	rfb_pixfmt_t		rsi_pixfmt;
136  	uint32_t		rsi_namelen;
137  } __packed rfb_server_info_t;
138  
139  typedef struct rfb_server_update_msg {
140  	uint8_t			rss_type;
141  	uint8_t			rss_pad;
142  	uint16_t		rss_numrects;
143  } __packed rfb_server_update_msg_t;
144  
145  typedef struct rfb_rect_hdr {
146  	uint16_t		rr_x;
147  	uint16_t		rr_y;
148  	uint16_t		rr_width;
149  	uint16_t		rr_height;
150  	uint32_t		rr_encoding;
151  } __packed rfb_rect_hdr_t;
152  
153  /* Client-to-server message formats */
154  
155  typedef struct rfb_cs_pixfmt_msg  {
156  	uint8_t			rp_pad[3];
157  	rfb_pixfmt_t		rp_pixfmt;
158  } __packed rfb_cs_pixfmt_msg_t;
159  
160  typedef struct rfb_cs_update_msg {
161  	uint8_t			rum_incremental;
162  	uint16_t		rum_x;
163  	uint16_t		rum_y;
164  	uint16_t		rum_width;
165  	uint16_t		rum_height;
166  } __packed rfb_cs_update_msg_t;
167  
168  typedef struct rfb_cs_encodings_msg {
169  	uint8_t			re_pad;
170  	uint16_t		re_numencs;
171  } __packed rfb_cs_encodings_msg_t;
172  
173  typedef struct rfb_cs_key_event_msg {
174  	uint8_t			rke_down;
175  	uint16_t		rke_pad;
176  	uint32_t		rke_sym;
177  } __packed rfb_cs_key_event_msg_t;
178  
179  typedef struct rfb_cs_pointer_event_msg {
180  	uint8_t			rpe_button;
181  	uint16_t		rpe_x;
182  	uint16_t		rpe_y;
183  } __packed rfb_cs_pointer_event_msg_t;
184  
185  typedef struct rfb_cs_cut_text_msg {
186  	uint8_t			rct_padding[3];
187  	uint32_t		rct_length;
188  } __packed rfb_cs_cut_text_msg_t;
189  
190  typedef struct rfb_cs_qemu_msg {
191  	uint8_t			rq_subtype;
192  } __packed rfb_cs_qemu_msg_t;
193  
194  typedef struct rfb_cs_qemu_extended_key_msg {
195  	uint16_t		rqek_down;
196  	uint32_t		rqek_sym;
197  	uint32_t		rqek_code;
198  } __packed rfb_cs_qemu_extended_key_msg_t;
199  
200  /* Client/server data structures */
201  
202  typedef struct rfb_server {
203  	list_node_t		rs_node;
204  	int			rs_fd;
205  	const char		*rs_name;
206  	const char		*rs_password;
207  
208  	struct mevent		*rs_connevent;
209  
210  	uint_t			rs_clientcount;
211  	pthread_mutex_t		rs_clientlock;
212  	list_t			rs_clients;
213  
214  	bool			rs_exclusive;
215  
216  	rfb_pixfmt_t		rs_pixfmt;
217  } rfb_server_t;
218  
219  typedef struct rfb_client {
220  	list_node_t		rc_node;
221  	uint_t			rc_instance;
222  
223  	int			rc_fd;
224  	rfb_server_t		*rc_s;
225  	rfb_server_info_t	rc_sinfo;
226  	pthread_t		rc_rx_tid;
227  	pthread_t		rc_tx_tid;
228  
229  	int			rc_width;
230  	int			rc_height;
231  	size_t			rc_cells;
232  	uint32_t		*rc_crc;
233  	uint32_t		*rc_crc_tmp;
234  	z_stream		rc_zstream;
235  	uint8_t			*rc_zbuf;
236  
237  	struct bhyvegc_image	rc_gci;
238  
239  	rfb_cver_t		rc_cver;
240  	rfb_encodings_t		rc_encodings;
241  
242  	atomic_bool		rc_closing;
243  	atomic_bool		rc_pending;
244  	atomic_bool		rc_input_detected;
245  	atomic_bool		rc_crc_reset;
246  	atomic_bool		rc_send_fullscreen;
247  
248  	bool			rc_custom_pixfmt;
249  	bool			rc_keyevent_sent;
250  } rfb_client_t;
251  
252  #endif	/* _RFB_IMPL_H */
253