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