# HG changeset patch # User Michiel Broek # Date 1556809926 -7200 # Node ID 537ffe2807757de89c3e6e60253db1709bd81a44 # Parent 1b82a6d50a393f48f0b2ddd82d51ebdb96361eb4 Removed the noVNC code and web pages. diff -r 1b82a6d50a39 -r 537ffe280775 Makefile --- a/Makefile Thu May 02 11:57:07 2019 +0200 +++ b/Makefile Thu May 02 17:12:06 2019 +0200 @@ -3,6 +3,7 @@ # project subdirectory. # +PROJECT_VER := 0.3.0 PROJECT_NAME := brewboard include $(IDF_PATH)/make/project.mk diff -r 1b82a6d50a39 -r 537ffe280775 components/tft/tft.c --- a/components/tft/tft.c Thu May 02 11:57:07 2019 +0200 +++ b/components/tft/tft.c Thu May 02 17:12:06 2019 +0200 @@ -15,12 +15,10 @@ #include "tft.h" #include "time.h" #include -#include "rom/tjpgd.h" +#include "esp32/rom/tjpgd.h" #include "esp_heap_caps.h" #include "tftspi.h" -#include "vnc-server.h" - #define DEG_TO_RAD 0.01745329252 #define RAD_TO_DEG 57.295779513 #define deg_to_rad 0.01745329252 + 3.14159265359 @@ -139,7 +137,6 @@ if ((x < dispWin.x1) || (y < dispWin.y1) || (x > dispWin.x2) || (y > dispWin.y2)) return; drawPixel(x, y, color, sel); - VncDrawPixel(x, y, VNC_RGB2COL(color.r, color.g, color.b)); } //==================================================================== @@ -168,7 +165,6 @@ if ((y + h) > (dispWin.y2+1)) h = dispWin.y2 - y + 1; if (h == 0) h = 1; TFT_pushColorRep(x, y, x, y+h-1, color, (uint32_t)h); - VncDrawVertLine(x, y, y+h-1, VNC_RGB2COL(color.r, color.g, color.b)); } //-------------------------------------------------------------------------- @@ -184,7 +180,6 @@ if (w == 0) w = 1; TFT_pushColorRep(x, y, x+w-1, y, color, (uint32_t)w); - VncDrawHorzLine(x, x+w-1, y, VNC_RGB2COL(color.r, color.g, color.b)); } //====================================================================== @@ -287,7 +282,6 @@ if (w == 0) w = 1; if (h == 0) h = 1; TFT_pushColorRep(x, y, x+w-1, y+h-1, color, (uint32_t)(h*w)); - VncFillRect(x, y, x+w-1, y+h-1, VNC_RGB2COL(color.r, color.g, color.b)); } //============================================================================ @@ -298,14 +292,12 @@ //================================== void TFT_fillScreen(color_t color) { TFT_pushColorRep(0, 0, _width-1, _height-1, color, (uint32_t)(_height*_width)); - VncCls(VNC_RGB2COL(color.r, color.g, color.b)); } //================================== void TFT_fillWindow(color_t color) { TFT_pushColorRep(dispWin.x1, dispWin.y1, dispWin.x2, dispWin.y2, color, (uint32_t)((dispWin.x2-dispWin.x1+1) * (dispWin.y2-dispWin.y1+1))); - VncFillRect(dispWin.x1, dispWin.y1, dispWin.x2, dispWin.y2, VNC_RGB2COL(color.r, color.g, color.b)); } // ^^^============= Basics drawing functions ================================^^^ @@ -893,9 +885,6 @@ // visible pixel bufPos = ((j + fontChar.adjYOffset) * char_width) + (fontChar.xOffset + i); // bufY + bufX color_line[bufPos] = _fg; - VncDrawPixel(x + (fontChar.xOffset + i), y + (j + fontChar.adjYOffset), VNC_RGB2COL(_fg.r, _fg.g, _fg.b)); - } else { - VncDrawPixel(x + (fontChar.xOffset + i), y + (j + fontChar.adjYOffset), VNC_RGB2COL(_bg.r, _bg.g, _bg.b)); } mask >>= 1; } @@ -971,9 +960,6 @@ for (i = 0; i < 8; i++) { if ((ch & mask) !=0) { color_line[(j*cfont.x_size) + (i+(k*8))] = _fg; - VncDrawPixel(x+i+(k*8), y+j, VNC_RGB2COL(_fg.r, _fg.g, _fg.b)); - } else { - VncDrawPixel(x+i+(k*8), y+j, VNC_RGB2COL(_bg.r, _bg.g, _bg.b)); } mask >>= 1; } diff -r 1b82a6d50a39 -r 537ffe280775 components/vnc_server/Kconfig --- a/components/vnc_server/Kconfig Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ - -menu "VNC Server" - -config VNC_SERVER_PORT - int "VNC server port number" - default 5900 - help - Port VNC server will listen on for client connection. - This defaults to the standard port 5900, but may - be changed to any other port number if required. - - -config VNC_SERVER_FRAME_WIDTH - int "Frame width in pixels" - default 320 - help - This sets the width of the VNC server frame buffer. - - -config VNC_SERVER_FRAME_HEIGHT - int "Frame heigth in pixels" - default 240 - help - This sets the height of the VNC server frame buffer. - - -endmenu diff -r 1b82a6d50a39 -r 537ffe280775 components/vnc_server/component.mk --- a/components/vnc_server/component.mk Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -# Use defaults. -COMPONENT_ADD_INCLUDEDIRS := . diff -r 1b82a6d50a39 -r 537ffe280775 components/vnc_server/vnc-server.c --- a/components/vnc_server/vnc-server.c Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1361 +0,0 @@ -/** - * @file vnc-server.c - * @brief VNC server original written for eCos. - * - * The VNC server runs on the target platform and waits for a client - * (vncviewer program running on a PC) to connect via an ethernet connection - * (port 5900). Once a client has connected, the target platform has a - * virtual screen, keyboard and mouse. - * - * This port of the VNC server has been designed with some limitations in - * order to keep memory and processor power requirements to a minimum. - * - * The VNC client must accept the settings that the VNC server suggests (bits-per-pixel, - * number-of-colours and so on as specified at build time with the eCos configuration - * tool) or the VNC server will just disconnect. - * - * The VNC server only supports CoRRE encoding and RAW encoding for sending - * display data to the client. - * - * The VNC server does not support password authentication, the client is able - * to connect without the user typing in a password. - * - * Only one VNC client may connect to the VNC server at a time. - * - * In reality these limitations are not a problem. - * - * @author Chris Garry - * @author Michiel Broek. - */ - -#include "vnc-server.h" -#include "websocket_server.h" - -static const char *TAG = "vnc-server"; - -#define BACKLOG 5 ///< Number of pending connections queue will hold -#define MESSAGE_BUFFER_SIZE 60 ///< Was 50, but I have seen 52 bytes length -#define TILE_SIZE 16 ///< Tile dimension -#define TRUE_COLOUR_FLAG 1 ///< True colour is set -#define BIG_ENDIAN_FLAG 1 ///< Always send colour data big endian - -/* Default display parameters */ -#define BITS_PER_PIXEL 8 ///< Bits per pixel -#define PIXEL_DEPTH 8 ///< Usefull bits per pixel -#define RED_MAX 7 ///< Red maximum -#define GREEN_MAX 7 ///< Green maximum -#define BLUE_MAX 3 ///< Blue maximum, together 8 bits. -#define RED_SHIFT 5 ///< Red shift in color byte -#define GREEN_SHIFT 2 ///< Green shift in color byte -#define BLUE_SHIFT 0 ///< Blue shift in color byte - - -/* Initial default RGB332 */ -uint8_t Bits_Per_Pixel = 8; ///< Current number of bits per pixel - -uint16_t Red_Max = RED_MAX; ///< Current Red maxmimum -uint16_t Green_Max = GREEN_MAX; ///< Current Green maximum -uint16_t Blue_Max = BLUE_MAX; ///< Current Blue maximum -uint8_t Red_Shift = RED_SHIFT; ///< Current Red bits shift -uint8_t Green_Shift = GREEN_SHIFT; ///< Current Green bits shift -uint8_t Blue_Shift = BLUE_SHIFT; ///< Current Blue bits shift -bool AltPixels = false; ///< Alternate the pixels - -/* Client to Server message types */ -#define SET_PIXEL_FORMAT 0 ///< Set pixel format -#define FIX_COLOUR_MAP_ENTRIES 1 ///< Fix color map entries (not used) -#define SET_ENCODINGS 2 ///< Set encodings -#define FRAME_BUFFER_UPDATE_REQ 3 ///< Request frame buffer update -#define KEY_EVENT 4 ///< Keyboard event (not used) -#define POINTER_EVENT 5 ///< Pointer event, translated to touch events -#define CLIENT_CUT_TEXT 6 ///< Text editing, not used. - -/* Macros to split colour to bytes */ -#define COLOUR2BYTE1(col) ((col>>8)&0xFF) ///< High part -#define COLOUR2BYTE0(col) (col&0xFF) ///< Low part - - -/* Thread function prototypes */ -static TaskHandle_t xTaskClientHandler = NULL; ///< Task for VNC clients -static TaskHandle_t xTaskFrameUpdate = NULL; ///< Task for framebuffer updates -static TaskHandle_t xTaskWSclient = NULL; ///< Task for websocket clients - -SemaphoreHandle_t SoundBell_lock = NULL; ///< Lock for the bell sound. - -static QueueHandle_t message_queue; ///< Websockets message queue -const static int message_queue_size = 5; ///< Message queue size - -/** - * @brief VNC messages. - */ -struct strMessage { - int length; ///< Length of the message - uint8_t message[MESSAGE_BUFFER_SIZE]; ///< The message -}; - - -uint8_t VNC_pointer_button = 0; ///< Button mask for the mouse pointer -uint16_t VNC_pointer_x = 0; ///< Mouse position X -uint16_t VNC_pointer_y = 0; ///< Mouse position Y - - -/* Define size of each thread's stack */ -#define MIN_STACK_SIZE 3072 ///< Minimal task stack size - - -/** - * @brief Messages - */ -static char server_ProtocolVersion[] = "RFB 003.003\n"; -static char bad_protocol[] = "Unsupported ProtocolVersion"; -static char server_busy[] = "Server is Busy"; -static char sound_bell[] = "\2"; -static char desktop_name[] = "MBSE BrewBoard"; // Hardcoded, don't change or the VNC webclient breaks. - -/** - * @brief Frame Buffer - */ -vnc_color_t frame_buffer[CONFIG_VNC_SERVER_FRAME_HEIGHT+1][CONFIG_VNC_SERVER_FRAME_WIDTH+1]; - -/* Calculate the number of tiles in the X and Y directions */ -#if (CONFIG_VNC_SERVER_FRAME_HEIGHT % TILE_SIZE) != 0 -#define NUM_TILES_Y_AXIS (CONFIG_VNC_SERVER_FRAME_HEIGHT/TILE_SIZE + 1) -#define LAST_TILE_HEIGHT (CONFIG_VNC_SERVER_FRAME_HEIGHT % TILE_SIZE) -#else -#define NUM_TILES_Y_AXIS (CONFIG_VNC_SERVER_FRAME_HEIGHT/TILE_SIZE) ///< Nr of tiles on the Y axis. -#define LAST_TILE_HEIGHT TILE_SIZE ///< Height of the last tile. -#endif - -#if (CONFIG_VNC_SERVER_FRAME_WIDTH % TILE_SIZE) != 0 -#define NUM_TILES_X_AXIS (CONFIG_VNC_SERVER_FRAME_WIDTH/TILE_SIZE + 1) -#define LAST_TILE_WIDTH (CONFIG_VNC_SERVER_FRAME_WIDTH % TILE_SIZE) -#else -#define NUM_TILES_X_AXIS (CONFIG_VNC_SERVER_FRAME_WIDTH/TILE_SIZE) ///< Nr of tiles on the X axis. -#define LAST_TILE_WIDTH TILE_SIZE ///< Width of the last tile. -#endif - -/** - * @brief Array for marking tiles that have been updated - */ -int tile_updated[NUM_TILES_Y_AXIS+1][NUM_TILES_X_AXIS+1]; - -EventGroupHandle_t xEventGroupVNC; ///< Variable to signal that a client is connected and initialised -const int VNC_CLIENT_UPDATE_REQ = BIT0; ///< Client update request event -int vnc_client_sock = -1; ///< Client network socket -bool vnc_client_connected = false; ///< Client connected? -int SoundBellCount; ///< Count the client's bell -bool VNC_WS_run = false; ///< Websocket running -int VNC_WS_num = -1; ///< Websocket connection number - - - -/** - * @brief Variable to hold the frame format details - */ -vnc_frame_format_t frame_format = {CONFIG_VNC_SERVER_FRAME_WIDTH, CONFIG_VNC_SERVER_FRAME_HEIGHT, frame_buffer, - 1, // RGB332 server native. - 0, // RGB555 - 0, // RGB565 - 0, // BGR233 - 0, // TRUECOLOR0888 -}; - - - -#if 0 -void dump_msg(char *buf, uint16_t buflen, char *mode) -{ - int i, l = 0; - - printf("%s %d", mode, buflen); - for (i = 0; i < buflen; i++) { - if ((i % 16) == 0) { - printf("\n%02d: ", l); - l++; - } - printf("%02x ", buf[i]); - } - printf("\n"); -} -#endif - - -/** - * @brief Structure to hold the encoding type details - */ -volatile struct encoding_type_struct -{ - uint8_t raw; - uint8_t copy_rectangle; - uint8_t rre; - uint8_t corre; - uint8_t hextile; -} encoding_type; - - -static int GetMessageData(int, char *, int); -static int GenTileUpdateData(uint8_t *); -void task_VNCserver(void *); -void task_frame(void *); -void task_WS(void *); - - - -/** - * @brief Serve a new VNC client. - */ -void vnc_netconn_serve(void); - - -/* VNC startup. */ -void VncStartup(void) -{ - /* Initialise mutex & cond vars */ - xEventGroupVNC = xEventGroupCreate(); - SoundBell_lock = xSemaphoreCreateMutex(); - - xTaskCreate(&task_VNCserver, "VNCserver", MIN_STACK_SIZE, NULL, 5, &xTaskClientHandler); - xTaskCreate(&task_frame, "frame_update", MIN_STACK_SIZE, NULL, 6, &xTaskFrameUpdate); -} - - -/** - * @brief Client Handler Task. - * - * This task handles the client initialisation sequence. Once the client - * is initialised this task handles all received messages from the client, - * but does not send any data to the client. - */ -void task_VNCserver(void *pvParameter) -{ - int server_sock; - struct sockaddr_in server_addr; - struct sockaddr_in client_addr; - socklen_t client_addr_size; - - ESP_LOGI(TAG, "Starting VNC server"); - - /* Clear the encoding type structure */ - encoding_type.raw = 0; - encoding_type.copy_rectangle = 0; - encoding_type.rre = 0; - encoding_type.corre = 0; - encoding_type.hextile = 0; - - /* Clear the sound bell counter */ - SoundBellCount = 0; - VNC_pointer_button = 0; - VNC_pointer_x = VNC_pointer_y = 0; - - /* Create socket for incomming connections */ - if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - ESP_LOGE(TAG, "socket() VNC function failed"); - exit(1); - } - - /* Construct the server address structure */ - memset(&server_addr, 0, sizeof(server_addr)); /* Fill entire structure with 0's */ - server_addr.sin_family = AF_INET; /* Internet address family */ - server_addr.sin_addr.s_addr = INADDR_ANY; /* Autofill with my IP address */ - server_addr.sin_port = htons(CONFIG_VNC_SERVER_PORT); - - /* Bind socket to local address */ - if (bind(server_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { - ESP_LOGE(TAG, "bind() VNC function failed"); - exit(1); - } - - /* Set the socket to listen for incoming connections */ - if (listen(server_sock, BACKLOG) < 0) { - ESP_LOGE(TAG, "listen() VNC function failed"); - exit(1); - } - - do { - vnc_client_sock = (accept(server_sock, (struct sockaddr *) &client_addr, &client_addr_size)); - if (vnc_client_sock >= 0) { - vnc_client_connected = true; - vnc_netconn_serve(); - vnc_client_connected = false; - } - vTaskDelay((TickType_t)10); /* allows the freeRTOS scheduler to take over if needed */ - } while (vnc_client_sock >= 0); -} - - - -/** - * @brief Serve a new VNC client and handle the whole session. - */ -void vnc_netconn_serve(void) -{ - long int temp_long; - char protocol_ver[8], message_buffer[MESSAGE_BUFFER_SIZE]; - int i, j, message_len, ProtocolOkay; - uint32_t *ptr_to_uint32; - uint16_t *ptr_to_uint16; - struct sockaddr_storage addr; - socklen_t len = sizeof addr; - char ipstr[INET6_ADDRSTRLEN]; - - getpeername(vnc_client_sock, (struct sockaddr*)&addr, &len); - if (addr.ss_family == AF_INET) { - struct sockaddr_in *s = (struct sockaddr_in *)&addr; - inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); - } - ESP_LOGI(TAG, "VNC new client %s socket %d", ipstr, vnc_client_sock); - - /* ProtocolVersion Handshake - begin */ - /* Send ProtocolVersion we want to use to client */ - message_len = sprintf(message_buffer, "RFB 003.003\n"); - if (send(vnc_client_sock, message_buffer, message_len, 0) != message_len) { - goto close_connection; - } - - /* Receive ProtocolVersion the client wants to use */ - if (GetMessageData(vnc_client_sock, &(message_buffer[0]), 12) == 0) { - goto close_connection; - } - - /* Check this is acceptable (RFB 003.xxx is okay) */ - ProtocolOkay = 1; - for (i = 0; i < 8; i++) { - if (message_buffer[i] != server_ProtocolVersion[i]) { - ProtocolOkay = 0; - } - - /* Store the protocol version - ignoring thr 'RFB ' part */ - protocol_ver[i] = message_buffer[i + 4]; - } - protocol_ver[7] = 0; - /* ProtocolVersion Handshake - end */ - - /* Authentication - begin */ - /* Send Authentication scheme to be used to client */ - if (ProtocolOkay == 0) { - /* ProtocolVerion is not okay */ - - /* Generate the Bad ProtocolVerion message */ - ptr_to_uint32 = (uint32_t *) &(message_buffer[0]); - *ptr_to_uint32 = htonl(0); - ptr_to_uint32 = (uint32_t *) &(message_buffer[4]); - *ptr_to_uint32 = htonl(strlen(bad_protocol)); - strcpy(&(message_buffer[8]), bad_protocol); - - if (send(vnc_client_sock, message_buffer, 8 + strlen(bad_protocol), 0) != (8 + strlen(bad_protocol))) { - printf("Call to send() 1 failed\n"); - } - goto close_connection; - - } else if (VNC_WS_num != -1) { - /* Busy with a websocket client */ - ptr_to_uint32 = (uint32_t *) &(message_buffer[0]); - *ptr_to_uint32 = htonl(0); - ptr_to_uint32 = (uint32_t *) &(message_buffer[4]); - *ptr_to_uint32 = htonl(strlen(server_busy)); - strcpy(&(message_buffer[8]), server_busy); - - if (send(vnc_client_sock, message_buffer, 8 + strlen(server_busy), 0) != (8 + strlen(server_busy))) { - printf("Call to send() 1 failed\n"); - } - goto close_connection; - - } else { - /* ProtocolVerion is okay - connect with no authentication*/ - - /* Generate the No Authentication message */ - ptr_to_uint32 = (uint32_t *) &(message_buffer[0]); - *ptr_to_uint32 = htonl((uint32_t)1); - - if (send(vnc_client_sock, message_buffer, 4, 0) != 4) { - goto close_connection; - } - } - /* Authentication - end */ - - /* ClientInitialisation - begin */ - /* Receive initialisation message from client (1 byte) */ - if (GetMessageData(vnc_client_sock, &(message_buffer[0]), 1) == 0) { - goto close_connection; - } - /* Do nothing with this as we only support 1 Client at a time */ - /* ClientInitialisation - end */ - - /* ServerInitialisation - begin */ - - /* Initial default RGB332 */ - Red_Max = RED_MAX; - Green_Max = GREEN_MAX; - Blue_Max = BLUE_MAX; - Red_Shift = RED_SHIFT; - Green_Shift = GREEN_SHIFT; - Blue_Shift = BLUE_SHIFT; - AltPixels = false; - - /* Create Initialisation message for client */ - ptr_to_uint16 = (uint16_t *) &(message_buffer[0]); - *ptr_to_uint16 = htons((uint16_t)CONFIG_VNC_SERVER_FRAME_WIDTH); - - ptr_to_uint16 = (uint16_t *) &(message_buffer[2]); - *ptr_to_uint16 = htons((uint16_t)CONFIG_VNC_SERVER_FRAME_HEIGHT); - - message_buffer[4] = (uint8_t)BITS_PER_PIXEL; - message_buffer[5] = (uint8_t)PIXEL_DEPTH; - message_buffer[6] = (uint8_t)BIG_ENDIAN_FLAG; - message_buffer[7] = (uint8_t)TRUE_COLOUR_FLAG; - - ptr_to_uint16 = (uint16_t *) &(message_buffer[8]); - *ptr_to_uint16 = htons(Red_Max); - - ptr_to_uint16 = (uint16_t *) &(message_buffer[10]); - *ptr_to_uint16 = htons(Green_Max); - - ptr_to_uint16 = (uint16_t *) &(message_buffer[12]); - *ptr_to_uint16 = htons(Blue_Max); - - message_buffer[14] = Red_Shift; - message_buffer[15] = Green_Shift; - message_buffer[16] = Blue_Shift; - - ptr_to_uint32 = (uint32_t *) &(message_buffer[20]); - *ptr_to_uint32 = htonl(strlen(desktop_name)); - strcpy(&(message_buffer[24]), desktop_name); - - if (send(vnc_client_sock, message_buffer, 24 + strlen(desktop_name), 0) != (24 + strlen(desktop_name))) { - printf("Call to send() 3 failed\n"); - } - /* ServerInitialisation - end */ - - /* Cancel any outstanding Sound Bell requests */ - if (xSemaphoreTake(SoundBell_lock, 10) == pdTRUE) { - SoundBellCount = 0; - xSemaphoreGive(SoundBell_lock); - } - - ESP_LOGI(TAG, "VNC client connected (RFB Protocol Ver: %s)", protocol_ver); - - /* Main message handling loop */ - while(1) { - int num_of_encodings; - - /* Receive 1st byte of message from client */ - if (GetMessageData(vnc_client_sock, &(message_buffer[0]), 1) == 0) { - goto close_connection; /* Connection lost */ - } - - switch(message_buffer[0]) { - case SET_PIXEL_FORMAT: - - /* Get the remainder (19 bytes) of message */ - if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 19) == 0) { - goto close_connection; - } - - /* Check pixel format is as expected */ - i = 0; - if (message_buffer[4] != BITS_PER_PIXEL) { - ESP_LOGI(TAG, "SetPixelFormat client wants %d bits-per-pixel", message_buffer[4]); - i++; - } - - if (message_buffer[5] != PIXEL_DEPTH) { - ESP_LOGI(TAG, "SetPixelFormat client wants %d pixel-depth", message_buffer[5]); - i++; - } - - if ((message_buffer[7] & 0x01) != TRUE_COLOUR_FLAG) { - ESP_LOGI(TAG, "SetPixelFormat client wants %d true-colour-flag", message_buffer[7]); - i++; - } - - ptr_to_uint16 = (uint16_t *)&(message_buffer[8]); - if (htons(*ptr_to_uint16) != Red_Max) { - Red_Max = htons(*ptr_to_uint16); - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d red-max", Red_Max); - } - - ptr_to_uint16 = (uint16_t *)&(message_buffer[10]); - if (htons(*ptr_to_uint16) != Green_Max) { - Green_Max = htons(*ptr_to_uint16); - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d green-max", Green_Max); - } - - ptr_to_uint16 = (uint16_t *)&(message_buffer[12]); - if (htons(*ptr_to_uint16) != Blue_Max) { - Blue_Max = htons(*ptr_to_uint16); - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d blue-max", Blue_Max); - } - - if (message_buffer[14] != Red_Shift) { - Red_Shift = message_buffer[14]; - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d red-shift", Red_Shift); - } - - if (message_buffer[15] != Green_Shift) { - Green_Shift = message_buffer[15]; - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d green-shift", Green_Shift); - } - - if (message_buffer[16] != Blue_Shift) { - Blue_Shift = message_buffer[16]; - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d blue-shift", Blue_Shift); - } - - if (i) { - ESP_LOGI(TAG, "SetPixelFormat %d errors, disconnect client", i); - ESP_LOGI(TAG, "Ensure the 'Auto select' is not enabled in your vncviewer options,"); - goto close_connection_quietly; - } - - break; - - case FIX_COLOUR_MAP_ENTRIES: -printf("fix colormap entries\n"); - /* Not supported, just get the data from the buffer and ignore it */ - - /* Get the next 5 bytes of message */ - if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 5) == 0) { - goto close_connection; - } - - /* Calculate how many colour entries are in the buffer */ - i = message_buffer[4]*255 + message_buffer[5]; - i *= 6; - - /* Get this amount of data from the buffer */ - for (j = 0; j < i; j++) { - if (GetMessageData(vnc_client_sock, &(message_buffer[6]), 6) == 0) { - goto close_connection; - } - } - - break; - - case SET_ENCODINGS: - - /* Get the next 3 bytes of message */ - if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 3) == 0) { - goto close_connection; - } - - num_of_encodings = message_buffer[2]*255 + message_buffer[3]; - - /* Get the remainder of message */ - if (GetMessageData(vnc_client_sock, &(message_buffer[0]), 4 * num_of_encodings) == 0) { - goto close_connection; - } - - /* Clear the encoding type structure */ - encoding_type.raw = 0; - encoding_type.copy_rectangle = 0; - encoding_type.rre = 0; - encoding_type.corre = 0; - encoding_type.hextile = 0; - - for (i = 0; i < num_of_encodings; i++) { - switch(message_buffer[3 + (i*4)]) { - case 0: /* Raw encoding */ - encoding_type.raw = i + 1; - break; - case 1: /* Copy rectangle encoding */ - encoding_type.copy_rectangle = i + 1; - break; - case 2: /* RRE encoding */ - encoding_type.rre = i + 1; - break; - case 4: /* CoRRE encoding */ - encoding_type.corre = i + 1; - break; - case 5: /* Hextile encoding */ - encoding_type.hextile = i + 1; - break; - default: /* Unknown coding type - do nothing */ - break; - } - } - break; - - case FRAME_BUFFER_UPDATE_REQ: - /* Get the remainder of message (9 bytes) */ - if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 9) == 0) { - goto close_connection; - } - - if (!message_buffer[1]) { - /* Non-incremental mode - mark the squares that need to be updated */ - for (i = (message_buffer[2]*255 + message_buffer[3])/TILE_SIZE; - i <= (message_buffer[2]*255 + message_buffer[3] + message_buffer[6]*255 + message_buffer[7])/TILE_SIZE; - i++) { - for (j = (message_buffer[4]*255 + message_buffer[5])/TILE_SIZE; - j <= (message_buffer[4]*255 + message_buffer[5] + message_buffer[8]*255 + message_buffer[9])/TILE_SIZE; - j++) { - tile_updated[j][i] = 1; - } - } - } - - /* Signal that there is now a pending update request */ - xEventGroupSetBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ); - break; - - case KEY_EVENT: - /* Handle the key event, ignored for brewboard */ - /* Get the remainder of message (7 bytes) */ - if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 7) == 0) { - goto close_connection; - } - break; - - case POINTER_EVENT: - /* Handle the pointer event, simulate the touch screen. */ - /* Get the remainder of message (5 bytes) */ - if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 5) == 0) { - goto close_connection; - } - /* Set global variables that will be read by another task. */ - VNC_pointer_button = message_buffer[1]; - VNC_pointer_x = message_buffer[2]*255 + message_buffer[3]; - VNC_pointer_y = message_buffer[4]*255 + message_buffer[5]; - break; - - case CLIENT_CUT_TEXT: - /* Handle the client has cut text event */ - /* Current we just get and discard the data */ - /* Get the next 7 bytes of the message */ - if (GetMessageData(vnc_client_sock, &(message_buffer[1]), 7) == 0) { - goto close_connection; - } - - ptr_to_uint32 = (uint32_t *)&(message_buffer[4]); - temp_long = htonl(*ptr_to_uint32); - - while (temp_long > 0) { - /* Get the text in chunks MESSAGE_BUFFER_SIZE-1 characters */ - if (temp_long > MESSAGE_BUFFER_SIZE-2) { - if (GetMessageData(vnc_client_sock, &(message_buffer[0]), MESSAGE_BUFFER_SIZE-1) == 0) { - goto close_connection; - } - - message_buffer[MESSAGE_BUFFER_SIZE-1] = 0; - temp_long -= (MESSAGE_BUFFER_SIZE-1); - } else { - if (GetMessageData(vnc_client_sock, &(message_buffer[0]), temp_long) == 0) { - goto close_connection; - } - - message_buffer[temp_long] = 0; - temp_long = 0; - } - } - - break; - - default: - ESP_LOGI(TAG, "Unknown message %d from client", message_buffer[0]); - } - - vTaskDelay( (TickType_t)1); - } - -close_connection: - ESP_LOGI(TAG, "VNC client disconnected"); - -close_connection_quietly: - - /* Cancel any outstanding update requests */ - xEventGroupClearBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ); - close(vnc_client_sock); -} - - - -/** - * @brief Frame update task. This thread handles the sending of all frame - * update data to the client and sends the 'ring bell' message to - * the client when required. - * Works for VNC port connected clients and Websocket clients. - * @param pvParameter Ignored - */ -void task_frame(void *pvParameter) -{ - int i, j, x_pos, y_pos, packet_length, num_updated_tiles; - uint16_t *ptr_to_uint16; - /* These are declared static so they don't use thread stack memory */ - static uint8_t FramebufferUpdate_msg[4 + 12 + TILE_SIZE*TILE_SIZE*BITS_PER_PIXEL/8 + 1460]; - static int FrameBufferPtr; /* Pointer to next space in buffer */ - static int tile_updated_local[NUM_TILES_Y_AXIS][NUM_TILES_X_AXIS]; - - ESP_LOGI(TAG, "Starting VNC frame updater"); - - while(1) { - /* Wait until client sends a frame update request */ -wait_for_client: - xEventGroupWaitBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ, pdFALSE, pdFALSE, portMAX_DELAY); - - /* Copy tile_updated array to local version and clear copied tiles */ - vTaskSuspendAll(); - num_updated_tiles = 0; - for (i = 0; i < NUM_TILES_Y_AXIS; i++) { - for (j = 0; j < NUM_TILES_X_AXIS; j++) { - if (tile_updated[i][j]) { - tile_updated_local[i][j] = 1; - tile_updated[i][j] = 0; - num_updated_tiles++; /* Keep count of the updated tiles */ - } - } - } - xTaskResumeAll(); - - if (num_updated_tiles) { - /* Cancel update request */ - xEventGroupClearBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ); - /* Fill in constant parts of FramebufferUpdate Message */ - FramebufferUpdate_msg[0] = 0; /* Message-type */ - FramebufferUpdate_msg[1] = 0; /* Padding */ - ptr_to_uint16 = (uint16_t *) &(FramebufferUpdate_msg[2]); - *ptr_to_uint16 = htons(num_updated_tiles); /* Number-of-rectangles */ - FrameBufferPtr = 4; - - for (y_pos = 0; y_pos < NUM_TILES_Y_AXIS; y_pos++) { - for (x_pos = 0; x_pos < NUM_TILES_X_AXIS; x_pos++) { - if (tile_updated_local[y_pos][x_pos]) { - /* Send current square data to client */ - - /* x-position */ - FramebufferUpdate_msg[FrameBufferPtr+0] = (x_pos * TILE_SIZE) / 256; - FramebufferUpdate_msg[FrameBufferPtr+1] = (x_pos * TILE_SIZE) % 256; - - /* y-position */ - FramebufferUpdate_msg[FrameBufferPtr+2] = (y_pos * TILE_SIZE) / 256; - FramebufferUpdate_msg[FrameBufferPtr+3] = (y_pos * TILE_SIZE) % 256; - - - /* Set width of tile in packet */ - if (x_pos == (NUM_TILES_X_AXIS -1)) { - /* Last tile in X-axis */ - FramebufferUpdate_msg[FrameBufferPtr+4] = LAST_TILE_WIDTH / 256; - FramebufferUpdate_msg[FrameBufferPtr+5] = LAST_TILE_WIDTH % 256; - } else { - FramebufferUpdate_msg[FrameBufferPtr+4] = TILE_SIZE / 256; - FramebufferUpdate_msg[FrameBufferPtr+5] = TILE_SIZE % 256; - } - - if (y_pos == (NUM_TILES_Y_AXIS -1)) { - /* Last tile in Y-axis */ - FramebufferUpdate_msg[FrameBufferPtr+6] = LAST_TILE_HEIGHT / 256; - FramebufferUpdate_msg[FrameBufferPtr+7] = LAST_TILE_HEIGHT % 256; - } else { - FramebufferUpdate_msg[FrameBufferPtr+6] = TILE_SIZE / 256; - FramebufferUpdate_msg[FrameBufferPtr+7] = TILE_SIZE % 256; - } - - /* Generate the packet data for this tile */ - packet_length = GenTileUpdateData(&(FramebufferUpdate_msg[FrameBufferPtr])); - - /* Send the packet data for this tile to the client */ - FrameBufferPtr += packet_length; - - if (FrameBufferPtr > 1460) { - /* Send the data to the client */ - if (VNC_WS_num != -1) { - ws_server_send_bin_client(VNC_WS_num, (char *)FramebufferUpdate_msg, FrameBufferPtr); - } - if (vnc_client_connected) { - if (send(vnc_client_sock, FramebufferUpdate_msg, FrameBufferPtr, 0) != FrameBufferPtr) { - goto wait_for_client; - } - } - FrameBufferPtr = 0; - } - - tile_updated_local[y_pos][x_pos] = 0; /* Clear the update bit for this square */ - } - } - } - - if (FrameBufferPtr > 0) { - /* Last data for this update, send it to the client */ - if (VNC_WS_num != -1) { - ws_server_send_bin_client(VNC_WS_num, (char *)FramebufferUpdate_msg, FrameBufferPtr); - } - if (vnc_client_connected) { - if (send(vnc_client_sock, FramebufferUpdate_msg, FrameBufferPtr, 0) != FrameBufferPtr) { - goto wait_for_client; - } - } - - FrameBufferPtr = 0; - } - - } else { /* if (num_updated_tiles) */ - /* There was no new display data to send to the client */ - /* Sleep for 1/20th second before checking again */ - vTaskDelay(20 / portTICK_PERIOD_MS); - } - - /* Check for sound bell event */ - if (xSemaphoreTake(SoundBell_lock, 10) == pdTRUE) { - if (SoundBellCount) { - --SoundBellCount; - xSemaphoreGive(SoundBell_lock); - - if (vnc_client_connected) { - if (send(vnc_client_sock, sound_bell, 1, 0) != 1) { - goto wait_for_client; - } - } - if (VNC_WS_num != -1) { - ws_server_send_bin_client(VNC_WS_num, sound_bell, 1); - } - } else { - xSemaphoreGive(SoundBell_lock); - } - } - } -} - - - -/** - * Convert a framebuffer pixel to BGR233 if needed. - * @param pixel The 8 bit pixel value - * @return Then unchanged or changed pixel. - */ -vnc_color_t IRAM_ATTR PixelConvert(vnc_color_t pixel) -{ - if (!AltPixels) - return pixel; - - return (((pixel >> RED_SHIFT) & RED_MAX) << Red_Shift) | - (((pixel >> GREEN_SHIFT) & GREEN_MAX) << Green_Shift) | - (((pixel >> BLUE_SHIFT) & BLUE_MAX) << Blue_Shift); -} - - - -/** - * @brief Generate tile update data function - * - * This function is called by the frame_update thread to generate the message - * data for a tile to send to the client. This function expects the - * x-position, y-position, width and height fields of the buffer to be filled - * in before it is called. - * - * The format of the buffer is: - * packet_buffer[0:1] - x-position of tile - * packet_buffer[2:3] - y-position of tile - * packet_buffer[4:5] - width of tile - * packet_buffer[6:7] - height of tile - * packet_buffer[8 onwards] - Pixel data for the tile - * - * The pixel data will be encoded with CoRRE encoding (if the CDL option is - * enabled and the client can handle it) or RAW encoding if that is smaller - * than CoRRE encoding for that particular tile. - * - * @param packet_buffer Buffer to store tile data - * @return Length of generated data in bytes - */ -static int GenTileUpdateData(uint8_t *packet_buffer) -{ - uint16_t x_pos, y_pos; - int i, j; - int tile_width, tile_height; - - /* Get the X and Y positions of this tile from the packet buffer */ - x_pos = packet_buffer[0] * 256 + packet_buffer[1]; - y_pos = packet_buffer[2] * 256 + packet_buffer[3]; - - /* Get the tile width and height from the packet buffer */ - tile_width = packet_buffer[4] * 256 + packet_buffer[5]; - tile_height = packet_buffer[6] * 256 + packet_buffer[7]; - - /* Create packet data using RAW encoding */ - for (i = 0; i < tile_height; i++) { - for (j = 0; j < tile_width; j++) { - if (Bits_Per_Pixel == 8) { - packet_buffer[12 + tile_width * i + j] = PixelConvert(frame_buffer[y_pos + i][x_pos + j]); - } else { - packet_buffer[12 + 2 * tile_width * i + 2*j] = COLOUR2BYTE0(frame_buffer[y_pos + i][x_pos + j]); - packet_buffer[12 + 2 * tile_width * i + 2*j+ 1] = COLOUR2BYTE1(frame_buffer[y_pos + i][x_pos + j]); - } - } - } - - /* Set the encoding type to raw */ - packet_buffer[8+0] = 0; - packet_buffer[8+1] = 0; - packet_buffer[8+2] = 0; - packet_buffer[8+3] = 0; - - return (12 + tile_width*tile_height*(Bits_Per_Pixel/8)); -} - - - -/** - * @brief Get message data function - * This function is called by the client_handler thread to get data - * from the client's socket. - * - * @param socket_fd File descriptor of the socket to get the data from. - * @param *buffer Buffer to store received data in. - * @param num_bytes Number of bytes to attempt to get. - * - * @return 1 on sucessfull completion - 0 on error. - */ -static int GetMessageData(int socket_fd, char *buffer, int num_bytes) -{ - int bytes_rxd; - int message_len = 0; - - while (message_len < num_bytes) { - if ((bytes_rxd = recv(socket_fd, buffer, num_bytes, 0)) <= 0) { - return 0; - } - message_len += bytes_rxd; - } - - return 1; -} - - - -void VncCls(vnc_color_t color) -{ - /* Clear the frame buffer */ - int i, j; - - for (i = 0; i < CONFIG_VNC_SERVER_FRAME_HEIGHT; i++) { - for (j = 0; j < CONFIG_VNC_SERVER_FRAME_WIDTH; j++) { - VncDrawPixel(j, i, color); - } - } -} - - - -void IRAM_ATTR VncDrawPixel(uint16_t x, uint16_t y, vnc_color_t color) -{ - if (x >= CONFIG_VNC_SERVER_FRAME_WIDTH || y >= CONFIG_VNC_SERVER_FRAME_HEIGHT) { - printf("write_frame(%d, %d) tile %d/%d\n", x, y, x/TILE_SIZE, y/TILE_SIZE); - return; - } - - /* Set that pixel to 'colour' */ - frame_buffer[y][x] = color; - - /* Mark the tile for update */ - tile_updated[y/TILE_SIZE][x/TILE_SIZE] = 1; -} - - - -void IRAM_ATTR VncDrawHorzLine(uint16_t x1, uint16_t x2, uint16_t y, vnc_color_t color) -{ - int i; - - /* Draw the line */ - for (i = x1; i <= x2; i++) { - VncDrawPixel(i, y, color); - } -} - - - -void IRAM_ATTR VncDrawVertLine(uint16_t x, uint16_t y1, uint16_t y2, vnc_color_t color) -{ - int i; - - /* Draw the line */ - for (i = y1; i <= y2; i++) { - VncDrawPixel(x, i, color); - } -} - - - -void IRAM_ATTR VncFillRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, vnc_color_t color) -{ - /* Draw a solid rectangle */ - int i, j; - - for (i = y1; i <= y2; i++) { - for (j = x1; j <= x2; j++) { - VncDrawPixel(j, i, color); - } - } -} - - - -void VncSoundBell(void) -{ - if (xSemaphoreTake(SoundBell_lock, 10) == pdTRUE) { - SoundBellCount++; - xSemaphoreGive(SoundBell_lock); - } -} - - - -/** - * @brief Websocket task. Created on a websocket connection. - */ -void task_WS(void *pvParameter) -{ - int i, j, num_of_encodings; - uint16_t *ptr_to_uint16; - struct strMessage _msg; - - VNC_WS_run = true; - - while (VNC_WS_run) { - - /* - * Wait until something is received from the client. Exit the queue receiver - * each 5 milliseconds to allow to evaluate the VNC_WS_run flag and to allow - * a clean exit of this task. - */ - if (xQueueReceive(message_queue, &_msg, 5 / portTICK_PERIOD_MS) == pdTRUE) { - - switch (_msg.message[0]) { - - case SET_PIXEL_FORMAT: - /* Check total message length */ - if (_msg.length >= 20) { - /* Check pixel format is as expected */ - i = 0; - if (_msg.message[4] != BITS_PER_PIXEL) { - ESP_LOGI(TAG, "SetPixelFormat client wants %d bits-per-pixel", _msg.message[4]); - i++; - } - - if (_msg.message[5] != PIXEL_DEPTH) { - ESP_LOGI(TAG, "SetPixelFormat client wants %d pixel-depth", _msg.message[5]); - i++; - } - - if ((_msg.message[7] & 0x01) != TRUE_COLOUR_FLAG) { - ESP_LOGI(TAG, "SetPixelFormat client wants %d true-colour-flag", _msg.message[7]); - i++; - } - - ptr_to_uint16 = (uint16_t *)&(_msg.message[8]); - if (htons(*ptr_to_uint16) != Red_Max) { - Red_Max = htons(*ptr_to_uint16); - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d red-max", Red_Max); - } - - ptr_to_uint16 = (uint16_t *)&(_msg.message[10]); - if (htons(*ptr_to_uint16) != Green_Max) { - Green_Max = htons(*ptr_to_uint16); - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d green-max", Green_Max); - } - - ptr_to_uint16 = (uint16_t *)&(_msg.message[12]); - if (htons(*ptr_to_uint16) != Blue_Max) { - Blue_Max = htons(*ptr_to_uint16); - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d blue-max", Blue_Max); - } - - if (_msg.message[14] != Red_Shift) { - Red_Shift = _msg.message[14]; - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d red-shift", Red_Shift); - } - - if (_msg.message[15] != Green_Shift) { - Green_Shift = _msg.message[15]; - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d green-shift", Green_Shift); - } - - if (_msg.message[16] != Blue_Shift) { - Blue_Shift = _msg.message[16]; - AltPixels = true; - ESP_LOGI(TAG, "SetPixelFormat client granted %d blue-shift", Blue_Shift); - } - - if (i) { - ESP_LOGI(TAG, "SetPixelFormat %d errors, disconnect client", i); - ESP_LOGI(TAG, "Ensure the 'Auto select' is not enabled in your vncviewer options,"); - _msg.length = 0; - ws_server_remove_client(VNC_WS_num); - } - } - break; - - case FIX_COLOUR_MAP_ENTRIES: - printf("FIX_COLOUR_MAP_ENTRIES\n"); - break; - - case SET_ENCODINGS: - if (_msg.length >= 3) { - // Get the total encodings - num_of_encodings = _msg.message[2]*255 + _msg.message[3]; - - /* Clear the encoding type structure */ - encoding_type.raw = 0; - encoding_type.copy_rectangle = 0; - encoding_type.rre = 0; - encoding_type.corre = 0; - encoding_type.hextile = 0; - - for (i = 0; i < num_of_encodings; i++) { - switch(_msg.message[3 + (i*4)]) { - case 0: /* Raw encoding */ - encoding_type.raw = i + 1; - break; - case 1: /* Copy rectangle encoding */ - encoding_type.copy_rectangle = i + 1; - break; - case 2: /* RRE encoding */ - encoding_type.rre = i + 1; - break; - case 4: /* CoRRE encoding */ - encoding_type.corre = i + 1; - break; - case 5: /* Hextile encoding */ - encoding_type.hextile = i + 1; - break; - default: /* Unknown coding type - do nothing */ - break; - } - } - } - break; - - case FRAME_BUFFER_UPDATE_REQ: - if (_msg.length == 10) { - if (!_msg.message[1]) { - /* Non-incremental mode - mark the squares that need to be updated */ - for (i = (_msg.message[2]*255 + _msg.message[3])/TILE_SIZE; - i <= (_msg.message[2]*255 + _msg.message[3] + _msg.message[6]*255 + _msg.message[7])/TILE_SIZE; - i++) { - for (j = (_msg.message[4]*255 + _msg.message[5])/TILE_SIZE; - j <= (_msg.message[4]*255 + _msg.message[5] + _msg.message[8]*255 + _msg.message[9])/TILE_SIZE; - j++) { - tile_updated[j][i] = 1; - } - } - } - - /* Signal that there is now a pending update request */ - xEventGroupSetBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ); - } - break; - - case KEY_EVENT: - printf("KEY_EVENT\n"); - /* Handle the key event, ignored for brewboard */ - /* Get the remainder of message (7 bytes) */ - break; - - case POINTER_EVENT: - /* Handle the pointer event, simulate the touch screen. */ - if (_msg.length == 6) { - /* Set global variables that will be read by another task. */ - VNC_pointer_button = _msg.message[1]; - VNC_pointer_x = _msg.message[2]*255 + _msg.message[3]; - VNC_pointer_y = _msg.message[4]*255 + _msg.message[5]; - } - _msg.length = 0; - break; - - case CLIENT_CUT_TEXT: - printf("CLIENT_CUT_TEXT\n"); - break; - - default: - ESP_LOGI(TAG, "Unknown message %d from client", _msg.message[0]); - } - } - } - - VNC_WS_num = -1; - xEventGroupClearBits(xEventGroupVNC, VNC_CLIENT_UPDATE_REQ); - ESP_LOGI(TAG, "task_WS finished"); - vTaskDelete(NULL); -} - - - -int VncStartWS(int num) -{ - char protocol_ver[8], message_buffer[MESSAGE_BUFFER_SIZE]; - int i, ProtocolOkay; - uint32_t *ptr_to_uint32; - uint16_t *ptr_to_uint16; - struct strMessage _msg; - - ESP_LOGI(TAG, "Start VNC WebSocket connection %d", num); - message_queue = xQueueCreate(message_queue_size, sizeof(struct strMessage)); - - /* - * Initial handshake - */ - ws_server_send_bin_client(num, "RFB 003.003\n", 12); - ProtocolOkay = 1; - if (xQueueReceive(message_queue, &_msg, 5000 / portTICK_PERIOD_MS) == pdTRUE) { -// dump_msg((char *)_msg.message, _msg.length, "pull"); - - for (i = 0; i < 8; i++) { - if (_msg.message[i] != server_ProtocolVersion[i]) { - ProtocolOkay = 0; - } - /* Store the protocol version - ignoring thr 'RFB ' part */ - protocol_ver[i] = _msg.message[i + 4]; - } - protocol_ver[7] = 0; - } else { - ESP_LOGE(TAG, "Client timeout after initial message"); - return -5; - } - - if (ProtocolOkay == 0) { - /* Generate the Bad ProtocolVerion message */ - ESP_LOGI(TAG, "Start VNC WebSocket task failed, bad protocol."); - ptr_to_uint32 = (uint32_t *) &(message_buffer[0]); - *ptr_to_uint32 = htonl(0); - ptr_to_uint32 = (uint32_t *) &(message_buffer[4]); - *ptr_to_uint32 = htonl(strlen(bad_protocol)); - strcpy(&(message_buffer[8]), bad_protocol); - ws_server_send_bin_client(num, message_buffer, 8 + strlen(bad_protocol)); - vTaskDelay(500 / portTICK_PERIOD_MS); - ws_server_remove_client(num); - return -2; - } - /* ProtocolVerion is okay - connect with no authentication*/ - - /* Server is busy with another client */ - if (VNC_WS_run || vnc_client_connected) { - ESP_LOGI(TAG, "Start VNC WebSocket task failed, server busy."); - ptr_to_uint32 = (uint32_t *) &(message_buffer[0]); - *ptr_to_uint32 = htonl(0); - ptr_to_uint32 = (uint32_t *) &(message_buffer[4]); - *ptr_to_uint32 = htonl(strlen(server_busy)); - strcpy(&(message_buffer[8]), server_busy); - ws_server_send_bin_client(num, message_buffer, 8 + strlen(server_busy)); - vTaskDelay(500 / portTICK_PERIOD_MS); - ws_server_remove_client(num); - return -1; - } - - /* Generate the No Authentication message */ - ptr_to_uint32 = (uint32_t *) &(message_buffer[0]); - *ptr_to_uint32 = htonl((uint32_t)1); - ws_server_send_bin_client(num, message_buffer, 4); - /* Authentication - end */ - - /* ClientInitialisation - begin */ - /* Receive initialisation message from client (1 byte) */ - if (xQueueReceive(message_queue, &_msg, 5000 / portTICK_PERIOD_MS) == pdFALSE) { - ESP_LOGE(TAG, "Client timeout after auth message"); - return -5; - } - /* Do nothing with this as we only support 1 Client at a time */ - /* ClientInitialisation - end */ - - /* Initial default RGB332 */ - Red_Max = RED_MAX; - Green_Max = GREEN_MAX; - Blue_Max = BLUE_MAX; - Red_Shift = RED_SHIFT; - Green_Shift = GREEN_SHIFT; - Blue_Shift = BLUE_SHIFT; - AltPixels = false; - - /* ServerInitialisation - begin */ - /* Create Initialisation message for client */ - ptr_to_uint16 = (uint16_t *) &(message_buffer[0]); - *ptr_to_uint16 = htons((uint16_t)CONFIG_VNC_SERVER_FRAME_WIDTH); - - ptr_to_uint16 = (uint16_t *) &(message_buffer[2]); - *ptr_to_uint16 = htons((uint16_t)CONFIG_VNC_SERVER_FRAME_HEIGHT); - - message_buffer[4] = (uint8_t)BITS_PER_PIXEL; - message_buffer[5] = (uint8_t)PIXEL_DEPTH; - message_buffer[6] = (uint8_t)BIG_ENDIAN_FLAG; - message_buffer[7] = (uint8_t)TRUE_COLOUR_FLAG; - - ptr_to_uint16 = (uint16_t *) &(message_buffer[8]); - *ptr_to_uint16 = htons(Red_Max); - - ptr_to_uint16 = (uint16_t *) &(message_buffer[10]); - *ptr_to_uint16 = htons(Green_Max); - - ptr_to_uint16 = (uint16_t *) &(message_buffer[12]); - *ptr_to_uint16 = htons(Blue_Max); - - message_buffer[14] = Red_Shift; - message_buffer[15] = Green_Shift; - message_buffer[16] = Blue_Shift; - - ptr_to_uint32 = (uint32_t *) &(message_buffer[20]); - *ptr_to_uint32 = htonl(strlen(desktop_name)); - strcpy(&(message_buffer[24]), desktop_name); - -// dump_msg(message_buffer, 24 + strlen(desktop_name), (char *)"send"); - ws_server_send_bin_client(num, message_buffer, 24 + strlen(desktop_name)); - - /* ServerInitialisation - end */ - ESP_LOGI(TAG, "VNC WebSocket client connected (RFB Protocol Ver: %s)", protocol_ver); - - VNC_WS_num = num; - xTaskCreate(&task_WS, "WSclient", MIN_STACK_SIZE, NULL, 5, &xTaskWSclient); - return 0; -} - - - -void VncStopWS(int num) -{ - if (! VNC_WS_run) { - ESP_LOGI(TAG, "Stop VNC WebSocket, not running."); - return; - } - - if (num != VNC_WS_num) { - ESP_LOGI(TAG, "Stop VNC WebSocket, %d is running, requested %d", VNC_WS_num, num); - return; - } - - ESP_LOGI(TAG, "Stop VNC WebSocket task connection %d", num); - VNC_WS_run = false; - xQueueReset(message_queue); -} - - - -void VncGetWSmessage(char *msg, uint16_t len) -{ - int max; - struct strMessage _msg; - - if (len == 0) - return; - - max = len; - if (max > MESSAGE_BUFFER_SIZE) { - ESP_LOGE(TAG, "VncGetWSmessage need %d bytes in a %d length buffer", len, MESSAGE_BUFFER_SIZE); - max = MESSAGE_BUFFER_SIZE; - } - - for (int i = 0; i < max; i++) { - _msg.message[i] = msg[i]; - } - _msg.length = max; - if (xQueueSendToBack(message_queue, &_msg, 200 / portTICK_PERIOD_MS) == pdFALSE) { - ESP_LOGE(TAG, "VncGetWSmessage() Queue full, message lost"); - } -} - diff -r 1b82a6d50a39 -r 537ffe280775 components/vnc_server/vnc-server.h --- a/components/vnc_server/vnc-server.h Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/** - * @file vnc-server.h - * @brief VNC server original written for eCos. - * - * The VNC server runs on the target platform and waits for a client - * (vncviewer program running on a PC) to connect via an ethernet connection - * (port 5900). Once a client has connected, the target platform has a - * virtual screen, keyboard and mouse. - * - * This port of the VNC server has been designed with some limitations in - * order to keep memory and processor power requirements to a minimum. - * - * The VNC client must accept the settings that the VNC server suggests (bits-per-pixel, - * number-of-colours and so on as specified at build time with the eCos configuration - * tool) or the VNC server will just disconnect. - * - * The VNC server only supports CoRRE encoding and RAW encoding for sending - * display data to the client. - * - * The VNC server does not support password authentication, the client is able - * to connect without the user typing in a password. - * - * Only one VNC client may connect to the VNC server at a time. - * - * In reality these limitations are not a problem. - * - * @author Chris Garry - * @author Michiel Broek. - */ - - - -#include -#include -#include -#include -#include -#include -#include -#include "lwip/sockets.h" -#include "lwip/netdb.h" -#include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "freertos/event_groups.h" - - - -/** - * @brief Type to hold the frame format details - */ -typedef struct -{ - uint16_t frame_width; ///< Frame width - uint16_t frame_height; ///< Frame height - void *frame_buffer; ///< Frame buffer data - bool rgb332; ///< 8 bits RGB format (only one is set). - bool rgb555; ///< 15 bits RGB - bool rgb565; ///< 16 bits RGB - bool bgr233; ///< 8 bits BGR format - bool truecolor0888; ///< 24 bits truecolor. -} vnc_frame_format_t; - - - -typedef uint8_t vnc_color_t; - - - -/** - * @brief Start the VNC server. Two tasks are started, one to handle the - * clients and one that serves the updates of the framebuffer. - */ -void VncStartup(void); - -/** - * @brief Clear the display and set a background color. - * @param color Then RGB color for the background. - */ -void VncCls(vnc_color_t color); - -/** - * @brief Draw a pixel on the display. - * @param x The horizontal position of the pixel. - * @param y The vertical position of the pixel. - * @param color The RGB value of the pixel. - */ -void VncDrawPixel(uint16_t x, uint16_t y, vnc_color_t color); - -/** - * @brief Draw a horizontal line on the display. - * @param x1 Start horizontal position. - * @param x2 End of the horizontal position. - * @param y The vertical position of the line. - * @param color The RGB color of the line. - */ -void VncDrawHorzLine(uint16_t x1, uint16_t x2, uint16_t y, vnc_color_t color); - -/** - * @brief Draw a vertical line on the display. - * @param x The jprizontal position of the line. - * @param y1 The vertical top position of the line. - * @param y2 The vertical bottom position of the line. - * @param color The RGB color of the line. - */ -void VncDrawVertLine(uint16_t x, uint16_t y1, uint16_t y2, vnc_color_t color); - -/** - * @brief Fill a rectangle with the given color. - * @param x1 The top-left horizontal start position. - * @param y1 The top-left vertical start position. - * @param x2 The bottom-right horizontal end position. - * @param y2 The bottom-right vertical end position. - * @param color The RGB color of the line. - */ -void VncFillRect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, vnc_color_t color); - -/** - * @brief Sound the bell on the client computer. - */ -void VncSoundBell(void); - - -/** - * @brief Macro to convert from RGB to colour values - */ -#define VNC_RGB2COL(r,g,b) (vnc_color_t)(((((uint8_t)r)&0xE0) >> 0) | ((((uint8_t)g)&0xE0) >> 3) | ((((uint8_t)b)&0xC0) >> 6)) - - -/** - * @brief Start task for a websocket client. - */ -int VncStartWS(int num); - -/** - * @brief Stop task for a websocket client. - */ -void VncStopWS(int num); - -/** - * @brief Remote websocket message to the VNC server. - */ -void VncGetWSmessage(char *msg, uint16_t len); - diff -r 1b82a6d50a39 -r 537ffe280775 image/files.list --- a/image/files.list Thu May 02 11:57:07 2019 +0200 +++ b/image/files.list Thu May 02 17:12:06 2019 +0200 @@ -3,73 +3,13 @@ fonts/Grotesk24x48.fon fonts/SmallFont.fon fonts/Ubuntu.fon -w/app/error-handler.js.gz -w/app/localization.js.gz -w/app/ui.js.gz -w/app/webutil.js.gz -w/app/images/clipboard.svg.gz -w/app/images/connect.svg.gz -w/app/images/disconnect.svg.gz -w/app/images/drag.svg.gz -w/app/images/error.svg.gz -w/app/images/expander.svg.gz -w/app/images/fullscreen.svg.gz -w/app/images/handle.svg.gz -w/app/images/handle_bg.svg.gz -w/app/images/info.svg.gz -w/app/images/mouse_left.svg.gz -w/app/images/mouse_middle.svg.gz -w/app/images/mouse_none.svg.gz -w/app/images/mouse_right.svg.gz -w/app/images/settings.svg.gz -w/app/images/warning.svg.gz -w/app/locale/de.json -w/app/locale/el.json -w/app/locale/es.json -w/app/locale/nl.json -w/app/locale/pl.json -w/app/locale/sv.json -w/app/locale/tr.json -w/app/locale/zh.json -w/app/sounds/bell.mp3 -w/app/sounds/bell.oga -w/app/styles/base.css w/app/styles/web.css -w/core/base64.js.gz -w/core/des.js.gz -w/core/display.js.gz -w/core/encodings.js.gz -w/core/inflator.js.gz -w/core/rfb.js.gz -w/core/websock.js.gz -w/core/input/mouse.js.gz -w/core/util/browser.js.gz -w/core/util/events.js.gz -w/core/util/eventtarget.js.gz -w/core/util/logging.js.gz -w/core/util/polyfill.js.gz -w/core/util/strings.js.gz w/css/style.css w/js/Chart.min.js.gz w/js/ch-plug-anno.min.js.gz w/js/jquery-1.12.4.min.js.gz w/js/webui.js -w/js/modl/babel.js.gz -w/js/modl/brloader.js.gz -w/js/utils/common.js.gz -w/js/zlib/adler32.js.gz -w/js/zlib/constants.js.gz -w/js/zlib/crc32.js.gz -w/js/zlib/deflate.js.gz -w/js/zlib/gzheader.js.gz -w/js/zlib/inffast.js.gz -w/js/zlib/inflate.js.gz -w/js/zlib/inftrees.js.gz -w/js/zlib/messages.js.gz -w/js/zlib/trees.js.gz -w/js/zlib/zstream.js.gz w/chart.html w/index.html.gz w/logs.html -w/vnc.html.gz w/webui.html diff -r 1b82a6d50a39 -r 537ffe280775 image/version.txt --- a/image/version.txt Thu May 02 11:57:07 2019 +0200 +++ b/image/version.txt Thu May 02 17:12:06 2019 +0200 @@ -1,1 +1,1 @@ -0.0.g +0.1.a diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/error-handler.js.gz Binary file image/w/app/error-handler.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/clipboard.svg.gz Binary file image/w/app/images/clipboard.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/connect.svg.gz Binary file image/w/app/images/connect.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/disconnect.svg.gz Binary file image/w/app/images/disconnect.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/drag.svg.gz Binary file image/w/app/images/drag.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/error.svg.gz Binary file image/w/app/images/error.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/expander.svg.gz Binary file image/w/app/images/expander.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/fullscreen.svg.gz Binary file image/w/app/images/fullscreen.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/handle.svg.gz Binary file image/w/app/images/handle.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/handle_bg.svg.gz Binary file image/w/app/images/handle_bg.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/info.svg.gz Binary file image/w/app/images/info.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/mouse_left.svg.gz Binary file image/w/app/images/mouse_left.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/mouse_middle.svg.gz Binary file image/w/app/images/mouse_middle.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/mouse_none.svg.gz Binary file image/w/app/images/mouse_none.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/mouse_right.svg.gz Binary file image/w/app/images/mouse_right.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/settings.svg.gz Binary file image/w/app/images/settings.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/images/warning.svg.gz Binary file image/w/app/images/warning.svg.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/locale/de.json --- a/image/w/app/locale/de.json Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -{ - "Connecting...": "Verbinden...", - "Disconnecting...": "Verbindung trennen...", - "Reconnecting...": "Verbindung wiederherstellen...", - "Internal error": "Interner Fehler", - "Must set host": "Richten Sie den Server ein", - "Connected (encrypted) to ": "Verbunden mit (verschlüsselt) ", - "Connected (unencrypted) to ": "Verbunden mit (unverschlüsselt) ", - "Something went wrong, connection is closed": "Etwas lief schief, Verbindung wurde getrennt", - "Disconnected": "Verbindung zum Server getrennt", - "New connection has been rejected with reason: ": "Verbindung wurde aus folgendem Grund abgelehnt: ", - "New connection has been rejected": "Verbindung wurde abgelehnt", - "Password is required": "Passwort ist erforderlich", - "noVNC encountered an error:": "Ein Fehler ist aufgetreten:", - "Hide/Show the control bar": "Kontrollleiste verstecken/anzeigen", - "Move/Drag Viewport": "Ansichtsfenster verschieben/ziehen", - "viewport drag": "Ansichtsfenster ziehen", - "Active Mouse Button": "Aktive Maustaste", - "No mousebutton": "Keine Maustaste", - "Left mousebutton": "Linke Maustaste", - "Middle mousebutton": "Mittlere Maustaste", - "Right mousebutton": "Rechte Maustaste", - "Keyboard": "Tastatur", - "Show Keyboard": "Tastatur anzeigen", - "Extra keys": "Zusatztasten", - "Show Extra Keys": "Zusatztasten anzeigen", - "Ctrl": "Strg", - "Toggle Ctrl": "Strg umschalten", - "Alt": "Alt", - "Toggle Alt": "Alt umschalten", - "Send Tab": "Tab senden", - "Tab": "Tab", - "Esc": "Esc", - "Send Escape": "Escape senden", - "Ctrl+Alt+Del": "Strg+Alt+Entf", - "Send Ctrl-Alt-Del": "Strg+Alt+Entf senden", - "Shutdown/Reboot": "Herunterfahren/Neustarten", - "Shutdown/Reboot...": "Herunterfahren/Neustarten...", - "Power": "Energie", - "Shutdown": "Herunterfahren", - "Reboot": "Neustarten", - "Reset": "Zurücksetzen", - "Clipboard": "Zwischenablage", - "Clear": "Löschen", - "Fullscreen": "Vollbild", - "Settings": "Einstellungen", - "Shared Mode": "Geteilter Modus", - "View Only": "Nur betrachten", - "Clip to Window": "Auf Fenster begrenzen", - "Scaling Mode:": "Skalierungsmodus:", - "None": "Keiner", - "Local Scaling": "Lokales skalieren", - "Remote Resizing": "Serverseitiges skalieren", - "Advanced": "Erweitert", - "Repeater ID:": "Repeater ID:", - "WebSocket": "WebSocket", - "Encrypt": "Verschlüsselt", - "Host:": "Server:", - "Port:": "Port:", - "Path:": "Pfad:", - "Automatic Reconnect": "Automatisch wiederverbinden", - "Reconnect Delay (ms):": "Wiederverbindungsverzögerung (ms):", - "Logging:": "Protokollierung:", - "Disconnect": "Verbindung trennen", - "Connect": "Verbinden", - "Password:": "Passwort:", - "Cancel": "Abbrechen", - "Canvas not supported.": "Canvas nicht unterstützt." -} \ No newline at end of file diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/locale/el.json --- a/image/w/app/locale/el.json Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -{ - "Connecting...": "Συνδέεται...", - "Disconnecting...": "Aποσυνδέεται...", - "Reconnecting...": "Επανασυνδέεται...", - "Internal error": "Εσωτερικό σφάλμα", - "Must set host": "Πρέπει να οριστεί ο διακομιστής", - "Connected (encrypted) to ": "Συνδέθηκε (κρυπτογραφημένα) με το ", - "Connected (unencrypted) to ": "Συνδέθηκε (μη κρυπτογραφημένα) με το ", - "Something went wrong, connection is closed": "Κάτι πήγε στραβά, η σύνδεση διακόπηκε", - "Disconnected": "Αποσυνδέθηκε", - "New connection has been rejected with reason: ": "Η νέα σύνδεση απορρίφθηκε διότι: ", - "New connection has been rejected": "Η νέα σύνδεση απορρίφθηκε ", - "Password is required": "Απαιτείται ο κωδικός πρόσβασης", - "noVNC encountered an error:": "το noVNC αντιμετώπισε ένα σφάλμα:", - "Hide/Show the control bar": "Απόκρυψη/Εμφάνιση γραμμής ελέγχου", - "Move/Drag Viewport": "Μετακίνηση/Σύρσιμο Θεατού πεδίου", - "viewport drag": "σύρσιμο θεατού πεδίου", - "Active Mouse Button": "Ενεργό Πλήκτρο Ποντικιού", - "No mousebutton": "Χωρίς Πλήκτρο Ποντικιού", - "Left mousebutton": "Αριστερό Πλήκτρο Ποντικιού", - "Middle mousebutton": "Μεσαίο Πλήκτρο Ποντικιού", - "Right mousebutton": "Δεξί Πλήκτρο Ποντικιού", - "Keyboard": "Πληκτρολόγιο", - "Show Keyboard": "Εμφάνιση Πληκτρολογίου", - "Extra keys": "Επιπλέον πλήκτρα", - "Show Extra Keys": "Εμφάνιση Επιπλέον Πλήκτρων", - "Ctrl": "Ctrl", - "Toggle Ctrl": "Εναλλαγή Ctrl", - "Alt": "Alt", - "Toggle Alt": "Εναλλαγή Alt", - "Send Tab": "Αποστολή Tab", - "Tab": "Tab", - "Esc": "Esc", - "Send Escape": "Αποστολή Escape", - "Ctrl+Alt+Del": "Ctrl+Alt+Del", - "Send Ctrl-Alt-Del": "Αποστολή Ctrl-Alt-Del", - "Shutdown/Reboot": "Κλείσιμο/Επανεκκίνηση", - "Shutdown/Reboot...": "Κλείσιμο/Επανεκκίνηση...", - "Power": "Απενεργοποίηση", - "Shutdown": "Κλείσιμο", - "Reboot": "Επανεκκίνηση", - "Reset": "Επαναφορά", - "Clipboard": "Πρόχειρο", - "Clear": "Καθάρισμα", - "Fullscreen": "Πλήρης Οθόνη", - "Settings": "Ρυθμίσεις", - "Shared Mode": "Κοινόχρηστη Λειτουργία", - "View Only": "Μόνο Θέαση", - "Clip to Window": "Αποκοπή στο όριο του Παράθυρου", - "Scaling Mode:": "Λειτουργία Κλιμάκωσης:", - "None": "Καμία", - "Local Scaling": "Τοπική Κλιμάκωση", - "Remote Resizing": "Απομακρυσμένη Αλλαγή μεγέθους", - "Advanced": "Για προχωρημένους", - "Repeater ID:": "Repeater ID:", - "WebSocket": "WebSocket", - "Encrypt": "Κρυπτογράφηση", - "Host:": "Όνομα διακομιστή:", - "Port:": "Πόρτα διακομιστή:", - "Path:": "Διαδρομή:", - "Automatic Reconnect": "Αυτόματη επανασύνδεση", - "Reconnect Delay (ms):": "Καθυστέρηση επανασύνδεσης (ms):", - "Logging:": "Καταγραφή:", - "Disconnect": "Αποσύνδεση", - "Connect": "Σύνδεση", - "Password:": "Κωδικός Πρόσβασης:", - "Cancel": "Ακύρωση", - "Canvas not supported.": "Δεν υποστηρίζεται το στοιχείο Canvas" -} \ No newline at end of file diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/locale/es.json --- a/image/w/app/locale/es.json Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -{ - "Connecting...": "Conectando...", - "Connected (encrypted) to ": "Conectado (con encriptación) a", - "Connected (unencrypted) to ": "Conectado (sin encriptación) a", - "Disconnecting...": "Desconectando...", - "Disconnected": "Desconectado", - "Must set host": "Debes configurar el host", - "Reconnecting...": "Reconectando...", - "Password is required": "Contraseña es obligatoria", - "Disconnect timeout": "Tiempo de desconexión agotado", - "noVNC encountered an error:": "noVNC ha encontrado un error:", - "Hide/Show the control bar": "Ocultar/Mostrar la barra de control", - "Move/Drag Viewport": "Mover/Arrastrar la ventana", - "viewport drag": "Arrastrar la ventana", - "Active Mouse Button": "Botón activo del ratón", - "No mousebutton": "Ningún botón del ratón", - "Left mousebutton": "Botón izquierdo del ratón", - "Middle mousebutton": "Botón central del ratón", - "Right mousebutton": "Botón derecho del ratón", - "Keyboard": "Teclado", - "Show Keyboard": "Mostrar teclado", - "Extra keys": "Teclas adicionales", - "Show Extra Keys": "Mostrar Teclas Adicionales", - "Ctrl": "Ctrl", - "Toggle Ctrl": "Pulsar/Soltar Ctrl", - "Alt": "Alt", - "Toggle Alt": "Pulsar/Soltar Alt", - "Send Tab": "Enviar Tabulación", - "Tab": "Tabulación", - "Esc": "Esc", - "Send Escape": "Enviar Escape", - "Ctrl+Alt+Del": "Ctrl+Alt+Del", - "Send Ctrl-Alt-Del": "Enviar Ctrl+Alt+Del", - "Shutdown/Reboot": "Apagar/Reiniciar", - "Shutdown/Reboot...": "Apagar/Reiniciar...", - "Power": "Encender", - "Shutdown": "Apagar", - "Reboot": "Reiniciar", - "Reset": "Restablecer", - "Clipboard": "Portapapeles", - "Clear": "Vaciar", - "Fullscreen": "Pantalla Completa", - "Settings": "Configuraciones", - "Shared Mode": "Modo Compartido", - "View Only": "Solo visualización", - "Clip to Window": "Recortar al tamaño de la ventana", - "Scaling Mode:": "Modo de escalado:", - "None": "Ninguno", - "Local Scaling": "Escalado Local", - "Local Downscaling": "Reducción de escala local", - "Remote Resizing": "Cambio de tamaño remoto", - "Advanced": "Avanzado", - "Local Cursor": "Cursor Local", - "Repeater ID:": "ID del Repetidor", - "WebSocket": "WebSocket", - "Encrypt": "", - "Host:": "Host", - "Port:": "Puesto", - "Path:": "Ruta", - "Automatic Reconnect": "Reconexión automática", - "Reconnect Delay (ms):": "Retraso en la reconexión (ms)", - "Logging:": "Logging", - "Disconnect": "Desconectar", - "Connect": "Conectar", - "Password:": "Contraseña", - "Cancel": "Cancelar", - "Canvas not supported.": "Canvas no está soportado" -} \ No newline at end of file diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/locale/nl.json --- a/image/w/app/locale/nl.json Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -{ - "Connecting...": "Verbinden...", - "Connected (encrypted) to ": "Verbonden (versleuteld) met ", - "Connected (unencrypted) to ": "Verbonden (onversleuteld) met ", - "Disconnecting...": "Verbinding verbreken...", - "Disconnected": "Verbinding verbroken", - "Must set host": "Host moeten worden ingesteld", - "Reconnecting...": "Opnieuw verbinding maken...", - "Password is required": "Wachtwoord is vereist", - "Disconnect timeout": "Timeout tijdens verbreken van verbinding", - "noVNC encountered an error:": "noVNC heeft een fout bemerkt:", - "Hide/Show the control bar": "Verberg/Toon de bedieningsbalk", - "Move/Drag Viewport": "Verplaats/Versleep Kijkvenster", - "viewport drag": "kijkvenster slepen", - "Active Mouse Button": "Actieve Muisknop", - "No mousebutton": "Geen muisknop", - "Left mousebutton": "Linker muisknop", - "Middle mousebutton": "Middelste muisknop", - "Right mousebutton": "Rechter muisknop", - "Keyboard": "Toetsenbord", - "Show Keyboard": "Toon Toetsenbord", - "Extra keys": "Extra toetsen", - "Show Extra Keys": "Toon Extra Toetsen", - "Ctrl": "Ctrl", - "Toggle Ctrl": "Ctrl aan/uitzetten", - "Alt": "Alt", - "Toggle Alt": "Alt aan/uitzetten", - "Send Tab": "Tab Sturen", - "Tab": "Tab", - "Esc": "Esc", - "Send Escape": "Escape Sturen", - "Ctrl+Alt+Del": "Ctrl-Alt-Del", - "Send Ctrl-Alt-Del": "Ctrl-Alt-Del Sturen", - "Shutdown/Reboot": "Uitschakelen/Herstarten", - "Shutdown/Reboot...": "Uitschakelen/Herstarten...", - "Power": "Systeem", - "Shutdown": "Uitschakelen", - "Reboot": "Herstarten", - "Reset": "Resetten", - "Clipboard": "Klembord", - "Clear": "Wissen", - "Fullscreen": "Volledig Scherm", - "Settings": "Instellingen", - "Shared Mode": "Gedeelde Modus", - "View Only": "Alleen Kijken", - "Clip to Window": "Randen buiten venster afsnijden", - "Scaling Mode:": "Schaalmodus:", - "None": "Geen", - "Local Scaling": "Lokaal Schalen", - "Local Downscaling": "Lokaal Neerschalen", - "Remote Resizing": "Op Afstand Formaat Wijzigen", - "Advanced": "Geavanceerd", - "Local Cursor": "Lokale Cursor", - "Repeater ID:": "Repeater ID:", - "WebSocket": "WebSocket", - "Encrypt": "Versleutelen", - "Host:": "Host:", - "Port:": "Poort:", - "Path:": "Pad:", - "Automatic Reconnect": "Automatisch Opnieuw Verbinden", - "Reconnect Delay (ms):": "Vertraging voor Opnieuw Verbinden (ms):", - "Logging:": "Logmeldingen:", - "Disconnect": "Verbinding verbreken", - "Connect": "Verbinden", - "Password:": "Wachtwoord:", - "Cancel": "Annuleren", - "Canvas not supported.": "Canvas wordt niet ondersteund." -} \ No newline at end of file diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/locale/pl.json --- a/image/w/app/locale/pl.json Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -{ - "Connecting...": "Łączenie...", - "Disconnecting...": "Rozłączanie...", - "Reconnecting...": "Łączenie...", - "Internal error": "Błąd wewnętrzny", - "Must set host": "Host i port są wymagane", - "Connected (encrypted) to ": "Połączenie (szyfrowane) z ", - "Connected (unencrypted) to ": "Połączenie (nieszyfrowane) z ", - "Something went wrong, connection is closed": "Coś poszło źle, połączenie zostało zamknięte", - "Disconnected": "Rozłączony", - "New connection has been rejected with reason: ": "Nowe połączenie zostało odrzucone z powodu: ", - "New connection has been rejected": "Nowe połączenie zostało odrzucone", - "Password is required": "Hasło jest wymagane", - "noVNC encountered an error:": "noVNC napotkało błąd:", - "Hide/Show the control bar": "Pokaż/Ukryj pasek ustawień", - "Move/Drag Viewport": "Ruszaj/Przeciągaj Viewport", - "viewport drag": "przeciągnij viewport", - "Active Mouse Button": "Aktywny Przycisk Myszy", - "No mousebutton": "Brak przycisku myszy", - "Left mousebutton": "Lewy przycisk myszy", - "Middle mousebutton": "Środkowy przycisk myszy", - "Right mousebutton": "Prawy przycisk myszy", - "Keyboard": "Klawiatura", - "Show Keyboard": "Pokaż klawiaturę", - "Extra keys": "Przyciski dodatkowe", - "Show Extra Keys": "Pokaż przyciski dodatkowe", - "Ctrl": "Ctrl", - "Toggle Ctrl": "Przełącz Ctrl", - "Alt": "Alt", - "Toggle Alt": "Przełącz Alt", - "Send Tab": "Wyślij Tab", - "Tab": "Tab", - "Esc": "Esc", - "Send Escape": "Wyślij Escape", - "Ctrl+Alt+Del": "Ctrl+Alt+Del", - "Send Ctrl-Alt-Del": "Wyślij Ctrl-Alt-Del", - "Shutdown/Reboot": "Wyłącz/Uruchom ponownie", - "Shutdown/Reboot...": "Wyłącz/Uruchom ponownie...", - "Power": "Włączony", - "Shutdown": "Wyłącz", - "Reboot": "Uruchom ponownie", - "Reset": "Resetuj", - "Clipboard": "Schowek", - "Clear": "Wyczyść", - "Fullscreen": "Pełny ekran", - "Settings": "Ustawienia", - "Shared Mode": "Tryb Współdzielenia", - "View Only": "Tylko Podgląd", - "Clip to Window": "Przytnij do Okna", - "Scaling Mode:": "Tryb Skalowania:", - "None": "Brak", - "Local Scaling": "Skalowanie lokalne", - "Remote Resizing": "Skalowanie zdalne", - "Advanced": "Zaawansowane", - "Repeater ID:": "ID Repeatera:", - "WebSocket": "WebSocket", - "Encrypt": "Szyfrowanie", - "Host:": "Host:", - "Port:": "Port:", - "Path:": "Ścieżka:", - "Automatic Reconnect": "Automatycznie wznawiaj połączenie", - "Reconnect Delay (ms):": "Opóźnienie wznawiania (ms):", - "Logging:": "Poziom logowania:", - "Disconnect": "Rozłącz", - "Connect": "Połącz", - "Password:": "Hasło:", - "Cancel": "Anuluj", - "Canvas not supported.": "Element Canvas nie jest wspierany." -} \ No newline at end of file diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/locale/sv.json --- a/image/w/app/locale/sv.json Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -{ - "Connecting...": "Ansluter...", - "Connected (encrypted) to ": "Ansluten (krypterat) till ", - "Connected (unencrypted) to ": "Ansluten (okrypterat) till ", - "Disconnecting...": "Kopplar ner...", - "Disconnected": "Frånkopplad", - "Must set host": "Du måste specifiera en värd", - "Reconnecting...": "Återansluter...", - "Password is required": "Lösenord krävs", - "Disconnect timeout": "Det tog för lång tid att koppla ner", - "noVNC encountered an error:": "noVNC stötte på ett problem:", - "Hide/Show the control bar": "Göm/Visa kontrollbaren", - "Move/Drag Viewport": "Flytta/Dra Vyn", - "viewport drag": "dra vy", - "Active Mouse Button": "Aktiv musknapp", - "No mousebutton": "Ingen musknapp", - "Left mousebutton": "Vänster musknapp", - "Middle mousebutton": "Mitten-musknapp", - "Right mousebutton": "Höger musknapp", - "Keyboard": "Tangentbord", - "Show Keyboard": "Visa Tangentbord", - "Extra keys": "Extraknappar", - "Show Extra Keys": "Visa Extraknappar", - "Ctrl": "Ctrl", - "Toggle Ctrl": "Växla Ctrl", - "Alt": "Alt", - "Toggle Alt": "Växla Alt", - "Send Tab": "Skicka Tab", - "Tab": "Tab", - "Esc": "Esc", - "Send Escape": "Skicka Escape", - "Ctrl+Alt+Del": "Ctrl+Alt+Del", - "Send Ctrl-Alt-Del": "Skicka Ctrl-Alt-Del", - "Shutdown/Reboot": "Stäng av/Boota om", - "Shutdown/Reboot...": "Stäng av/Boota om...", - "Power": "Ström", - "Shutdown": "Stäng av", - "Reboot": "Boota om", - "Reset": "Återställ", - "Clipboard": "Urklipp", - "Clear": "Rensa", - "Fullscreen": "Fullskärm", - "Settings": "Inställningar", - "Shared Mode": "Delat Läge", - "View Only": "Endast Visning", - "Clip to Window": "Begränsa till Fönster", - "Scaling Mode:": "Skalningsläge:", - "None": "Ingen", - "Local Scaling": "Lokal Skalning", - "Local Downscaling": "Lokal Nedskalning", - "Remote Resizing": "Ändra Storlek", - "Advanced": "Avancerat", - "Local Cursor": "Lokal Muspekare", - "Repeater ID:": "Repeater-ID:", - "WebSocket": "WebSocket", - "Encrypt": "Kryptera", - "Host:": "Värd:", - "Port:": "Port:", - "Path:": "Sökväg:", - "Automatic Reconnect": "Automatisk Återanslutning", - "Reconnect Delay (ms):": "Fördröjning (ms):", - "Logging:": "Loggning:", - "Disconnect": "Koppla från", - "Connect": "Anslut", - "Password:": "Lösenord:", - "Cancel": "Avbryt", - "Canvas not supported.": "Canvas stöds ej" -} \ No newline at end of file diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/locale/tr.json --- a/image/w/app/locale/tr.json Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -{ - "Connecting...": "Bağlanıyor...", - "Disconnecting...": "Bağlantı kesiliyor...", - "Reconnecting...": "Yeniden bağlantı kuruluyor...", - "Internal error": "İç hata", - "Must set host": "Sunucuyu kur", - "Connected (encrypted) to ": "Bağlı (şifrelenmiş)", - "Connected (unencrypted) to ": "Bağlandı (şifrelenmemiş)", - "Something went wrong, connection is closed": "Bir şeyler ters gitti, bağlantı kesildi", - "Disconnected": "Bağlantı kesildi", - "New connection has been rejected with reason: ": "Bağlantı aşağıdaki nedenlerden dolayı reddedildi: ", - "New connection has been rejected": "Bağlantı reddedildi", - "Password is required": "Şifre gerekli", - "noVNC encountered an error:": "Bir hata oluştu:", - "Hide/Show the control bar": "Denetim masasını Gizle/Göster", - "Move/Drag Viewport": "Görünümü Taşı/Sürükle", - "viewport drag": "Görüntü penceresini sürükle", - "Active Mouse Button": "Aktif Fare Düğmesi", - "No mousebutton": "Fare düğmesi yok", - "Left mousebutton": "Farenin sol düğmesi", - "Middle mousebutton": "Farenin orta düğmesi", - "Right mousebutton": "Farenin sağ düğmesi", - "Keyboard": "Klavye", - "Show Keyboard": "Klavye Düzenini Göster", - "Extra keys": "Ekstra tuşlar", - "Show Extra Keys": "Ekstra tuşları göster", - "Ctrl": "Ctrl", - "Toggle Ctrl": "Ctrl Değiştir ", - "Alt": "Alt", - "Toggle Alt": "Alt Değiştir", - "Send Tab": "Sekme Gönder", - "Tab": "Sekme", - "Esc": "Esc", - "Send Escape": "Boşluk Gönder", - "Ctrl+Alt+Del": "Ctrl + Alt + Del", - "Send Ctrl-Alt-Del": "Ctrl-Alt-Del Gönder", - "Shutdown/Reboot": "Kapat/Yeniden Başlat", - "Shutdown/Reboot...": "Kapat/Yeniden Başlat...", - "Power": "Güç", - "Shutdown": "Kapat", - "Reboot": "Yeniden Başlat", - "Reset": "Sıfırla", - "Clipboard": "Pano", - "Clear": "Temizle", - "Fullscreen": "Tam Ekran", - "Settings": "Ayarlar", - "Shared Mode": "Paylaşım Modu", - "View Only": "Sadece Görüntüle", - "Clip to Window": "Pencereye Tıkla", - "Scaling Mode:": "Ölçekleme Modu:", - "None": "Bilinmeyen", - "Local Scaling": "Yerel Ölçeklendirme", - "Remote Resizing": "Uzaktan Yeniden Boyutlandırma", - "Advanced": "Gelişmiş", - "Repeater ID:": "Tekralayıcı ID:", - "WebSocket": "WebSocket", - "Encrypt": "Şifrele", - "Host:": "Ana makine:", - "Port:": "Port:", - "Path:": "Yol:", - "Automatic Reconnect": "Otomatik Yeniden Bağlan", - "Reconnect Delay (ms):": "Yeniden Bağlanma Süreci (ms):", - "Logging:": "Giriş yapılıyor:", - "Disconnect": "Bağlantıyı Kes", - "Connect": "Bağlan", - "Password:": "Parola:", - "Cancel": "Vazgeç", - "Canvas not supported.": "Tuval desteklenmiyor." -} \ No newline at end of file diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/locale/zh.json --- a/image/w/app/locale/zh.json Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -{ - "Connecting...": "連線中...", - "Disconnecting...": "正在中斷連線...", - "Reconnecting...": "重新連線中...", - "Internal error": "內部錯誤", - "Must set host": "請提供主機資訊", - "Connected (encrypted) to ": "已加密連線到", - "Connected (unencrypted) to ": "未加密連線到", - "Something went wrong, connection is closed": "發生錯誤,連線已關閉", - "Failed to connect to server": "無法連線到伺服器", - "Disconnected": "連線已中斷", - "New connection has been rejected with reason: ": "連線被拒絕,原因:", - "New connection has been rejected": "連線被拒絕", - "Password is required": "請提供密碼", - "noVNC encountered an error:": "noVNC 遇到一個錯誤:", - "Hide/Show the control bar": "顯示/隱藏控制列", - "Move/Drag Viewport": "拖放顯示範圍", - "viewport drag": "顯示範圍拖放", - "Active Mouse Button": "啟用滑鼠按鍵", - "No mousebutton": "無滑鼠按鍵", - "Left mousebutton": "滑鼠左鍵", - "Middle mousebutton": "滑鼠中鍵", - "Right mousebutton": "滑鼠右鍵", - "Keyboard": "鍵盤", - "Show Keyboard": "顯示鍵盤", - "Extra keys": "額外按鍵", - "Show Extra Keys": "顯示額外按鍵", - "Ctrl": "Ctrl", - "Toggle Ctrl": "切換 Ctrl", - "Alt": "Alt", - "Toggle Alt": "切換 Alt", - "Send Tab": "送出 Tab 鍵", - "Tab": "Tab", - "Esc": "Esc", - "Send Escape": "送出 Escape 鍵", - "Ctrl+Alt+Del": "Ctrl-Alt-Del", - "Send Ctrl-Alt-Del": "送出 Ctrl-Alt-Del 快捷鍵", - "Shutdown/Reboot": "關機/重新啟動", - "Shutdown/Reboot...": "關機/重新啟動...", - "Power": "電源", - "Shutdown": "關機", - "Reboot": "重新啟動", - "Reset": "重設", - "Clipboard": "剪貼簿", - "Clear": "清除", - "Fullscreen": "全螢幕", - "Settings": "設定", - "Shared Mode": "分享模式", - "View Only": "僅檢視", - "Clip to Window": "限制/裁切視窗大小", - "Scaling Mode:": "縮放模式:", - "None": "無", - "Local Scaling": "本機縮放", - "Remote Resizing": "遠端調整大小", - "Advanced": "進階", - "Repeater ID:": "中繼站 ID", - "WebSocket": "WebSocket", - "Encrypt": "加密", - "Host:": "主機:", - "Port:": "連接埠:", - "Path:": "路徑:", - "Automatic Reconnect": "自動重新連線", - "Reconnect Delay (ms):": "重新連線間隔 (ms):", - "Logging:": "日誌級別:", - "Disconnect": "中斷連線", - "Connect": "連線", - "Password:": "密碼:", - "Cancel": "取消" -} \ No newline at end of file diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/localization.js.gz Binary file image/w/app/localization.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/sounds/bell.mp3 Binary file image/w/app/sounds/bell.mp3 has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/sounds/bell.oga Binary file image/w/app/sounds/bell.oga has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/styles/base.css --- a/image/w/app/styles/base.css Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,893 +0,0 @@ -/* - * noVNC base CSS - * Copyright (C) 2012 Joel Martin - * Copyright (C) 2016 Samuel Mannehed for Cendio AB - * Copyright (C) 2016 Pierre Ossman for Cendio AB - * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) - * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). - */ - -/* - * Z index layers: - * - * 0: Main screen - * 10: Control bar - * 50: Transition blocker - * 60: Connection popups - * 100: Status bar - * ... - * 1000: Javascript crash - * ... - * 10000: Max (used for polyfills) - */ - -body { - margin:0; - padding:0; - font-family: Helvetica; - /*Background image with light grey curve.*/ - background-color:#494949; - background-repeat:no-repeat; - background-position:right bottom; - height:100%; - touch-action: none; -} - -html { - height:100%; -} - -.noVNC_only_touch.noVNC_hidden { - display: none; -} - -.noVNC_disabled { - color: rgb(128, 128, 128); -} - -/* ---------------------------------------- - * Spinner - * ---------------------------------------- - */ - -.noVNC_spinner { - position: relative; -} -.noVNC_spinner, .noVNC_spinner::before, .noVNC_spinner::after { - width: 10px; - height: 10px; - border-radius: 2px; - box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); - animation: noVNC_spinner 1.0s linear infinite; -} -.noVNC_spinner::before { - content: ""; - position: absolute; - left: 0px; - top: 0px; - animation-delay: -0.1s; -} -.noVNC_spinner::after { - content: ""; - position: absolute; - top: 0px; - left: 0px; - animation-delay: 0.1s; -} -@keyframes noVNC_spinner { - 0% { box-shadow: -60px 10px 0 rgba(255, 255, 255, 0); width: 20px; } - 25% { box-shadow: 20px 10px 0 rgba(255, 255, 255, 1); width: 10px; } - 50% { box-shadow: 60px 10px 0 rgba(255, 255, 255, 0); width: 10px; } -} - -/* ---------------------------------------- - * Input Elements - * ---------------------------------------- - */ - -input[type=input], input[type=password], input[type=number], -input:not([type]), textarea { - /* Disable default rendering */ - -webkit-appearance: none; - -moz-appearance: none; - background: none; - - margin: 2px; - padding: 2px; - border: 1px solid rgb(192, 192, 192); - border-radius: 5px; - color: black; - background: linear-gradient(to top, rgb(255, 255, 255) 80%, rgb(240, 240, 240)); -} - -input[type=button], input[type=submit], select { - /* Disable default rendering */ - -webkit-appearance: none; - -moz-appearance: none; - background: none; - - margin: 2px; - padding: 2px; - border: 1px solid rgb(192, 192, 192); - border-bottom-width: 2px; - border-radius: 5px; - color: black; - background: linear-gradient(to top, rgb(255, 255, 255), rgb(240, 240, 240)); - - /* This avoids it jumping around when :active */ - vertical-align: middle; -} - -input[type=button], input[type=submit] { - padding-left: 20px; - padding-right: 20px; -} - -option { - color: black; - background: white; -} - -input[type=input]:focus, input[type=password]:focus, -input:not([type]):focus, input[type=button]:focus, -input[type=submit]:focus, -textarea:focus, select:focus { - box-shadow: 0px 0px 3px rgba(74, 144, 217, 0.5); - border-color: rgb(74, 144, 217); - outline: none; -} - -input[type=button]::-moz-focus-inner, -input[type=submit]::-moz-focus-inner { - border: none; -} - -input[type=input]:disabled, input[type=password]:disabled, -input:not([type]):disabled, input[type=button]:disabled, -input[type=submit]:disabled, input[type=number]:disabled, -textarea:disabled, select:disabled { - color: rgb(128, 128, 128); - background: rgb(240, 240, 240); -} - -input[type=button]:active, input[type=submit]:active, -select:active { - border-bottom-width: 1px; - margin-top: 3px; -} - -:root:not(.noVNC_touch) input[type=button]:hover:not(:disabled), -:root:not(.noVNC_touch) input[type=submit]:hover:not(:disabled), -:root:not(.noVNC_touch) select:hover:not(:disabled) { - background: linear-gradient(to top, rgb(255, 255, 255), rgb(250, 250, 250)); -} - -/* ---------------------------------------- - * WebKit centering hacks - * ---------------------------------------- - */ - -.noVNC_center { - /* - * This is a workaround because webkit misrenders transforms and - * uses non-integer coordinates, resulting in blurry content. - * Ideally we'd use "top: 50%; transform: translateY(-50%);" on - * the objects instead. - */ - display: flex; - align-items: center; - justify-content: center; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; -} -.noVNC_center > * { - pointer-events: auto; -} -.noVNC_vcenter { - display: flex; - flex-direction: column; - justify-content: center; - position: fixed; - top: 0; - left: 0; - height: 100%; - pointer-events: none; -} -.noVNC_vcenter > * { - pointer-events: auto; -} - -/* ---------------------------------------- - * Layering - * ---------------------------------------- - */ - -.noVNC_connect_layer { - z-index: 60; -} - -/* ---------------------------------------- - * Fallback error - * ---------------------------------------- - */ - -#noVNC_fallback_error { - z-index: 1000; - visibility: hidden; -} -#noVNC_fallback_error.noVNC_open { - visibility: visible; -} - -#noVNC_fallback_error > div { - max-width: 90%; - padding: 15px; - - transition: 0.5s ease-in-out; - - transform: translateY(-50px); - opacity: 0; - - text-align: center; - font-weight: bold; - color: #fff; - - border-radius: 10px; - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); - background: rgba(200,55,55,0.8); -} -#noVNC_fallback_error.noVNC_open > div { - transform: translateY(0); - opacity: 1; -} - -#noVNC_fallback_errormsg { - font-weight: normal; -} - -#noVNC_fallback_errormsg .noVNC_message { - display: inline-block; - text-align: left; - font-family: monospace; - white-space: pre-wrap; -} - -#noVNC_fallback_error .noVNC_location { - font-style: italic; - font-size: 0.8em; - color: rgba(255, 255, 255, 0.8); -} - -#noVNC_fallback_error .noVNC_stack { - max-height: 50vh; - padding: 10px; - margin: 10px; - font-size: 0.8em; - text-align: left; - font-family: monospace; - white-space: pre; - border: 1px solid rgba(0, 0, 0, 0.5); - background: rgba(0, 0, 0, 0.2); - overflow: auto; -} - -/* ---------------------------------------- - * Control Bar - * ---------------------------------------- - */ - -#noVNC_control_bar_anchor { - /* The anchor is needed to get z-stacking to work */ - position: fixed; - z-index: 10; - - transition: 0.5s ease-in-out; - - /* Edge misrenders animations wihthout this */ - transform: translateX(0); -} -:root.noVNC_connected #noVNC_control_bar_anchor.noVNC_idle { - opacity: 0.8; -} -#noVNC_control_bar_anchor.noVNC_right { - left: auto; - right: 0; -} - -#noVNC_control_bar { - position: relative; - left: -100%; - - transition: 0.5s ease-in-out; - - background-color: rgb(110, 132, 163); - border-radius: 0 10px 10px 0; - -} -#noVNC_control_bar.noVNC_open { - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); - left: 0; -} -#noVNC_control_bar::before { - /* This extra element is to get a proper shadow */ - content: ""; - position: absolute; - z-index: -1; - height: 100%; - width: 30px; - left: -30px; - transition: box-shadow 0.5s ease-in-out; -} -#noVNC_control_bar.noVNC_open::before { - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); -} -.noVNC_right #noVNC_control_bar { - left: 100%; - border-radius: 10px 0 0 10px; -} -.noVNC_right #noVNC_control_bar.noVNC_open { - left: 0; -} -.noVNC_right #noVNC_control_bar::before { - visibility: hidden; -} - -#noVNC_control_bar_handle { - position: absolute; - left: -15px; - top: 0; - transform: translateY(35px); - width: calc(100% + 30px); - height: 50px; - z-index: -1; - cursor: pointer; - border-radius: 5px; - background-color: rgb(83, 99, 122); - background-image: url("../images/handle_bg.svg"); - background-repeat: no-repeat; - background-position: right; - box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.5); -} -#noVNC_control_bar_handle:after { - content: ""; - transition: transform 0.5s ease-in-out; - background: url("../images/handle.svg"); - position: absolute; - top: 22px; /* (50px-6px)/2 */ - right: 5px; - width: 5px; - height: 6px; -} -#noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after { - transform: translateX(1px) rotate(180deg); -} -:root:not(.noVNC_connected) #noVNC_control_bar_handle { - display: none; -} -.noVNC_right #noVNC_control_bar_handle { - background-position: left; -} -.noVNC_right #noVNC_control_bar_handle:after { - left: 5px; - right: 0; - transform: translateX(1px) rotate(180deg); -} -.noVNC_right #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after { - transform: none; -} -#noVNC_control_bar_handle div { - position: absolute; - right: -35px; - top: 0; - width: 50px; - height: 50px; -} -:root:not(.noVNC_touch) #noVNC_control_bar_handle div { - display: none; -} -.noVNC_right #noVNC_control_bar_handle div { - left: -35px; - right: auto; -} - -#noVNC_control_bar .noVNC_scroll { - max-height: 100vh; /* Chrome is buggy with 100% */ - overflow-x: hidden; - overflow-y: auto; - padding: 0 10px 0 5px; -} -.noVNC_right #noVNC_control_bar .noVNC_scroll { - padding: 0 5px 0 10px; -} - -/* Control bar hint */ -#noVNC_control_bar_hint { - position: fixed; - left: calc(100vw - 50px); - right: auto; - top: 50%; - transform: translateY(-50%) scale(0); - width: 100px; - height: 50%; - max-height: 600px; - - visibility: hidden; - opacity: 0; - transition: 0.2s ease-in-out; - background: transparent; - box-shadow: 0 0 10px black, inset 0 0 10px 10px rgba(110, 132, 163, 0.8); - border-radius: 10px; - transition-delay: 0s; -} -#noVNC_control_bar_anchor.noVNC_right #noVNC_control_bar_hint{ - left: auto; - right: calc(100vw - 50px); -} -#noVNC_control_bar_hint.noVNC_active { - visibility: visible; - opacity: 1; - transition-delay: 0.2s; - transform: translateY(-50%) scale(1); -} - -/* General button style */ -.noVNC_button { - display: block; - padding: 4px 4px; - margin: 10px 0; - vertical-align: middle; - border:1px solid rgba(255, 255, 255, 0.2); - border-radius: 6px; -} -.noVNC_button.noVNC_selected { - border-color: rgba(0, 0, 0, 0.8); - background: rgba(0, 0, 0, 0.5); -} -.noVNC_button:disabled { - opacity: 0.4; -} -.noVNC_button:focus { - outline: none; -} -.noVNC_button:active { - padding-top: 5px; - padding-bottom: 3px; -} -/* Android browsers don't properly update hover state if touch events - * are intercepted, but focus should be safe to display */ -:root:not(.noVNC_touch) .noVNC_button.noVNC_selected:hover, -.noVNC_button.noVNC_selected:focus { - border-color: rgba(0, 0, 0, 0.4); - background: rgba(0, 0, 0, 0.2); -} -:root:not(.noVNC_touch) .noVNC_button:hover, -.noVNC_button:focus { - background: rgba(255, 255, 255, 0.2); -} -.noVNC_button.noVNC_hidden { - display: none; -} - -/* Panels */ -.noVNC_panel { - transform: translateX(25px); - - transition: 0.5s ease-in-out; - - max-height: 100vh; /* Chrome is buggy with 100% */ - overflow-x: hidden; - overflow-y: auto; - - visibility: hidden; - opacity: 0; - - padding: 15px; - - background: #fff; - border-radius: 10px; - color: #000; - border: 2px solid #E0E0E0; - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); -} -.noVNC_panel.noVNC_open { - visibility: visible; - opacity: 1; - transform: translateX(75px); -} -.noVNC_right .noVNC_vcenter { - left: auto; - right: 0; -} -.noVNC_right .noVNC_panel { - transform: translateX(-25px); -} -.noVNC_right .noVNC_panel.noVNC_open { - transform: translateX(-75px); -} - -.noVNC_panel hr { - border: none; - border-top: 1px solid rgb(192, 192, 192); -} - -.noVNC_panel label { - display: block; - white-space: nowrap; -} - -.noVNC_panel .noVNC_heading { - background-color: rgb(110, 132, 163); - border-radius: 5px; - padding: 5px; - /* Compensate for padding in image */ - padding-right: 8px; - color: white; - font-size: 20px; - margin-bottom: 10px; - white-space: nowrap; -} -.noVNC_panel .noVNC_heading img { - vertical-align: bottom; -} - -.noVNC_submit { - float: right; -} - -/* Expanders */ -.noVNC_expander { - cursor: pointer; -} -.noVNC_expander::before { - content: url("../images/expander.svg"); - display: inline-block; - margin-right: 5px; - transition: 0.2s ease-in-out; -} -.noVNC_expander.noVNC_open::before { - transform: rotateZ(90deg); -} -.noVNC_expander ~ * { - margin: 5px; - margin-left: 10px; - padding: 5px; - background: rgba(0, 0, 0, 0.05); - border-radius: 5px; -} -.noVNC_expander:not(.noVNC_open) ~ * { - display: none; -} - -/* Control bar content */ - -#noVNC_control_bar .noVNC_logo { - font-size: 13px; -} - -:root:not(.noVNC_connected) #noVNC_view_drag_button { - display: none; -} - -/* noVNC Touch Device only buttons */ -:root:not(.noVNC_connected) #noVNC_mobile_buttons { - display: none; -} -:root:not(.noVNC_touch) #noVNC_mobile_buttons { - display: none; -} - -/* Extra manual keys */ -:root:not(.noVNC_connected) #noVNC_extra_keys { - display: none; -} - -#noVNC_modifiers { - background-color: rgb(92, 92, 92); - border: none; - padding: 0 10px; -} - -/* Shutdown/Reboot */ -:root:not(.noVNC_connected) #noVNC_power_button { - display: none; -} -#noVNC_power { -} -#noVNC_power_buttons { - display: none; -} - -#noVNC_power input[type=button] { - width: 100%; -} - -/* Clipboard */ -:root:not(.noVNC_connected) #noVNC_clipboard_button { - display: none; -} -#noVNC_clipboard { - /* Full screen, minus padding and left and right margins */ - max-width: calc(100vw - 2*15px - 75px - 25px); -} -#noVNC_clipboard_text { - width: 500px; - max-width: 100%; -} - -/* Settings */ -#noVNC_settings { -} -#noVNC_settings ul { - list-style: none; - margin: 0px; - padding: 0px; -} -#noVNC_setting_port { - width: 80px; -} -#noVNC_setting_path { - width: 100px; -} - -/* Connection Controls */ -:root:not(.noVNC_connected) #noVNC_disconnect_button { - display: none; -} - -/* ---------------------------------------- - * Status Dialog - * ---------------------------------------- - */ - -#noVNC_status { - position: fixed; - top: 0; - left: 0; - width: 100%; - z-index: 100; - transform: translateY(-100%); - - cursor: pointer; - - transition: 0.5s ease-in-out; - - visibility: hidden; - opacity: 0; - - padding: 5px; - - display: flex; - flex-direction: row; - justify-content: center; - align-content: center; - - line-height: 25px; - word-wrap: break-word; - color: #fff; - - border-bottom: 1px solid rgba(0, 0, 0, 0.9); -} -#noVNC_status.noVNC_open { - transform: translateY(0); - visibility: visible; - opacity: 1; -} - -#noVNC_status::before { - content: ""; - display: inline-block; - width: 25px; - height: 25px; - margin-right: 5px; -} - -#noVNC_status.noVNC_status_normal { - background: rgba(128,128,128,0.9); -} -#noVNC_status.noVNC_status_normal::before { - content: url("../images/info.svg") " "; -} -#noVNC_status.noVNC_status_error { - background: rgba(200,55,55,0.9); -} -#noVNC_status.noVNC_status_error::before { - content: url("../images/error.svg") " "; -} -#noVNC_status.noVNC_status_warn { - background: rgba(180,180,30,0.9); -} -#noVNC_status.noVNC_status_warn::before { - content: url("../images/warning.svg") " "; -} - -/* ---------------------------------------- - * Connect Dialog - * ---------------------------------------- - */ - -#noVNC_connect_dlg { - transition: 0.5s ease-in-out; - - transform: scale(0, 0); - visibility: hidden; - opacity: 0; -} -#noVNC_connect_dlg.noVNC_open { - transform: scale(1, 1); - visibility: visible; - opacity: 1; -} -#noVNC_connect_dlg .noVNC_logo { - transition: 0.5s ease-in-out; - padding: 10px; - margin-bottom: 10px; - - font-size: 80px; - text-align: center; - - border-radius: 5px; -} -@media (max-width: 440px) { - #noVNC_connect_dlg { - max-width: calc(100vw - 100px); - } - #noVNC_connect_dlg .noVNC_logo { - font-size: calc(25vw - 30px); - } -} -#noVNC_connect_button { - cursor: pointer; - - padding: 10px; - - color: white; - background-color: rgb(110, 132, 163); - border-radius: 12px; - - text-align: center; - font-size: 20px; - - box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.5); -} -#noVNC_connect_button div { - margin: 2px; - padding: 5px 30px; - border: 1px solid rgb(83, 99, 122); - border-bottom-width: 2px; - border-radius: 5px; - background: linear-gradient(to top, rgb(110, 132, 163), rgb(99, 119, 147)); - - /* This avoids it jumping around when :active */ - vertical-align: middle; -} -#noVNC_connect_button div:active { - border-bottom-width: 1px; - margin-top: 3px; -} -:root:not(.noVNC_touch) #noVNC_connect_button div:hover { - background: linear-gradient(to top, rgb(110, 132, 163), rgb(105, 125, 155)); -} - -#noVNC_connect_button img { - vertical-align: bottom; - height: 1.3em; -} - -/* ---------------------------------------- - * Password Dialog - * ---------------------------------------- - */ - -#noVNC_password_dlg { - position: relative; - - transform: translateY(-50px); -} -#noVNC_password_dlg.noVNC_open { - transform: translateY(0); -} -#noVNC_password_dlg ul { - list-style: none; - margin: 0px; - padding: 0px; -} - -/* ---------------------------------------- - * Main Area - * ---------------------------------------- - */ - -/* Transition screen */ -#noVNC_transition { - display: none; - - position: fixed; - top: 0; - left: 0; - bottom: 0; - right: 0; - - color: white; - background: rgba(0, 0, 0, 0.5); - z-index: 50; - - /*display: flex;*/ - align-items: center; - justify-content: center; - flex-direction: column; -} -:root.noVNC_loading #noVNC_transition, -:root.noVNC_connecting #noVNC_transition, -:root.noVNC_disconnecting #noVNC_transition, -:root.noVNC_reconnecting #noVNC_transition { - display: flex; -} -:root:not(.noVNC_reconnecting) #noVNC_cancel_reconnect_button { - display: none; -} -#noVNC_transition_text { - font-size: 1.5em; -} - -/* Main container */ -#noVNC_container { - width: 100%; - height: 100%; - background-color: #313131; - border-bottom-right-radius: 800px 600px; - /*border-top-left-radius: 800px 600px;*/ -} - -#noVNC_keyboardinput { - width: 1px; - height: 1px; - background-color: #fff; - color: #fff; - border: 0; - position: absolute; - left: -40px; - z-index: -1; - ime-mode: disabled; -} - -/*Default noVNC logo.*/ -.noVNC_logo { - color:yellow; - font-family: sans-serif; - line-height:90%; - text-shadow: 0.1em 0.1em 0 black; -} -.noVNC_logo span{ - color:green; -} - -#noVNC_bell { - display: none; -} - -/* ---------------------------------------- - * Media sizing - * ---------------------------------------- - */ - -@media screen and (max-width: 640px){ - #noVNC_logo { - font-size: 150px; - } -} - -@media screen and (min-width: 321px) and (max-width: 480px) { - #noVNC_logo { - font-size: 110px; - } -} - -@media screen and (max-width: 320px) { - #noVNC_logo { - font-size: 90px; - } -} diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/ui.js.gz Binary file image/w/app/ui.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/app/webutil.js.gz Binary file image/w/app/webutil.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/base64.js.gz Binary file image/w/core/base64.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/des.js.gz Binary file image/w/core/des.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/display.js.gz Binary file image/w/core/display.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/encodings.js.gz Binary file image/w/core/encodings.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/inflator.js.gz Binary file image/w/core/inflator.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/input/mouse.js.gz Binary file image/w/core/input/mouse.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/rfb.js.gz Binary file image/w/core/rfb.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/rfb.js.orig --- a/image/w/core/rfb.js.orig Thu May 02 11:57:07 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2554 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2012 Joel Martin - * Copyright (C) 2017 Samuel Mannehed for Cendio AB - * Licensed under MPL 2.0 (see LICENSE.txt) - * - * See README.md for usage and integration instructions. - * - * TIGHT decoder portion: - * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) - */ - -import * as Log from './util/logging.js'; -import { decodeUTF8 } from './util/strings.js'; -import { supportsCursorURIs, isTouchDevice } from './util/browser.js'; -import EventTargetMixin from './util/eventtarget.js'; -import Display from "./display.js"; -import Keyboard from "./input/keyboard.js"; -import Mouse from "./input/mouse.js"; -import Websock from "./websock.js"; -import DES from "./des.js"; -import KeyTable from "./input/keysym.js"; -import XtScancode from "./input/xtscancodes.js"; -import Inflator from "./inflator.js"; -import { encodings, encodingName } from "./encodings.js"; -import "./util/polyfill.js"; - -/*jslint white: false, browser: true */ -/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */ - -// How many seconds to wait for a disconnect to finish -var DISCONNECT_TIMEOUT = 3; - -export default function RFB(target, url, options) { - if (!target) { - throw Error("Must specify target"); - } - if (!url) { - throw Error("Must specify URL"); - } - - this._target = target; - this._url = url; - - // Connection details - options = options || {}; - this._rfb_credentials = options.credentials || {}; - this._shared = 'shared' in options ? !!options.shared : true; - this._repeaterID = options.repeaterID || ''; - - // Internal state - this._rfb_connection_state = ''; - this._rfb_init_state = ''; - this._rfb_auth_scheme = ''; - this._rfb_clean_disconnect = true; - - // Server capabilities - this._rfb_version = 0; - this._rfb_max_version = 3.8; - this._rfb_tightvnc = false; - this._rfb_xvp_ver = 0; - - this._fb_width = 0; - this._fb_height = 0; - - this._fb_name = ""; - - this._capabilities = { power: false }; - - this._supportsFence = false; - - this._supportsContinuousUpdates = false; - this._enabledContinuousUpdates = false; - - this._supportsSetDesktopSize = false; - this._screen_id = 0; - this._screen_flags = 0; - - this._qemuExtKeyEventSupported = false; - - // Internal objects - this._sock = null; // Websock object - this._display = null; // Display object - this._flushing = false; // Display flushing state - this._keyboard = null; // Keyboard input handler object - this._mouse = null; // Mouse input handler object - - // Timers - this._disconnTimer = null; // disconnection timer - this._resizeTimeout = null; // resize rate limiting - - // Decoder states and stats - this._encHandlers = {}; - this._encStats = {}; - - this._FBU = { - rects: 0, - subrects: 0, // RRE and HEXTILE - lines: 0, // RAW - tiles: 0, // HEXTILE - bytes: 0, - x: 0, - y: 0, - width: 0, - height: 0, - encoding: 0, - subencoding: -1, - background: null, - zlibs: [] // TIGHT zlib streams - }; - for (var i = 0; i < 4; i++) { - this._FBU.zlibs[i] = new Inflator(); - } - - this._destBuff = null; - this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel) - - this._rre_chunk_sz = 100; - - this._timing = { - last_fbu: 0, - fbu_total: 0, - fbu_total_cnt: 0, - full_fbu_total: 0, - full_fbu_cnt: 0, - - fbu_rt_start: 0, - fbu_rt_total: 0, - fbu_rt_cnt: 0, - pixels: 0 - }; - - // Mouse state - this._mouse_buttonMask = 0; - this._mouse_arr = []; - this._viewportDragging = false; - this._viewportDragPos = {}; - this._viewportHasMoved = false; - - // Bound event handlers - this._eventHandlers = { - focusCanvas: this._focusCanvas.bind(this), - windowResize: this._windowResize.bind(this), - }; - - // main setup - Log.Debug(">> RFB.constructor"); - - // Create DOM elements - this._screen = document.createElement('div'); - this._screen.style.display = 'flex'; - this._screen.style.width = '100%'; - this._screen.style.height = '100%'; - this._screen.style.overflow = 'auto'; - this._screen.style.backgroundColor = 'rgb(40, 40, 40)'; - this._canvas = document.createElement('canvas'); - this._canvas.style.margin = 'auto'; - // Some browsers add an outline on focus - this._canvas.style.outline = 'none'; - // IE miscalculates width without this :( - this._canvas.style.flexShrink = '0'; - this._canvas.width = 0; - this._canvas.height = 0; - this._canvas.tabIndex = -1; - this._screen.appendChild(this._canvas); - - // populate encHandlers with bound versions - this._encHandlers[encodings.encodingRaw] = RFB.encodingHandlers.RAW.bind(this); - this._encHandlers[encodings.encodingCopyRect] = RFB.encodingHandlers.COPYRECT.bind(this); - this._encHandlers[encodings.encodingRRE] = RFB.encodingHandlers.RRE.bind(this); - this._encHandlers[encodings.encodingHextile] = RFB.encodingHandlers.HEXTILE.bind(this); - this._encHandlers[encodings.encodingTight] = RFB.encodingHandlers.TIGHT.bind(this); - - this._encHandlers[encodings.pseudoEncodingDesktopSize] = RFB.encodingHandlers.DesktopSize.bind(this); - this._encHandlers[encodings.pseudoEncodingLastRect] = RFB.encodingHandlers.last_rect.bind(this); - this._encHandlers[encodings.pseudoEncodingCursor] = RFB.encodingHandlers.Cursor.bind(this); - this._encHandlers[encodings.pseudoEncodingQEMUExtendedKeyEvent] = RFB.encodingHandlers.QEMUExtendedKeyEvent.bind(this); - this._encHandlers[encodings.pseudoEncodingExtendedDesktopSize] = RFB.encodingHandlers.ExtendedDesktopSize.bind(this); - - // NB: nothing that needs explicit teardown should be done - // before this point, since this can throw an exception - try { - this._display = new Display(this._canvas); - } catch (exc) { - Log.Error("Display exception: " + exc); - throw exc; - } - this._display.onflush = this._onFlush.bind(this); - this._display.clear(); - - this._keyboard = new Keyboard(this._canvas); - this._keyboard.onkeyevent = this._handleKeyEvent.bind(this); - - this._mouse = new Mouse(this._canvas); - this._mouse.onmousebutton = this._handleMouseButton.bind(this); - this._mouse.onmousemove = this._handleMouseMove.bind(this); - - this._sock = new Websock(); - this._sock.on('message', this._handle_message.bind(this)); - this._sock.on('open', function () { - if ((this._rfb_connection_state === 'connecting') && - (this._rfb_init_state === '')) { - this._rfb_init_state = 'ProtocolVersion'; - Log.Debug("Starting VNC handshake"); - } else { - this._fail("Unexpected server connection while " + - this._rfb_connection_state); - } - }.bind(this)); - this._sock.on('close', function (e) { - Log.Debug("WebSocket on-close event"); - var msg = ""; - if (e.code) { - msg = "(code: " + e.code; - if (e.reason) { - msg += ", reason: " + e.reason; - } - msg += ")"; - } - switch (this._rfb_connection_state) { - case 'connecting': - this._fail("Connection closed " + msg); - break; - case 'connected': - // Handle disconnects that were initiated server-side - this._updateConnectionState('disconnecting'); - this._updateConnectionState('disconnected'); - break; - case 'disconnecting': - // Normal disconnection path - this._updateConnectionState('disconnected'); - break; - case 'disconnected': - this._fail("Unexpected server disconnect " + - "when already disconnected " + msg); - break; - default: - this._fail("Unexpected server disconnect before connecting " + - msg); - break; - } - this._sock.off('close'); - }.bind(this)); - this._sock.on('error', function (e) { - Log.Warn("WebSocket on-error event"); - }); - - // Slight delay of the actual connection so that the caller has - // time to set up callbacks - setTimeout(this._updateConnectionState.bind(this, 'connecting')); - - Log.Debug("<< RFB.constructor"); -}; - -RFB.prototype = { - // ===== PROPERTIES ===== - - dragViewport: false, - focusOnClick: true, - - _viewOnly: false, - get viewOnly() { return this._viewOnly; }, - set viewOnly(viewOnly) { - this._viewOnly = viewOnly; - - if (this._rfb_connection_state === "connecting" || - this._rfb_connection_state === "connected") { - if (viewOnly) { - this._keyboard.ungrab(); - this._mouse.ungrab(); - } else { - this._keyboard.grab(); - this._mouse.grab(); - } - } - }, - - get capabilities() { return this._capabilities; }, - - get touchButton() { return this._mouse.touchButton; }, - set touchButton(button) { this._mouse.touchButton = button; }, - - _clipViewport: false, - get clipViewport() { return this._clipViewport; }, - set clipViewport(viewport) { - this._clipViewport = viewport; - this._updateClip(); - }, - - _scaleViewport: false, - get scaleViewport() { return this._scaleViewport; }, - set scaleViewport(scale) { - this._scaleViewport = scale; - // Scaling trumps clipping, so we may need to adjust - // clipping when enabling or disabling scaling - if (scale && this._clipViewport) { - this._updateClip(); - } - this._updateScale(); - if (!scale && this._clipViewport) { - this._updateClip(); - } - }, - - _resizeSession: false, - get resizeSession() { return this._resizeSession; }, - set resizeSession(resize) { - this._resizeSession = resize; - if (resize) { - this._requestRemoteResize(); - } - }, - - // ===== PUBLIC METHODS ===== - - disconnect: function () { - this._updateConnectionState('disconnecting'); - this._sock.off('error'); - this._sock.off('message'); - this._sock.off('open'); - }, - - sendCredentials: function (creds) { - this._rfb_credentials = creds; - setTimeout(this._init_msg.bind(this), 0); - }, - - sendCtrlAltDel: function () { - if (this._rfb_connection_state !== 'connected' || this._viewOnly) { return; } - Log.Info("Sending Ctrl-Alt-Del"); - - this.sendKey(KeyTable.XK_Control_L, "ControlLeft", true); - this.sendKey(KeyTable.XK_Alt_L, "AltLeft", true); - this.sendKey(KeyTable.XK_Delete, "Delete", true); - this.sendKey(KeyTable.XK_Delete, "Delete", false); - this.sendKey(KeyTable.XK_Alt_L, "AltLeft", false); - this.sendKey(KeyTable.XK_Control_L, "ControlLeft", false); - }, - - machineShutdown: function () { - this._xvpOp(1, 2); - }, - - machineReboot: function () { - this._xvpOp(1, 3); - }, - - machineReset: function () { - this._xvpOp(1, 4); - }, - - // Send a key press. If 'down' is not specified then send a down key - // followed by an up key. - sendKey: function (keysym, code, down) { - if (this._rfb_connection_state !== 'connected' || this._viewOnly) { return; } - - if (down === undefined) { - this.sendKey(keysym, code, true); - this.sendKey(keysym, code, false); - return; - } - - var scancode = XtScancode[code]; - - if (this._qemuExtKeyEventSupported && scancode) { - // 0 is NoSymbol - keysym = keysym || 0; - - Log.Info("Sending key (" + (down ? "down" : "up") + "): keysym " + keysym + ", scancode " + scancode); - - RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode); - } else { - if (!keysym) { - return; - } - Log.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym); - RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0); - } - }, - - focus: function () { - this._canvas.focus(); - }, - - blur: function () { - this._canvas.blur(); - }, - - clipboardPasteFrom: function (text) { - if (this._rfb_connection_state !== 'connected' || this._viewOnly) { return; } - RFB.messages.clientCutText(this._sock, text); - }, - - // ===== PRIVATE METHODS ===== - - _connect: function () { - Log.Debug(">> RFB.connect"); - - Log.Info("connecting to " + this._url); - - try { - // WebSocket.onopen transitions to the RFB init states - this._sock.open(this._url, ['binary']); - } catch (e) { - if (e.name === 'SyntaxError') { - this._fail("Invalid host or port (" + e + ")"); - } else { - this._fail("Error when opening socket (" + e + ")"); - } - } - - // Make our elements part of the page - this._target.appendChild(this._screen); - - // Monitor size changes of the screen - // FIXME: Use ResizeObserver, or hidden overflow - window.addEventListener('resize', this._eventHandlers.windowResize); - - // Always grab focus on some kind of click event - this._canvas.addEventListener("mousedown", this._eventHandlers.focusCanvas); - this._canvas.addEventListener("touchstart", this._eventHandlers.focusCanvas); - - Log.Debug("<< RFB.connect"); - }, - - _disconnect: function () { - Log.Debug(">> RFB.disconnect"); - this._canvas.removeEventListener("mousedown", this._eventHandlers.focusCanvas); - this._canvas.removeEventListener("touchstart", this._eventHandlers.focusCanvas); - window.removeEventListener('resize', this._eventHandlers.windowResize); - this._keyboard.ungrab(); - this._mouse.ungrab(); - this._sock.close(); - this._print_stats(); - try { - this._target.removeChild(this._screen); - } catch (e) { - if (e.name === 'NotFoundError') { - // Some cases where the initial connection fails - // can disconnect before the _screen is created - } else { - throw e; - } - } - clearTimeout(this._resizeTimeout); - Log.Debug("<< RFB.disconnect"); - }, - - _print_stats: function () { - var stats = this._encStats; - - Log.Info("Encoding stats for this connection:"); - Object.keys(stats).forEach(function (key) { - var s = stats[key]; - if (s[0] + s[1] > 0) { - Log.Info(" " + encodingName(key) + ": " + s[0] + " rects"); - } - }); - - Log.Info("Encoding stats since page load:"); - Object.keys(stats).forEach(function (key) { - var s = stats[key]; - Log.Info(" " + encodingName(key) + ": " + s[1] + " rects"); - }); - }, - - _focusCanvas: function(event) { - // Respect earlier handlers' request to not do side-effects - if (event.defaultPrevented) { - return; - } - - if (!this.focusOnClick) { - return; - } - - this.focus(); - }, - - _windowResize: function (event) { - // If the window resized then our screen element might have - // as well. Update the viewport dimensions. - window.requestAnimationFrame(function () { - this._updateClip(); - this._updateScale(); - }.bind(this)); - - if (this._resizeSession) { - // Request changing the resolution of the remote display to - // the size of the local browser viewport. - - // In order to not send multiple requests before the browser-resize - // is finished we wait 0.5 seconds before sending the request. - clearTimeout(this._resizeTimeout); - this._resizeTimeout = setTimeout(this._requestRemoteResize.bind(this), 500); - } - }, - - // Update state of clipping in Display object, and make sure the - // configured viewport matches the current screen size - _updateClip: function () { - var cur_clip = this._display.clipViewport; - var new_clip = this._clipViewport; - - if (this._scaleViewport) { - // Disable viewport clipping if we are scaling - new_clip = false; - } - - if (cur_clip !== new_clip) { - this._display.clipViewport = new_clip; - } - - if (new_clip) { - // When clipping is enabled, the screen is limited to - // the size of the container. - let size = this._screenSize(); - this._display.viewportChangeSize(size.w, size.h); - this._fixScrollbars(); - } - }, - - _updateScale: function () { - if (!this._scaleViewport) { - this._display.scale = 1.0; - } else { - let size = this._screenSize(); - this._display.autoscale(size.w, size.h); - } - this._fixScrollbars(); - }, - - // Requests a change of remote desktop size. This message is an extension - // and may only be sent if we have received an ExtendedDesktopSize message - _requestRemoteResize: function () { - clearTimeout(this._resizeTimeout); - this._resizeTimeout = null; - - if (!this._resizeSession || this._viewOnly || - !this._supportsSetDesktopSize) { - return; - } - - let size = this._screenSize(); - RFB.messages.setDesktopSize(this._sock, size.w, size.h, - this._screen_id, this._screen_flags); - - Log.Debug('Requested new desktop size: ' + - size.w + 'x' + size.h); - }, - - // Gets the the size of the available screen - _screenSize: function () { - return { w: this._screen.offsetWidth, - h: this._screen.offsetHeight }; - }, - - _fixScrollbars: function () { - // This is a hack because Chrome screws up the calculation - // for when scrollbars are needed. So to fix it we temporarily - // toggle them off and on. - var orig = this._screen.style.overflow; - this._screen.style.overflow = 'hidden'; - // Force Chrome to recalculate the layout by asking for - // an element's dimensions - this._screen.getBoundingClientRect(); - this._screen.style.overflow = orig; - }, - - /* - * Connection states: - * connecting - * connected - * disconnecting - * disconnected - permanent state - */ - _updateConnectionState: function (state) { - var oldstate = this._rfb_connection_state; - - if (state === oldstate) { - Log.Debug("Already in state '" + state + "', ignoring"); - return; - } - - // The 'disconnected' state is permanent for each RFB object - if (oldstate === 'disconnected') { - Log.Error("Tried changing state of a disconnected RFB object"); - return; - } - - // Ensure proper transitions before doing anything - switch (state) { - case 'connected': - if (oldstate !== 'connecting') { - Log.Error("Bad transition to connected state, " + - "previous connection state: " + oldstate); - return; - } - break; - - case 'disconnected': - if (oldstate !== 'disconnecting') { - Log.Error("Bad transition to disconnected state, " + - "previous connection state: " + oldstate); - return; - } - break; - - case 'connecting': - if (oldstate !== '') { - Log.Error("Bad transition to connecting state, " + - "previous connection state: " + oldstate); - return; - } - break; - - case 'disconnecting': - if (oldstate !== 'connected' && oldstate !== 'connecting') { - Log.Error("Bad transition to disconnecting state, " + - "previous connection state: " + oldstate); - return; - } - break; - - default: - Log.Error("Unknown connection state: " + state); - return; - } - - // State change actions - - this._rfb_connection_state = state; - - var smsg = "New state '" + state + "', was '" + oldstate + "'."; - Log.Debug(smsg); - - if (this._disconnTimer && state !== 'disconnecting') { - Log.Debug("Clearing disconnect timer"); - clearTimeout(this._disconnTimer); - this._disconnTimer = null; - - // make sure we don't get a double event - this._sock.off('close'); - } - - switch (state) { - case 'connecting': - this._connect(); - break; - - case 'connected': - var event = new CustomEvent("connect", { detail: {} }); - this.dispatchEvent(event); - break; - - case 'disconnecting': - this._disconnect(); - - this._disconnTimer = setTimeout(function () { - Log.Error("Disconnection timed out."); - this._updateConnectionState('disconnected'); - }.bind(this), DISCONNECT_TIMEOUT * 1000); - break; - - case 'disconnected': - event = new CustomEvent( - "disconnect", { detail: - { clean: this._rfb_clean_disconnect } }); - this.dispatchEvent(event); - break; - } - }, - - /* Print errors and disconnect - * - * The parameter 'details' is used for information that - * should be logged but not sent to the user interface. - */ - _fail: function (details) { - switch (this._rfb_connection_state) { - case 'disconnecting': - Log.Error("Failed when disconnecting: " + details); - break; - case 'connected': - Log.Error("Failed while connected: " + details); - break; - case 'connecting': - Log.Error("Failed when connecting: " + details); - break; - default: - Log.Error("RFB failure: " + details); - break; - } - this._rfb_clean_disconnect = false; //This is sent to the UI - - // Transition to disconnected without waiting for socket to close - this._updateConnectionState('disconnecting'); - this._updateConnectionState('disconnected'); - - return false; - }, - - _setCapability: function (cap, val) { - this._capabilities[cap] = val; - var event = new CustomEvent("capabilities", - { detail: { capabilities: this._capabilities } }); - this.dispatchEvent(event); - }, - - _handle_message: function () { - if (this._sock.rQlen() === 0) { - Log.Warn("handle_message called on an empty receive queue"); - return; - } - - switch (this._rfb_connection_state) { - case 'disconnected': - Log.Error("Got data while disconnected"); - break; - case 'connected': - while (true) { - if (this._flushing) { - break; - } - if (!this._normal_msg()) { - break; - } - if (this._sock.rQlen() === 0) { - break; - } - } - break; - default: - this._init_msg(); - break; - } - }, - - _handleKeyEvent: function (keysym, code, down) { - this.sendKey(keysym, code, down); - }, - - _handleMouseButton: function (x, y, down, bmask) { - if (down) { - this._mouse_buttonMask |= bmask; - } else { - this._mouse_buttonMask &= ~bmask; - } - - if (this.dragViewport) { - if (down && !this._viewportDragging) { - this._viewportDragging = true; - this._viewportDragPos = {'x': x, 'y': y}; - this._viewportHasMoved = false; - - // Skip sending mouse events - return; - } else { - this._viewportDragging = false; - - // If we actually performed a drag then we are done - // here and should not send any mouse events - if (this._viewportHasMoved) { - return; - } - - // Otherwise we treat this as a mouse click event. - // Send the button down event here, as the button up - // event is sent at the end of this function. - RFB.messages.pointerEvent(this._sock, - this._display.absX(x), - this._display.absY(y), - bmask); - } - } - - if (this._viewOnly) { return; } // View only, skip mouse events - - if (this._rfb_connection_state !== 'connected') { return; } - RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask); - }, - - _handleMouseMove: function (x, y) { - if (this._viewportDragging) { - var deltaX = this._viewportDragPos.x - x; - var deltaY = this._viewportDragPos.y - y; - - // The goal is to trigger on a certain physical width, the - // devicePixelRatio brings us a bit closer but is not optimal. - var dragThreshold = 10 * (window.devicePixelRatio || 1); - - if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold || - Math.abs(deltaY) > dragThreshold)) { - this._viewportHasMoved = true; - - this._viewportDragPos = {'x': x, 'y': y}; - this._display.viewportChangePos(deltaX, deltaY); - } - - // Skip sending mouse events - return; - } - - if (this._viewOnly) { return; } // View only, skip mouse events - - if (this._rfb_connection_state !== 'connected') { return; } - RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask); - }, - - // Message Handlers - - _negotiate_protocol_version: function () { - if (this._sock.rQlen() < 12) { - return this._fail("Received incomplete protocol version."); - } - - var sversion = this._sock.rQshiftStr(12).substr(4, 7); - Log.Info("Server ProtocolVersion: " + sversion); - var is_repeater = 0; - switch (sversion) { - case "000.000": // UltraVNC repeater - is_repeater = 1; - break; - case "003.003": - case "003.006": // UltraVNC - case "003.889": // Apple Remote Desktop - this._rfb_version = 3.3; - break; - case "003.007": - this._rfb_version = 3.7; - break; - case "003.008": - case "004.000": // Intel AMT KVM - case "004.001": // RealVNC 4.6 - case "005.000": // RealVNC 5.3 - this._rfb_version = 3.8; - break; - default: - return this._fail("Invalid server version " + sversion); - } - - if (is_repeater) { - var repeaterID = "ID:" + this._repeaterID; - while (repeaterID.length < 250) { - repeaterID += "\0"; - } - this._sock.send_string(repeaterID); - return true; - } - - if (this._rfb_version > this._rfb_max_version) { - this._rfb_version = this._rfb_max_version; - } - - var cversion = "00" + parseInt(this._rfb_version, 10) + - ".00" + ((this._rfb_version * 10) % 10); - this._sock.send_string("RFB " + cversion + "\n"); - Log.Debug('Sent ProtocolVersion: ' + cversion); - - this._rfb_init_state = 'Security'; - }, - - _negotiate_security: function () { - // Polyfill since IE and PhantomJS doesn't have - // TypedArray.includes() - function includes(item, array) { - for (var i = 0; i < array.length; i++) { - if (array[i] === item) { - return true; - } - } - return false; - } - - if (this._rfb_version >= 3.7) { - // Server sends supported list, client decides - var num_types = this._sock.rQshift8(); - if (this._sock.rQwait("security type", num_types, 1)) { return false; } - - if (num_types === 0) { - return this._handle_security_failure("no security types"); - } - - var types = this._sock.rQshiftBytes(num_types); - Log.Debug("Server security types: " + types); - - // Look for each auth in preferred order - this._rfb_auth_scheme = 0; - if (includes(1, types)) { - this._rfb_auth_scheme = 1; // None - } else if (includes(22, types)) { - this._rfb_auth_scheme = 22; // XVP - } else if (includes(16, types)) { - this._rfb_auth_scheme = 16; // Tight - } else if (includes(2, types)) { - this._rfb_auth_scheme = 2; // VNC Auth - } else { - return this._fail("Unsupported security types (types: " + types + ")"); - } - - this._sock.send([this._rfb_auth_scheme]); - } else { - // Server decides - if (this._sock.rQwait("security scheme", 4)) { return false; } - this._rfb_auth_scheme = this._sock.rQshift32(); - } - - this._rfb_init_state = 'Authentication'; - Log.Debug('Authenticating using scheme: ' + this._rfb_auth_scheme); - - return this._init_msg(); // jump to authentication - }, - - /* - * Get the security failure reason if sent from the server and - * send the 'securityfailure' event. - * - * - The optional parameter context can be used to add some extra - * context to the log output. - * - * - The optional parameter security_result_status can be used to - * add a custom status code to the event. - */ - _handle_security_failure: function (context, security_result_status) { - - if (typeof context === 'undefined') { - context = ""; - } else { - context = " on " + context; - } - - if (typeof security_result_status === 'undefined') { - security_result_status = 1; // fail - } - - if (this._sock.rQwait("reason length", 4)) { - return false; - } - let strlen = this._sock.rQshift32(); - let reason = ""; - - if (strlen > 0) { - if (this._sock.rQwait("reason", strlen, 8)) { return false; } - reason = this._sock.rQshiftStr(strlen); - } - - if (reason !== "") { - - let event = new CustomEvent( - "securityfailure", - { detail: { status: security_result_status, reason: reason } }); - this.dispatchEvent(event); - - return this._fail("Security negotiation failed" + context + - " (reason: " + reason + ")"); - } else { - - let event = new CustomEvent( - "securityfailure", - { detail: { status: security_result_status } }); - this.dispatchEvent(event); - - return this._fail("Security negotiation failed" + context); - } - }, - - // authentication - _negotiate_xvp_auth: function () { - if (!this._rfb_credentials.username || - !this._rfb_credentials.password || - !this._rfb_credentials.target) { - var event = new CustomEvent("credentialsrequired", - { detail: { types: ["username", "password", "target"] } }); - this.dispatchEvent(event); - return false; - } - - var xvp_auth_str = String.fromCharCode(this._rfb_credentials.username.length) + - String.fromCharCode(this._rfb_credentials.target.length) + - this._rfb_credentials.username + - this._rfb_credentials.target; - this._sock.send_string(xvp_auth_str); - this._rfb_auth_scheme = 2; - return this._negotiate_authentication(); - }, - - _negotiate_std_vnc_auth: function () { - if (this._sock.rQwait("auth challenge", 16)) { return false; } - - if (!this._rfb_credentials.password) { - var event = new CustomEvent("credentialsrequired", - { detail: { types: ["password"] } }); - this.dispatchEvent(event); - return false; - } - - // TODO(directxman12): make genDES not require an Array - var challenge = Array.prototype.slice.call(this._sock.rQshiftBytes(16)); - var response = RFB.genDES(this._rfb_credentials.password, challenge); - this._sock.send(response); - this._rfb_init_state = "SecurityResult"; - return true; - }, - - _negotiate_tight_tunnels: function (numTunnels) { - var clientSupportedTunnelTypes = { - 0: { vendor: 'TGHT', signature: 'NOTUNNEL' } - }; - var serverSupportedTunnelTypes = {}; - // receive tunnel capabilities - for (var i = 0; i < numTunnels; i++) { - var cap_code = this._sock.rQshift32(); - var cap_vendor = this._sock.rQshiftStr(4); - var cap_signature = this._sock.rQshiftStr(8); - serverSupportedTunnelTypes[cap_code] = { vendor: cap_vendor, signature: cap_signature }; - } - - // choose the notunnel type - if (serverSupportedTunnelTypes[0]) { - if (serverSupportedTunnelTypes[0].vendor != clientSupportedTunnelTypes[0].vendor || - serverSupportedTunnelTypes[0].signature != clientSupportedTunnelTypes[0].signature) { - return this._fail("Client's tunnel type had the incorrect " + - "vendor or signature"); - } - this._sock.send([0, 0, 0, 0]); // use NOTUNNEL - return false; // wait until we receive the sub auth count to continue - } else { - return this._fail("Server wanted tunnels, but doesn't support " + - "the notunnel type"); - } - }, - - _negotiate_tight_auth: function () { - if (!this._rfb_tightvnc) { // first pass, do the tunnel negotiation - if (this._sock.rQwait("num tunnels", 4)) { return false; } - var numTunnels = this._sock.rQshift32(); - if (numTunnels > 0 && this._sock.rQwait("tunnel capabilities", 16 * numTunnels, 4)) { return false; } - - this._rfb_tightvnc = true; - - if (numTunnels > 0) { - this._negotiate_tight_tunnels(numTunnels); - return false; // wait until we receive the sub auth to continue - } - } - - // second pass, do the sub-auth negotiation - if (this._sock.rQwait("sub auth count", 4)) { return false; } - var subAuthCount = this._sock.rQshift32(); - if (subAuthCount === 0) { // empty sub-auth list received means 'no auth' subtype selected - this._rfb_init_state = 'SecurityResult'; - return true; - } - - if (this._sock.rQwait("sub auth capabilities", 16 * subAuthCount, 4)) { return false; } - - var clientSupportedTypes = { - 'STDVNOAUTH__': 1, - 'STDVVNCAUTH_': 2 - }; - - var serverSupportedTypes = []; - - for (var i = 0; i < subAuthCount; i++) { - var capNum = this._sock.rQshift32(); - var capabilities = this._sock.rQshiftStr(12); - serverSupportedTypes.push(capabilities); - } - - for (var authType in clientSupportedTypes) { - if (serverSupportedTypes.indexOf(authType) != -1) { - this._sock.send([0, 0, 0, clientSupportedTypes[authType]]); - - switch (authType) { - case 'STDVNOAUTH__': // no auth - this._rfb_init_state = 'SecurityResult'; - return true; - case 'STDVVNCAUTH_': // VNC auth - this._rfb_auth_scheme = 2; - return this._init_msg(); - default: - return this._fail("Unsupported tiny auth scheme " + - "(scheme: " + authType + ")"); - } - } - } - - return this._fail("No supported sub-auth types!"); - }, - - _negotiate_authentication: function () { - switch (this._rfb_auth_scheme) { - case 0: // connection failed - return this._handle_security_failure("authentication scheme"); - - case 1: // no auth - if (this._rfb_version >= 3.8) { - this._rfb_init_state = 'SecurityResult'; - return true; - } - this._rfb_init_state = 'ClientInitialisation'; - return this._init_msg(); - - case 22: // XVP auth - return this._negotiate_xvp_auth(); - - case 2: // VNC authentication - return this._negotiate_std_vnc_auth(); - - case 16: // TightVNC Security Type - return this._negotiate_tight_auth(); - - default: - return this._fail("Unsupported auth scheme (scheme: " + - this._rfb_auth_scheme + ")"); - } - }, - - _handle_security_result: function () { - if (this._sock.rQwait('VNC auth response ', 4)) { return false; } - - let status = this._sock.rQshift32(); - - if (status === 0) { // OK - this._rfb_init_state = 'ClientInitialisation'; - Log.Debug('Authentication OK'); - return this._init_msg(); - } else { - if (this._rfb_version >= 3.8) { - return this._handle_security_failure("security result", status); - } else { - let event = new CustomEvent("securityfailure", - { detail: { status: status } }); - this.dispatchEvent(event); - - return this._fail("Security handshake failed"); - } - } - }, - - _negotiate_server_init: function () { - if (this._sock.rQwait("server initialization", 24)) { return false; } - - /* Screen size */ - var width = this._sock.rQshift16(); - var height = this._sock.rQshift16(); - - /* PIXEL_FORMAT */ - var bpp = this._sock.rQshift8(); - var depth = this._sock.rQshift8(); - var big_endian = this._sock.rQshift8(); - var true_color = this._sock.rQshift8(); - - var red_max = this._sock.rQshift16(); - var green_max = this._sock.rQshift16(); - var blue_max = this._sock.rQshift16(); - var red_shift = this._sock.rQshift8(); - var green_shift = this._sock.rQshift8(); - var blue_shift = this._sock.rQshift8(); - this._sock.rQskipBytes(3); // padding - - // NB(directxman12): we don't want to call any callbacks or print messages until - // *after* we're past the point where we could backtrack - - /* Connection name/title */ - var name_length = this._sock.rQshift32(); - if (this._sock.rQwait('server init name', name_length, 24)) { return false; } - this._fb_name = decodeUTF8(this._sock.rQshiftStr(name_length)); - - if (this._rfb_tightvnc) { - if (this._sock.rQwait('TightVNC extended server init header', 8, 24 + name_length)) { return false; } - // In TightVNC mode, ServerInit message is extended - var numServerMessages = this._sock.rQshift16(); - var numClientMessages = this._sock.rQshift16(); - var numEncodings = this._sock.rQshift16(); - this._sock.rQskipBytes(2); // padding - - var totalMessagesLength = (numServerMessages + numClientMessages + numEncodings) * 16; - if (this._sock.rQwait('TightVNC extended server init header', totalMessagesLength, 32 + name_length)) { return false; } - - // we don't actually do anything with the capability information that TIGHT sends, - // so we just skip the all of this. - - // TIGHT server message capabilities - this._sock.rQskipBytes(16 * numServerMessages); - - // TIGHT client message capabilities - this._sock.rQskipBytes(16 * numClientMessages); - - // TIGHT encoding capabilities - this._sock.rQskipBytes(16 * numEncodings); - } - - // NB(directxman12): these are down here so that we don't run them multiple times - // if we backtrack - Log.Info("Screen: " + width + "x" + height + - ", bpp: " + bpp + ", depth: " + depth + - ", big_endian: " + big_endian + - ", true_color: " + true_color + - ", red_max: " + red_max + - ", green_max: " + green_max + - ", blue_max: " + blue_max + - ", red_shift: " + red_shift + - ", green_shift: " + green_shift + - ", blue_shift: " + blue_shift); - - if (big_endian !== 0) { - Log.Warn("Server native endian is not little endian"); - } - - if (red_shift !== 16) { - Log.Warn("Server native red-shift is not 16"); - } - - if (blue_shift !== 0) { - Log.Warn("Server native blue-shift is not 0"); - } - - // we're past the point where we could backtrack, so it's safe to call this - var event = new CustomEvent("desktopname", - { detail: { name: this._fb_name } }); - this.dispatchEvent(event); - - this._resize(width, height); - - if (!this._viewOnly) { this._keyboard.grab(); } - if (!this._viewOnly) { this._mouse.grab(); } - - this._fb_depth = 24; - - if (this._fb_name === "Intel(r) AMT KVM") { - Log.Warn("Intel AMT KVM only supports 8/16 bit depths. Using low color mode."); - this._fb_depth = 8; - } else if (this._fb_name === "MBSE BrewBoard") { - Log.Warn("MBSE BrewBoard only supports 8 bit depths. Using low color mode."); - this._fb_depth = 8; - } - - RFB.messages.pixelFormat(this._sock, this._fb_depth, true); - this._sendEncodings(); - RFB.messages.fbUpdateRequest(this._sock, false, 0, 0, this._fb_width, this._fb_height); - - this._timing.fbu_rt_start = (new Date()).getTime(); - this._timing.pixels = 0; - - // Cursor will be server side until the server decides to honor - // our request and send over the cursor image - this._display.disableLocalCursor(); - - this._updateConnectionState('connected'); - return true; - }, - - _sendEncodings: function () { - var encs = []; - - // In preference order - encs.push(encodings.encodingCopyRect); - // Only supported with full depth support - if (this._fb_depth == 24) { - encs.push(encodings.encodingTight); - encs.push(encodings.encodingHextile); - encs.push(encodings.encodingRRE); - } - encs.push(encodings.encodingRaw); - - // Psuedo-encoding settings - encs.push(encodings.pseudoEncodingTightPNG); - encs.push(encodings.pseudoEncodingQualityLevel0 + 6); - encs.push(encodings.pseudoEncodingCompressLevel0 + 2); - - encs.push(encodings.pseudoEncodingDesktopSize); - encs.push(encodings.pseudoEncodingLastRect); - encs.push(encodings.pseudoEncodingQEMUExtendedKeyEvent); - encs.push(encodings.pseudoEncodingExtendedDesktopSize); - encs.push(encodings.pseudoEncodingXvp); - encs.push(encodings.pseudoEncodingFence); - encs.push(encodings.pseudoEncodingContinuousUpdates); - - if (supportsCursorURIs() && - !isTouchDevice && this._fb_depth == 24) { - encs.push(encodings.pseudoEncodingCursor); - } - - RFB.messages.clientEncodings(this._sock, encs); - }, - - /* RFB protocol initialization states: - * ProtocolVersion - * Security - * Authentication - * SecurityResult - * ClientInitialization - not triggered by server message - * ServerInitialization - */ - _init_msg: function () { - switch (this._rfb_init_state) { - case 'ProtocolVersion': - return this._negotiate_protocol_version(); - - case 'Security': - return this._negotiate_security(); - - case 'Authentication': - return this._negotiate_authentication(); - - case 'SecurityResult': - return this._handle_security_result(); - - case 'ClientInitialisation': - this._sock.send([this._shared ? 1 : 0]); // ClientInitialisation - this._rfb_init_state = 'ServerInitialisation'; - return true; - - case 'ServerInitialisation': - return this._negotiate_server_init(); - - default: - return this._fail("Unknown init state (state: " + - this._rfb_init_state + ")"); - } - }, - - _handle_set_colour_map_msg: function () { - Log.Debug("SetColorMapEntries"); - - return this._fail("Unexpected SetColorMapEntries message"); - }, - - _handle_server_cut_text: function () { - Log.Debug("ServerCutText"); - - if (this._sock.rQwait("ServerCutText header", 7, 1)) { return false; } - this._sock.rQskipBytes(3); // Padding - var length = this._sock.rQshift32(); - if (this._sock.rQwait("ServerCutText", length, 8)) { return false; } - - var text = this._sock.rQshiftStr(length); - - if (this._viewOnly) { return true; } - - var event = new CustomEvent("clipboard", - { detail: { text: text } }); - this.dispatchEvent(event); - - return true; - }, - - _handle_server_fence_msg: function() { - if (this._sock.rQwait("ServerFence header", 8, 1)) { return false; } - this._sock.rQskipBytes(3); // Padding - var flags = this._sock.rQshift32(); - var length = this._sock.rQshift8(); - - if (this._sock.rQwait("ServerFence payload", length, 9)) { return false; } - - if (length > 64) { - Log.Warn("Bad payload length (" + length + ") in fence response"); - length = 64; - } - - var payload = this._sock.rQshiftStr(length); - - this._supportsFence = true; - - /* - * Fence flags - * - * (1<<0) - BlockBefore - * (1<<1) - BlockAfter - * (1<<2) - SyncNext - * (1<<31) - Request - */ - - if (!(flags & (1<<31))) { - return this._fail("Unexpected fence response"); - } - - // Filter out unsupported flags - // FIXME: support syncNext - flags &= (1<<0) | (1<<1); - - // BlockBefore and BlockAfter are automatically handled by - // the fact that we process each incoming message - // synchronuosly. - RFB.messages.clientFence(this._sock, flags, payload); - - return true; - }, - - _handle_xvp_msg: function () { - if (this._sock.rQwait("XVP version and message", 3, 1)) { return false; } - this._sock.rQskip8(); // Padding - var xvp_ver = this._sock.rQshift8(); - var xvp_msg = this._sock.rQshift8(); - - switch (xvp_msg) { - case 0: // XVP_FAIL - Log.Error("XVP Operation Failed"); - break; - case 1: // XVP_INIT - this._rfb_xvp_ver = xvp_ver; - Log.Info("XVP extensions enabled (version " + this._rfb_xvp_ver + ")"); - this._setCapability("power", true); - break; - default: - this._fail("Illegal server XVP message (msg: " + xvp_msg + ")"); - break; - } - - return true; - }, - - _normal_msg: function () { - var msg_type; - - if (this._FBU.rects > 0) { - msg_type = 0; - } else { - msg_type = this._sock.rQshift8(); - } - - switch (msg_type) { - case 0: // FramebufferUpdate - var ret = this._framebufferUpdate(); - if (ret && !this._enabledContinuousUpdates) { - RFB.messages.fbUpdateRequest(this._sock, true, 0, 0, - this._fb_width, this._fb_height); - } - return ret; - - case 1: // SetColorMapEntries - return this._handle_set_colour_map_msg(); - - case 2: // Bell - Log.Debug("Bell"); - var event = new CustomEvent("bell", { detail: {} }); - this.dispatchEvent(event); - return true; - - case 3: // ServerCutText - return this._handle_server_cut_text(); - - case 150: // EndOfContinuousUpdates - var first = !(this._supportsContinuousUpdates); - this._supportsContinuousUpdates = true; - this._enabledContinuousUpdates = false; - if (first) { - this._enabledContinuousUpdates = true; - this._updateContinuousUpdates(); - Log.Info("Enabling continuous updates."); - } else { - // FIXME: We need to send a framebufferupdaterequest here - // if we add support for turning off continuous updates - } - return true; - - case 248: // ServerFence - return this._handle_server_fence_msg(); - - case 250: // XVP - return this._handle_xvp_msg(); - - default: - this._fail("Unexpected server message (type " + msg_type + ")"); - Log.Debug("sock.rQslice(0, 30): " + this._sock.rQslice(0, 30)); - return true; - } - }, - - _onFlush: function() { - this._flushing = false; - // Resume processing - if (this._sock.rQlen() > 0) { - this._handle_message(); - } - }, - - _framebufferUpdate: function () { - var ret = true; - var now; - - if (this._FBU.rects === 0) { - if (this._sock.rQwait("FBU header", 3, 1)) { return false; } - this._sock.rQskip8(); // Padding - this._FBU.rects = this._sock.rQshift16(); - this._FBU.bytes = 0; - this._timing.cur_fbu = 0; - if (this._timing.fbu_rt_start > 0) { - now = (new Date()).getTime(); - Log.Info("First FBU latency: " + (now - this._timing.fbu_rt_start)); - } - - // Make sure the previous frame is fully rendered first - // to avoid building up an excessive queue - if (this._display.pending()) { - this._flushing = true; - this._display.flush(); - return false; - } - } - - while (this._FBU.rects > 0) { - if (this._rfb_connection_state !== 'connected') { return false; } - - if (this._sock.rQwait("FBU", this._FBU.bytes)) { return false; } - if (this._FBU.bytes === 0) { - if (this._sock.rQwait("rect header", 12)) { return false; } - /* New FramebufferUpdate */ - - var hdr = this._sock.rQshiftBytes(12); - this._FBU.x = (hdr[0] << 8) + hdr[1]; - this._FBU.y = (hdr[2] << 8) + hdr[3]; - this._FBU.width = (hdr[4] << 8) + hdr[5]; - this._FBU.height = (hdr[6] << 8) + hdr[7]; - this._FBU.encoding = parseInt((hdr[8] << 24) + (hdr[9] << 16) + - (hdr[10] << 8) + hdr[11], 10); - - if (!this._encHandlers[this._FBU.encoding]) { - this._fail("Unsupported encoding (encoding: " + - this._FBU.encoding + ")"); - return false; - } - } - - this._timing.last_fbu = (new Date()).getTime(); - - ret = this._encHandlers[this._FBU.encoding](); - - now = (new Date()).getTime(); - this._timing.cur_fbu += (now - this._timing.last_fbu); - - if (ret) { - if (!(this._FBU.encoding in this._encStats)) { - this._encStats[this._FBU.encoding] = [0, 0]; - } - this._encStats[this._FBU.encoding][0]++; - this._encStats[this._FBU.encoding][1]++; - this._timing.pixels += this._FBU.width * this._FBU.height; - } - - if (this._timing.pixels >= (this._fb_width * this._fb_height)) { - if ((this._FBU.width === this._fb_width && this._FBU.height === this._fb_height) || - this._timing.fbu_rt_start > 0) { - this._timing.full_fbu_total += this._timing.cur_fbu; - this._timing.full_fbu_cnt++; - Log.Info("Timing of full FBU, curr: " + - this._timing.cur_fbu + ", total: " + - this._timing.full_fbu_total + ", cnt: " + - this._timing.full_fbu_cnt + ", avg: " + - (this._timing.full_fbu_total / this._timing.full_fbu_cnt)); - } - - if (this._timing.fbu_rt_start > 0) { - var fbu_rt_diff = now - this._timing.fbu_rt_start; - this._timing.fbu_rt_total += fbu_rt_diff; - this._timing.fbu_rt_cnt++; - Log.Info("full FBU round-trip, cur: " + - fbu_rt_diff + ", total: " + - this._timing.fbu_rt_total + ", cnt: " + - this._timing.fbu_rt_cnt + ", avg: " + - (this._timing.fbu_rt_total / this._timing.fbu_rt_cnt)); - this._timing.fbu_rt_start = 0; - } - } - - if (!ret) { return ret; } // need more data - } - - this._display.flip(); - - return true; // We finished this FBU - }, - - _updateContinuousUpdates: function() { - if (!this._enabledContinuousUpdates) { return; } - - RFB.messages.enableContinuousUpdates(this._sock, true, 0, 0, - this._fb_width, this._fb_height); - }, - - _resize: function(width, height) { - this._fb_width = width; - this._fb_height = height; - - this._destBuff = new Uint8Array(this._fb_width * this._fb_height * 4); - - this._display.resize(this._fb_width, this._fb_height); - - // Adjust the visible viewport based on the new dimensions - this._updateClip(); - this._updateScale(); - - this._timing.fbu_rt_start = (new Date()).getTime(); - this._updateContinuousUpdates(); - }, - - _xvpOp: function (ver, op) { - if (this._rfb_xvp_ver < ver) { return; } - Log.Info("Sending XVP operation " + op + " (version " + ver + ")"); - RFB.messages.xvpOp(this._sock, ver, op); - }, -}; - -Object.assign(RFB.prototype, EventTargetMixin); - -// Class Methods -RFB.messages = { - keyEvent: function (sock, keysym, down) { - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 4; // msg-type - buff[offset + 1] = down; - - buff[offset + 2] = 0; - buff[offset + 3] = 0; - - buff[offset + 4] = (keysym >> 24); - buff[offset + 5] = (keysym >> 16); - buff[offset + 6] = (keysym >> 8); - buff[offset + 7] = keysym; - - sock._sQlen += 8; - sock.flush(); - }, - - QEMUExtendedKeyEvent: function (sock, keysym, down, keycode) { - function getRFBkeycode(xt_scancode) { - var upperByte = (keycode >> 8); - var lowerByte = (keycode & 0x00ff); - if (upperByte === 0xe0 && lowerByte < 0x7f) { - lowerByte = lowerByte | 0x80; - return lowerByte; - } - return xt_scancode; - } - - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 255; // msg-type - buff[offset + 1] = 0; // sub msg-type - - buff[offset + 2] = (down >> 8); - buff[offset + 3] = down; - - buff[offset + 4] = (keysym >> 24); - buff[offset + 5] = (keysym >> 16); - buff[offset + 6] = (keysym >> 8); - buff[offset + 7] = keysym; - - var RFBkeycode = getRFBkeycode(keycode); - - buff[offset + 8] = (RFBkeycode >> 24); - buff[offset + 9] = (RFBkeycode >> 16); - buff[offset + 10] = (RFBkeycode >> 8); - buff[offset + 11] = RFBkeycode; - - sock._sQlen += 12; - sock.flush(); - }, - - pointerEvent: function (sock, x, y, mask) { - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 5; // msg-type - - buff[offset + 1] = mask; - - buff[offset + 2] = x >> 8; - buff[offset + 3] = x; - - buff[offset + 4] = y >> 8; - buff[offset + 5] = y; - - sock._sQlen += 6; - sock.flush(); - }, - - // TODO(directxman12): make this unicode compatible? - clientCutText: function (sock, text) { - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 6; // msg-type - - buff[offset + 1] = 0; // padding - buff[offset + 2] = 0; // padding - buff[offset + 3] = 0; // padding - - var n = text.length; - - buff[offset + 4] = n >> 24; - buff[offset + 5] = n >> 16; - buff[offset + 6] = n >> 8; - buff[offset + 7] = n; - - for (var i = 0; i < n; i++) { - buff[offset + 8 + i] = text.charCodeAt(i); - } - - sock._sQlen += 8 + n; - sock.flush(); - }, - - setDesktopSize: function (sock, width, height, id, flags) { - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 251; // msg-type - buff[offset + 1] = 0; // padding - buff[offset + 2] = width >> 8; // width - buff[offset + 3] = width; - buff[offset + 4] = height >> 8; // height - buff[offset + 5] = height; - - buff[offset + 6] = 1; // number-of-screens - buff[offset + 7] = 0; // padding - - // screen array - buff[offset + 8] = id >> 24; // id - buff[offset + 9] = id >> 16; - buff[offset + 10] = id >> 8; - buff[offset + 11] = id; - buff[offset + 12] = 0; // x-position - buff[offset + 13] = 0; - buff[offset + 14] = 0; // y-position - buff[offset + 15] = 0; - buff[offset + 16] = width >> 8; // width - buff[offset + 17] = width; - buff[offset + 18] = height >> 8; // height - buff[offset + 19] = height; - buff[offset + 20] = flags >> 24; // flags - buff[offset + 21] = flags >> 16; - buff[offset + 22] = flags >> 8; - buff[offset + 23] = flags; - - sock._sQlen += 24; - sock.flush(); - }, - - clientFence: function (sock, flags, payload) { - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 248; // msg-type - - buff[offset + 1] = 0; // padding - buff[offset + 2] = 0; // padding - buff[offset + 3] = 0; // padding - - buff[offset + 4] = flags >> 24; // flags - buff[offset + 5] = flags >> 16; - buff[offset + 6] = flags >> 8; - buff[offset + 7] = flags; - - var n = payload.length; - - buff[offset + 8] = n; // length - - for (var i = 0; i < n; i++) { - buff[offset + 9 + i] = payload.charCodeAt(i); - } - - sock._sQlen += 9 + n; - sock.flush(); - }, - - enableContinuousUpdates: function (sock, enable, x, y, width, height) { - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 150; // msg-type - buff[offset + 1] = enable; // enable-flag - - buff[offset + 2] = x >> 8; // x - buff[offset + 3] = x; - buff[offset + 4] = y >> 8; // y - buff[offset + 5] = y; - buff[offset + 6] = width >> 8; // width - buff[offset + 7] = width; - buff[offset + 8] = height >> 8; // height - buff[offset + 9] = height; - - sock._sQlen += 10; - sock.flush(); - }, - - pixelFormat: function (sock, depth, true_color) { - var buff = sock._sQ; - var offset = sock._sQlen; - - var bpp, bits; - - if (depth > 16) { - bpp = 32; - } else if (depth > 8) { - bpp = 16; - } else { - bpp = 8; - } - - bits = Math.floor(depth/3); - - buff[offset] = 0; // msg-type - - buff[offset + 1] = 0; // padding - buff[offset + 2] = 0; // padding - buff[offset + 3] = 0; // padding - - buff[offset + 4] = bpp; // bits-per-pixel - buff[offset + 5] = depth; // depth - buff[offset + 6] = 0; // little-endian - buff[offset + 7] = true_color ? 1 : 0; // true-color - - buff[offset + 8] = 0; // red-max - buff[offset + 10] = 0; // green-max - buff[offset + 12] = 0; // blue-max - - if (depth == 8) { - buff[offset + 9] = 7; // red-max - buff[offset + 11] = 7; // green-max - buff[offset + 13] = 3; // blue-max - buff[offset + 14] = 5; // red-shift - buff[offset + 15] = 2; // green-shift - buff[offset + 16] = 0; // blue-shift - } else { - buff[offset + 9] = (1 << bits) - 1; // red-max - buff[offset + 11] = (1 << bits) - 1; // green-max - buff[offset + 13] = (1 << bits) - 1; // blue-max - buff[offset + 14] = bits * 2; // red-shift - buff[offset + 15] = bits * 1; // green-shift - buff[offset + 16] = bits * 0; // blue-shift - } - - buff[offset + 17] = 0; // padding - buff[offset + 18] = 0; // padding - buff[offset + 19] = 0; // padding - - sock._sQlen += 20; - sock.flush(); - }, - - clientEncodings: function (sock, encodings) { - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 2; // msg-type - buff[offset + 1] = 0; // padding - - buff[offset + 2] = encodings.length >> 8; - buff[offset + 3] = encodings.length; - - var i, j = offset + 4; - for (i = 0; i < encodings.length; i++) { - var enc = encodings[i]; - buff[j] = enc >> 24; - buff[j + 1] = enc >> 16; - buff[j + 2] = enc >> 8; - buff[j + 3] = enc; - - j += 4; - } - - sock._sQlen += j - offset; - sock.flush(); - }, - - fbUpdateRequest: function (sock, incremental, x, y, w, h) { - var buff = sock._sQ; - var offset = sock._sQlen; - - if (typeof(x) === "undefined") { x = 0; } - if (typeof(y) === "undefined") { y = 0; } - - buff[offset] = 3; // msg-type - buff[offset + 1] = incremental ? 1 : 0; - - buff[offset + 2] = (x >> 8) & 0xFF; - buff[offset + 3] = x & 0xFF; - - buff[offset + 4] = (y >> 8) & 0xFF; - buff[offset + 5] = y & 0xFF; - - buff[offset + 6] = (w >> 8) & 0xFF; - buff[offset + 7] = w & 0xFF; - - buff[offset + 8] = (h >> 8) & 0xFF; - buff[offset + 9] = h & 0xFF; - - sock._sQlen += 10; - sock.flush(); - }, - - xvpOp: function (sock, ver, op) { - var buff = sock._sQ; - var offset = sock._sQlen; - - buff[offset] = 250; // msg-type - buff[offset + 1] = 0; // padding - - buff[offset + 2] = ver; - buff[offset + 3] = op; - - sock._sQlen += 4; - sock.flush(); - }, -}; - -RFB.genDES = function (password, challenge) { - var passwd = []; - for (var i = 0; i < password.length; i++) { - passwd.push(password.charCodeAt(i)); - } - return (new DES(passwd)).encrypt(challenge); -}; - -RFB.encodingHandlers = { - RAW: function () { - if (this._FBU.lines === 0) { - this._FBU.lines = this._FBU.height; - } - - var pixelSize = this._fb_depth == 8 ? 1 : 4; - this._FBU.bytes = this._FBU.width * pixelSize; // at least a line - if (this._sock.rQwait("RAW", this._FBU.bytes)) { return false; } - var cur_y = this._FBU.y + (this._FBU.height - this._FBU.lines); - var curr_height = Math.min(this._FBU.lines, - Math.floor(this._sock.rQlen() / (this._FBU.width * pixelSize))); - var data = this._sock.get_rQ(); - var index = this._sock.get_rQi(); - if (this._fb_depth == 8) { - var pixels = this._FBU.width * curr_height - var newdata = new Uint8Array(pixels * 4); - var i; - for (i = 0;i < pixels;i++) { - //newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3; - //newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x3) * 255 / 3; - //newdata[i * 4 + 2] = ((data[index + i] >> 4) & 0x3) * 255 / 3; - // Convert 8 bit RGB332 color to internal RGB888. - newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3; // blue - newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x7) * 255 / 7; // green - newdata[i * 4 + 2] = ((data[index + i] >> 5) & 0x7) * 255 / 7; // red - newdata[i * 4 + 4] = 0; - } - data = newdata; - index = 0; - } - this._display.blitImage(this._FBU.x, cur_y, this._FBU.width, - curr_height, data, index); - this._sock.rQskipBytes(this._FBU.width * curr_height * pixelSize); - this._FBU.lines -= curr_height; - - if (this._FBU.lines > 0) { - this._FBU.bytes = this._FBU.width * pixelSize; // At least another line - } else { - this._FBU.rects--; - this._FBU.bytes = 0; - } - - return true; - }, - - COPYRECT: function () { - this._FBU.bytes = 4; - if (this._sock.rQwait("COPYRECT", 4)) { return false; } - this._display.copyImage(this._sock.rQshift16(), this._sock.rQshift16(), - this._FBU.x, this._FBU.y, this._FBU.width, - this._FBU.height); - - this._FBU.rects--; - this._FBU.bytes = 0; - return true; - }, - - RRE: function () { - var color; - if (this._FBU.subrects === 0) { - this._FBU.bytes = 4 + 4; - if (this._sock.rQwait("RRE", 4 + 4)) { return false; } - this._FBU.subrects = this._sock.rQshift32(); - color = this._sock.rQshiftBytes(4); // Background - this._display.fillRect(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, color); - } - - while (this._FBU.subrects > 0 && this._sock.rQlen() >= (4 + 8)) { - color = this._sock.rQshiftBytes(4); - var x = this._sock.rQshift16(); - var y = this._sock.rQshift16(); - var width = this._sock.rQshift16(); - var height = this._sock.rQshift16(); - this._display.fillRect(this._FBU.x + x, this._FBU.y + y, width, height, color); - this._FBU.subrects--; - } - - if (this._FBU.subrects > 0) { - var chunk = Math.min(this._rre_chunk_sz, this._FBU.subrects); - this._FBU.bytes = (4 + 8) * chunk; - } else { - this._FBU.rects--; - this._FBU.bytes = 0; - } - - return true; - }, - - HEXTILE: function () { - var rQ = this._sock.get_rQ(); - var rQi = this._sock.get_rQi(); - - if (this._FBU.tiles === 0) { - this._FBU.tiles_x = Math.ceil(this._FBU.width / 16); - this._FBU.tiles_y = Math.ceil(this._FBU.height / 16); - this._FBU.total_tiles = this._FBU.tiles_x * this._FBU.tiles_y; - this._FBU.tiles = this._FBU.total_tiles; - } - - while (this._FBU.tiles > 0) { - this._FBU.bytes = 1; - if (this._sock.rQwait("HEXTILE subencoding", this._FBU.bytes)) { return false; } - var subencoding = rQ[rQi]; // Peek - if (subencoding > 30) { // Raw - this._fail("Illegal hextile subencoding (subencoding: " + - subencoding + ")"); - return false; - } - - var subrects = 0; - var curr_tile = this._FBU.total_tiles - this._FBU.tiles; - var tile_x = curr_tile % this._FBU.tiles_x; - var tile_y = Math.floor(curr_tile / this._FBU.tiles_x); - var x = this._FBU.x + tile_x * 16; - var y = this._FBU.y + tile_y * 16; - var w = Math.min(16, (this._FBU.x + this._FBU.width) - x); - var h = Math.min(16, (this._FBU.y + this._FBU.height) - y); - - // Figure out how much we are expecting - if (subencoding & 0x01) { // Raw - this._FBU.bytes += w * h * 4; - } else { - if (subencoding & 0x02) { // Background - this._FBU.bytes += 4; - } - if (subencoding & 0x04) { // Foreground - this._FBU.bytes += 4; - } - if (subencoding & 0x08) { // AnySubrects - this._FBU.bytes++; // Since we aren't shifting it off - if (this._sock.rQwait("hextile subrects header", this._FBU.bytes)) { return false; } - subrects = rQ[rQi + this._FBU.bytes - 1]; // Peek - if (subencoding & 0x10) { // SubrectsColoured - this._FBU.bytes += subrects * (4 + 2); - } else { - this._FBU.bytes += subrects * 2; - } - } - } - - if (this._sock.rQwait("hextile", this._FBU.bytes)) { return false; } - - // We know the encoding and have a whole tile - this._FBU.subencoding = rQ[rQi]; - rQi++; - if (this._FBU.subencoding === 0) { - if (this._FBU.lastsubencoding & 0x01) { - // Weird: ignore blanks are RAW - Log.Debug(" Ignoring blank after RAW"); - } else { - this._display.fillRect(x, y, w, h, this._FBU.background); - } - } else if (this._FBU.subencoding & 0x01) { // Raw - this._display.blitImage(x, y, w, h, rQ, rQi); - rQi += this._FBU.bytes - 1; - } else { - if (this._FBU.subencoding & 0x02) { // Background - this._FBU.background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; - rQi += 4; - } - if (this._FBU.subencoding & 0x04) { // Foreground - this._FBU.foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; - rQi += 4; - } - - this._display.startTile(x, y, w, h, this._FBU.background); - if (this._FBU.subencoding & 0x08) { // AnySubrects - subrects = rQ[rQi]; - rQi++; - - for (var s = 0; s < subrects; s++) { - var color; - if (this._FBU.subencoding & 0x10) { // SubrectsColoured - color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; - rQi += 4; - } else { - color = this._FBU.foreground; - } - var xy = rQ[rQi]; - rQi++; - var sx = (xy >> 4); - var sy = (xy & 0x0f); - - var wh = rQ[rQi]; - rQi++; - var sw = (wh >> 4) + 1; - var sh = (wh & 0x0f) + 1; - - this._display.subTile(sx, sy, sw, sh, color); - } - } - this._display.finishTile(); - } - this._sock.set_rQi(rQi); - this._FBU.lastsubencoding = this._FBU.subencoding; - this._FBU.bytes = 0; - this._FBU.tiles--; - } - - if (this._FBU.tiles === 0) { - this._FBU.rects--; - } - - return true; - }, - - TIGHT: function () { - this._FBU.bytes = 1; // compression-control byte - if (this._sock.rQwait("TIGHT compression-control", this._FBU.bytes)) { return false; } - - var checksum = function (data) { - var sum = 0; - for (var i = 0; i < data.length; i++) { - sum += data[i]; - if (sum > 65536) sum -= 65536; - } - return sum; - }; - - var resetStreams = 0; - var streamId = -1; - var decompress = function (data, expected) { - for (var i = 0; i < 4; i++) { - if ((resetStreams >> i) & 1) { - this._FBU.zlibs[i].reset(); - Log.Info("Reset zlib stream " + i); - } - } - - //var uncompressed = this._FBU.zlibs[streamId].uncompress(data, 0); - var uncompressed = this._FBU.zlibs[streamId].inflate(data, true, expected); - /*if (uncompressed.status !== 0) { - Log.Error("Invalid data in zlib stream"); - }*/ - - //return uncompressed.data; - return uncompressed; - }.bind(this); - - var indexedToRGBX2Color = function (data, palette, width, height) { - // Convert indexed (palette based) image data to RGB - // TODO: reduce number of calculations inside loop - var dest = this._destBuff; - var w = Math.floor((width + 7) / 8); - var w1 = Math.floor(width / 8); - - /*for (var y = 0; y < height; y++) { - var b, x, dp, sp; - var yoffset = y * width; - var ybitoffset = y * w; - var xoffset, targetbyte; - for (x = 0; x < w1; x++) { - xoffset = yoffset + x * 8; - targetbyte = data[ybitoffset + x]; - for (b = 7; b >= 0; b--) { - dp = (xoffset + 7 - b) * 3; - sp = (targetbyte >> b & 1) * 3; - dest[dp] = palette[sp]; - dest[dp + 1] = palette[sp + 1]; - dest[dp + 2] = palette[sp + 2]; - } - } - - xoffset = yoffset + x * 8; - targetbyte = data[ybitoffset + x]; - for (b = 7; b >= 8 - width % 8; b--) { - dp = (xoffset + 7 - b) * 3; - sp = (targetbyte >> b & 1) * 3; - dest[dp] = palette[sp]; - dest[dp + 1] = palette[sp + 1]; - dest[dp + 2] = palette[sp + 2]; - } - }*/ - - for (var y = 0; y < height; y++) { - var b, x, dp, sp; - for (x = 0; x < w1; x++) { - for (b = 7; b >= 0; b--) { - dp = (y * width + x * 8 + 7 - b) * 4; - sp = (data[y * w + x] >> b & 1) * 3; - dest[dp] = palette[sp]; - dest[dp + 1] = palette[sp + 1]; - dest[dp + 2] = palette[sp + 2]; - dest[dp + 3] = 255; - } - } - - for (b = 7; b >= 8 - width % 8; b--) { - dp = (y * width + x * 8 + 7 - b) * 4; - sp = (data[y * w + x] >> b & 1) * 3; - dest[dp] = palette[sp]; - dest[dp + 1] = palette[sp + 1]; - dest[dp + 2] = palette[sp + 2]; - dest[dp + 3] = 255; - } - } - - return dest; - }.bind(this); - - var indexedToRGBX = function (data, palette, width, height) { - // Convert indexed (palette based) image data to RGB - var dest = this._destBuff; - var total = width * height * 4; - for (var i = 0, j = 0; i < total; i += 4, j++) { - var sp = data[j] * 3; - dest[i] = palette[sp]; - dest[i + 1] = palette[sp + 1]; - dest[i + 2] = palette[sp + 2]; - dest[i + 3] = 255; - } - - return dest; - }.bind(this); - - var rQi = this._sock.get_rQi(); - var rQ = this._sock.rQwhole(); - var cmode, data; - var cl_header, cl_data; - - var handlePalette = function () { - var numColors = rQ[rQi + 2] + 1; - var paletteSize = numColors * 3; - this._FBU.bytes += paletteSize; - if (this._sock.rQwait("TIGHT palette " + cmode, this._FBU.bytes)) { return false; } - - var bpp = (numColors <= 2) ? 1 : 8; - var rowSize = Math.floor((this._FBU.width * bpp + 7) / 8); - var raw = false; - if (rowSize * this._FBU.height < 12) { - raw = true; - cl_header = 0; - cl_data = rowSize * this._FBU.height; - //clength = [0, rowSize * this._FBU.height]; - } else { - // begin inline getTightCLength (returning two-item arrays is bad for performance with GC) - var cl_offset = rQi + 3 + paletteSize; - cl_header = 1; - cl_data = 0; - cl_data += rQ[cl_offset] & 0x7f; - if (rQ[cl_offset] & 0x80) { - cl_header++; - cl_data += (rQ[cl_offset + 1] & 0x7f) << 7; - if (rQ[cl_offset + 1] & 0x80) { - cl_header++; - cl_data += rQ[cl_offset + 2] << 14; - } - } - // end inline getTightCLength - } - - this._FBU.bytes += cl_header + cl_data; - if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) { return false; } - - // Shift ctl, filter id, num colors, palette entries, and clength off - this._sock.rQskipBytes(3); - //var palette = this._sock.rQshiftBytes(paletteSize); - this._sock.rQshiftTo(this._paletteBuff, paletteSize); - this._sock.rQskipBytes(cl_header); - - if (raw) { - data = this._sock.rQshiftBytes(cl_data); - } else { - data = decompress(this._sock.rQshiftBytes(cl_data), rowSize * this._FBU.height); - } - - // Convert indexed (palette based) image data to RGB - var rgbx; - if (numColors == 2) { - rgbx = indexedToRGBX2Color(data, this._paletteBuff, this._FBU.width, this._FBU.height); - this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0, false); - } else { - rgbx = indexedToRGBX(data, this._paletteBuff, this._FBU.width, this._FBU.height); - this._display.blitRgbxImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, rgbx, 0, false); - } - - - return true; - }.bind(this); - - var handleCopy = function () { - var raw = false; - var uncompressedSize = this._FBU.width * this._FBU.height * 3; - if (uncompressedSize < 12) { - raw = true; - cl_header = 0; - cl_data = uncompressedSize; - } else { - // begin inline getTightCLength (returning two-item arrays is for peformance with GC) - var cl_offset = rQi + 1; - cl_header = 1; - cl_data = 0; - cl_data += rQ[cl_offset] & 0x7f; - if (rQ[cl_offset] & 0x80) { - cl_header++; - cl_data += (rQ[cl_offset + 1] & 0x7f) << 7; - if (rQ[cl_offset + 1] & 0x80) { - cl_header++; - cl_data += rQ[cl_offset + 2] << 14; - } - } - // end inline getTightCLength - } - this._FBU.bytes = 1 + cl_header + cl_data; - if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) { return false; } - - // Shift ctl, clength off - this._sock.rQshiftBytes(1 + cl_header); - - if (raw) { - data = this._sock.rQshiftBytes(cl_data); - } else { - data = decompress(this._sock.rQshiftBytes(cl_data), uncompressedSize); - } - - this._display.blitRgbImage(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, data, 0, false); - - return true; - }.bind(this); - - var ctl = this._sock.rQpeek8(); - - // Keep tight reset bits - resetStreams = ctl & 0xF; - - // Figure out filter - ctl = ctl >> 4; - streamId = ctl & 0x3; - - if (ctl === 0x08) cmode = "fill"; - else if (ctl === 0x09) cmode = "jpeg"; - else if (ctl === 0x0A) cmode = "png"; - else if (ctl & 0x04) cmode = "filter"; - else if (ctl < 0x04) cmode = "copy"; - else return this._fail("Illegal tight compression received (ctl: " + - ctl + ")"); - - switch (cmode) { - // fill use depth because TPIXELs drop the padding byte - case "fill": // TPIXEL - this._FBU.bytes += 3; - break; - case "jpeg": // max clength - this._FBU.bytes += 3; - break; - case "png": // max clength - this._FBU.bytes += 3; - break; - case "filter": // filter id + num colors if palette - this._FBU.bytes += 2; - break; - case "copy": - break; - } - - if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) { return false; } - - // Determine FBU.bytes - switch (cmode) { - case "fill": - // skip ctl byte - this._display.fillRect(this._FBU.x, this._FBU.y, this._FBU.width, this._FBU.height, [rQ[rQi + 3], rQ[rQi + 2], rQ[rQi + 1]], false); - this._sock.rQskipBytes(4); - break; - case "png": - case "jpeg": - // begin inline getTightCLength (returning two-item arrays is for peformance with GC) - var cl_offset = rQi + 1; - cl_header = 1; - cl_data = 0; - cl_data += rQ[cl_offset] & 0x7f; - if (rQ[cl_offset] & 0x80) { - cl_header++; - cl_data += (rQ[cl_offset + 1] & 0x7f) << 7; - if (rQ[cl_offset + 1] & 0x80) { - cl_header++; - cl_data += rQ[cl_offset + 2] << 14; - } - } - // end inline getTightCLength - this._FBU.bytes = 1 + cl_header + cl_data; // ctl + clength size + jpeg-data - if (this._sock.rQwait("TIGHT " + cmode, this._FBU.bytes)) { return false; } - - // We have everything, render it - this._sock.rQskipBytes(1 + cl_header); // shift off clt + compact length - data = this._sock.rQshiftBytes(cl_data); - this._display.imageRect(this._FBU.x, this._FBU.y, "image/" + cmode, data); - break; - case "filter": - var filterId = rQ[rQi + 1]; - if (filterId === 1) { - if (!handlePalette()) { return false; } - } else { - // Filter 0, Copy could be valid here, but servers don't send it as an explicit filter - // Filter 2, Gradient is valid but not use if jpeg is enabled - this._fail("Unsupported tight subencoding received " + - "(filter: " + filterId + ")"); - } - break; - case "copy": - if (!handleCopy()) { return false; } - break; - } - - - this._FBU.bytes = 0; - this._FBU.rects--; - - return true; - }, - - last_rect: function () { - this._FBU.rects = 0; - return true; - }, - - ExtendedDesktopSize: function () { - this._FBU.bytes = 1; - if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) { return false; } - - var firstUpdate = !this._supportsSetDesktopSize; - this._supportsSetDesktopSize = true; - - // Normally we only apply the current resize mode after a - // window resize event. However there is no such trigger on the - // initial connect. And we don't know if the server supports - // resizing until we've gotten here. - if (firstUpdate) { - this._requestRemoteResize(); - } - - var number_of_screens = this._sock.rQpeek8(); - - this._FBU.bytes = 4 + (number_of_screens * 16); - if (this._sock.rQwait("ExtendedDesktopSize", this._FBU.bytes)) { return false; } - - this._sock.rQskipBytes(1); // number-of-screens - this._sock.rQskipBytes(3); // padding - - for (var i = 0; i < number_of_screens; i += 1) { - // Save the id and flags of the first screen - if (i === 0) { - this._screen_id = this._sock.rQshiftBytes(4); // id - this._sock.rQskipBytes(2); // x-position - this._sock.rQskipBytes(2); // y-position - this._sock.rQskipBytes(2); // width - this._sock.rQskipBytes(2); // height - this._screen_flags = this._sock.rQshiftBytes(4); // flags - } else { - this._sock.rQskipBytes(16); - } - } - - /* - * The x-position indicates the reason for the change: - * - * 0 - server resized on its own - * 1 - this client requested the resize - * 2 - another client requested the resize - */ - - // We need to handle errors when we requested the resize. - if (this._FBU.x === 1 && this._FBU.y !== 0) { - var msg = ""; - // The y-position indicates the status code from the server - switch (this._FBU.y) { - case 1: - msg = "Resize is administratively prohibited"; - break; - case 2: - msg = "Out of resources"; - break; - case 3: - msg = "Invalid screen layout"; - break; - default: - msg = "Unknown reason"; - break; - } - Log.Warn("Server did not accept the resize request: " - + msg); - } else { - this._resize(this._FBU.width, this._FBU.height); - } - - this._FBU.bytes = 0; - this._FBU.rects -= 1; - return true; - }, - - DesktopSize: function () { - this._resize(this._FBU.width, this._FBU.height); - this._FBU.bytes = 0; - this._FBU.rects -= 1; - return true; - }, - - Cursor: function () { - Log.Debug(">> set_cursor"); - var x = this._FBU.x; // hotspot-x - var y = this._FBU.y; // hotspot-y - var w = this._FBU.width; - var h = this._FBU.height; - - var pixelslength = w * h * 4; - var masklength = Math.floor((w + 7) / 8) * h; - - this._FBU.bytes = pixelslength + masklength; - if (this._sock.rQwait("cursor encoding", this._FBU.bytes)) { return false; } - - this._display.changeCursor(this._sock.rQshiftBytes(pixelslength), - this._sock.rQshiftBytes(masklength), - x, y, w, h); - - this._FBU.bytes = 0; - this._FBU.rects--; - - Log.Debug("<< set_cursor"); - return true; - }, - - QEMUExtendedKeyEvent: function () { - this._FBU.rects--; - - // Old Safari doesn't support creating keyboard events - try { - var keyboardEvent = document.createEvent("keyboardEvent"); - if (keyboardEvent.code !== undefined) { - this._qemuExtKeyEventSupported = true; - } - } catch (err) { - } - }, -}; diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/util/browser.js.gz Binary file image/w/core/util/browser.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/util/events.js.gz Binary file image/w/core/util/events.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/util/eventtarget.js.gz Binary file image/w/core/util/eventtarget.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/util/logging.js.gz Binary file image/w/core/util/logging.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/util/polyfill.js.gz Binary file image/w/core/util/polyfill.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/util/strings.js.gz Binary file image/w/core/util/strings.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/core/websock.js.gz Binary file image/w/core/websock.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/index.html.gz Binary file image/w/index.html.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/modl/babel.js.gz Binary file image/w/js/modl/babel.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/modl/brloader.js.gz Binary file image/w/js/modl/brloader.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/utils/common.js.gz Binary file image/w/js/utils/common.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/adler32.js.gz Binary file image/w/js/zlib/adler32.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/constants.js.gz Binary file image/w/js/zlib/constants.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/crc32.js.gz Binary file image/w/js/zlib/crc32.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/deflate.js.gz Binary file image/w/js/zlib/deflate.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/gzheader.js.gz Binary file image/w/js/zlib/gzheader.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/inffast.js.gz Binary file image/w/js/zlib/inffast.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/inflate.js.gz Binary file image/w/js/zlib/inflate.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/inftrees.js.gz Binary file image/w/js/zlib/inftrees.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/messages.js.gz Binary file image/w/js/zlib/messages.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/trees.js.gz Binary file image/w/js/zlib/trees.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/js/zlib/zstream.js.gz Binary file image/w/js/zlib/zstream.js.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 image/w/vnc.html.gz Binary file image/w/vnc.html.gz has changed diff -r 1b82a6d50a39 -r 537ffe280775 main/brewboard.c --- a/main/brewboard.c Thu May 02 11:57:07 2019 +0200 +++ b/main/brewboard.c Thu May 02 17:12:06 2019 +0200 @@ -148,7 +148,7 @@ SoundPlay(SOUND_StartUp); /* Do not write to the TFT during VNC startup to avoid race conditions */ - VncStartup(); +// VncStartup(); start_http_websocket(); vTaskDelay(1000 / portTICK_PERIOD_MS); Main_Screen = MAIN_MODE_FREE; diff -r 1b82a6d50a39 -r 537ffe280775 main/buttons.c --- a/main/buttons.c Thu May 02 11:57:07 2019 +0200 +++ b/main/buttons.c Thu May 02 17:12:06 2019 +0200 @@ -9,10 +9,6 @@ sButton Buttons[MAXBUTTONS]; ///< 40 buttons on a screen. int level = 1; ///< Keyboard level. -extern uint8_t VNC_pointer_button; ///< Mouse buttons mask -extern uint16_t VNC_pointer_x; ///< Mouse coordinate X -extern uint16_t VNC_pointer_y; ///< Mouse coordinate Y - const char *mashTypes[] = { "Infusion", "Temperature", "Decoction" }; const char *SSR2Types[] = { "Uit", "HLT of MLT", "HLT en MLT", "Idle" }; @@ -138,12 +134,7 @@ return rc; } - if (VNC_pointer_button & 0x07) { - v_pressed = true; - vx = VNC_pointer_x; - vy = VNC_pointer_y; - return -1; - } else if (v_pressed) { + if (v_pressed) { rc = Buttons_Search(vx, vy); v_pressed = false; vx = vy = -1; diff -r 1b82a6d50a39 -r 537ffe280775 main/config.h --- a/main/config.h Thu May 02 11:57:07 2019 +0200 +++ b/main/config.h Thu May 02 17:12:06 2019 +0200 @@ -59,7 +59,6 @@ #include "tftspi.h" #include "tft.h" #include "PID_v1.h" -#include "vnc-server.h" #include "websocket_server.h" #include "buttons.h" diff -r 1b82a6d50a39 -r 537ffe280775 main/task_http.c --- a/main/task_http.c Thu May 02 11:57:07 2019 +0200 +++ b/main/task_http.c Thu May 02 17:12:06 2019 +0200 @@ -210,37 +210,6 @@ /** - * @brief Handle VNC websocket events. - */ -void websockify_callback(uint8_t num, WEBSOCKET_TYPE_t type, char* msg, uint64_t len) -{ - switch(type) { - case WEBSOCKET_DISCONNECT_EXTERNAL: - VncStopWS(num); - break; - - case WEBSOCKET_DISCONNECT_INTERNAL: - ESP_LOGI(TAG,"Websockify client %i was disconnected",num); - VncStopWS(num); - break; - - case WEBSOCKET_DISCONNECT_ERROR: - ESP_LOGI(TAG,"Websockify client %i was disconnected due to an error",num); - VncStopWS(num); - break; - - case WEBSOCKET_BIN: - VncGetWSmessage(msg, len); - //dump_buf(msg, len); - break; - - default: break; - } -} - - - -/** * @brief Handle web ui websocket events. */ void websock_callback(uint8_t num, WEBSOCKET_TYPE_t type, char* msg, uint64_t len) @@ -419,15 +388,6 @@ return; } - // websocket for noVNC. - if ((strstr(buf,"GET /websockify ") && strstr(buf,"Upgrade: websocket"))) { - int nr = ws_server_add_client_protocol(conn, buf, buflen, "/websockify", "binary", websockify_callback); - ESP_LOGI(TAG, "%s new websocket on /websockify client: %d", ipstr, nr); - netbuf_delete(inbuf); - VncStartWS(nr); - return; - } - // websocket for web UI. if ((strstr(buf,"GET /ws ") && strstr(buf,"Upgrade: websocket"))) { int nr = ws_server_add_client_protocol(conn, buf, buflen, "/ws", "binary", websock_callback); diff -r 1b82a6d50a39 -r 537ffe280775 main/task_sound.c --- a/main/task_sound.c Thu May 02 11:57:07 2019 +0200 +++ b/main/task_sound.c Thu May 02 17:12:06 2019 +0200 @@ -104,14 +104,11 @@ xEventGroupClearBits(xEventGroupSound, SOUND_STARTUP); } if (uxBits & SOUND_PROMPT) { - VncSoundBell(); BuzzerPlay(_sound_Prompt); xEventGroupClearBits(xEventGroupSound, SOUND_PROMPT); } if (uxBits & SOUND_TEMPREACHED) { - VncSoundBell(); BuzzerPlay(_sound_TempReached); - VncSoundBell(); xEventGroupClearBits(xEventGroupSound, SOUND_TEMPREACHED); } if (uxBits & SOUND_TIMEOUT) { @@ -119,11 +116,7 @@ xEventGroupClearBits(xEventGroupSound, SOUND_TIMEOUT); } if (uxBits & SOUND_ADDHOP) { - VncSoundBell(); - VncSoundBell(); BuzzerPlay(_sound_AddHop); - VncSoundBell(); - VncSoundBell(); xEventGroupClearBits(xEventGroupSound, SOUND_ADDHOP); } if (uxBits & SOUND_END) { @@ -131,7 +124,6 @@ xEventGroupClearBits(xEventGroupSound, SOUND_END); } if (uxBits & SOUND_WARN) { - VncSoundBell(); BuzzerPlay(_sound_Warn); xEventGroupClearBits(xEventGroupSound, SOUND_WARN); } diff -r 1b82a6d50a39 -r 537ffe280775 sdkconfig --- a/sdkconfig Thu May 02 11:57:07 2019 +0200 +++ b/sdkconfig Thu May 02 17:12:06 2019 +0200 @@ -498,9 +498,6 @@ # CONFIG_SUPPORT_TERMIOS is not set CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 -CONFIG_VNC_SERVER_PORT=5900 -CONFIG_VNC_SERVER_FRAME_WIDTH=320 -CONFIG_VNC_SERVER_FRAME_HEIGHT=240 # CONFIG_WL_SECTOR_SIZE_512 is not set CONFIG_WL_SECTOR_SIZE_4096=y CONFIG_WL_SECTOR_SIZE=4096