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