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