Removed the noVNC code and web pages. novnc

Thu, 02 May 2019 17:12:06 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 02 May 2019 17:12:06 +0200
branch
novnc
changeset 38
537ffe280775
parent 37
1b82a6d50a39
child 39
e5900c9b9a7b

Removed the noVNC code and web pages.

Makefile file | annotate | diff | comparison | revisions
components/tft/tft.c file | annotate | diff | comparison | revisions
components/vnc_server/Kconfig file | annotate | diff | comparison | revisions
components/vnc_server/component.mk file | annotate | diff | comparison | revisions
components/vnc_server/vnc-server.c file | annotate | diff | comparison | revisions
components/vnc_server/vnc-server.h file | annotate | diff | comparison | revisions
image/files.list file | annotate | diff | comparison | revisions
image/version.txt file | annotate | diff | comparison | revisions
image/w/app/error-handler.js.gz file | annotate | diff | comparison | revisions
image/w/app/images/clipboard.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/connect.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/disconnect.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/drag.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/error.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/expander.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/fullscreen.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/handle.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/handle_bg.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/info.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/mouse_left.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/mouse_middle.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/mouse_none.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/mouse_right.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/settings.svg.gz file | annotate | diff | comparison | revisions
image/w/app/images/warning.svg.gz file | annotate | diff | comparison | revisions
image/w/app/locale/de.json file | annotate | diff | comparison | revisions
image/w/app/locale/el.json file | annotate | diff | comparison | revisions
image/w/app/locale/es.json file | annotate | diff | comparison | revisions
image/w/app/locale/nl.json file | annotate | diff | comparison | revisions
image/w/app/locale/pl.json file | annotate | diff | comparison | revisions
image/w/app/locale/sv.json file | annotate | diff | comparison | revisions
image/w/app/locale/tr.json file | annotate | diff | comparison | revisions
image/w/app/locale/zh.json file | annotate | diff | comparison | revisions
image/w/app/localization.js.gz file | annotate | diff | comparison | revisions
image/w/app/sounds/bell.mp3 file | annotate | diff | comparison | revisions
image/w/app/sounds/bell.oga file | annotate | diff | comparison | revisions
image/w/app/styles/base.css file | annotate | diff | comparison | revisions
image/w/app/ui.js.gz file | annotate | diff | comparison | revisions
image/w/app/webutil.js.gz file | annotate | diff | comparison | revisions
image/w/core/base64.js.gz file | annotate | diff | comparison | revisions
image/w/core/des.js.gz file | annotate | diff | comparison | revisions
image/w/core/display.js.gz file | annotate | diff | comparison | revisions
image/w/core/encodings.js.gz file | annotate | diff | comparison | revisions
image/w/core/inflator.js.gz file | annotate | diff | comparison | revisions
image/w/core/input/mouse.js.gz file | annotate | diff | comparison | revisions
image/w/core/rfb.js.gz file | annotate | diff | comparison | revisions
image/w/core/rfb.js.orig file | annotate | diff | comparison | revisions
image/w/core/util/browser.js.gz file | annotate | diff | comparison | revisions
image/w/core/util/events.js.gz file | annotate | diff | comparison | revisions
image/w/core/util/eventtarget.js.gz file | annotate | diff | comparison | revisions
image/w/core/util/logging.js.gz file | annotate | diff | comparison | revisions
image/w/core/util/polyfill.js.gz file | annotate | diff | comparison | revisions
image/w/core/util/strings.js.gz file | annotate | diff | comparison | revisions
image/w/core/websock.js.gz file | annotate | diff | comparison | revisions
image/w/index.html.gz file | annotate | diff | comparison | revisions
image/w/js/modl/babel.js.gz file | annotate | diff | comparison | revisions
image/w/js/modl/brloader.js.gz file | annotate | diff | comparison | revisions
image/w/js/utils/common.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/adler32.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/constants.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/crc32.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/deflate.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/gzheader.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/inffast.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/inflate.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/inftrees.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/messages.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/trees.js.gz file | annotate | diff | comparison | revisions
image/w/js/zlib/zstream.js.gz file | annotate | diff | comparison | revisions
image/w/vnc.html.gz file | annotate | diff | comparison | revisions
main/brewboard.c file | annotate | diff | comparison | revisions
main/buttons.c file | annotate | diff | comparison | revisions
main/config.h file | annotate | diff | comparison | revisions
main/task_http.c file | annotate | diff | comparison | revisions
main/task_sound.c file | annotate | diff | comparison | revisions
sdkconfig file | annotate | diff | comparison | revisions
--- 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
--- 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 <math.h>
-#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;
 		    }
--- 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
--- 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 := .
--- 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 <cgarry@sweeneydesign.co.uk>
- * @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");
-    }
-}
-
--- 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 <cgarry@sweeneydesign.co.uk>
- * @author Michiel Broek.
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <sys/unistd.h>
-#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);
-
--- 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
--- 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
Binary file image/w/app/error-handler.js.gz has changed
Binary file image/w/app/images/clipboard.svg.gz has changed
Binary file image/w/app/images/connect.svg.gz has changed
Binary file image/w/app/images/disconnect.svg.gz has changed
Binary file image/w/app/images/drag.svg.gz has changed
Binary file image/w/app/images/error.svg.gz has changed
Binary file image/w/app/images/expander.svg.gz has changed
Binary file image/w/app/images/fullscreen.svg.gz has changed
Binary file image/w/app/images/handle.svg.gz has changed
Binary file image/w/app/images/handle_bg.svg.gz has changed
Binary file image/w/app/images/info.svg.gz has changed
Binary file image/w/app/images/mouse_left.svg.gz has changed
Binary file image/w/app/images/mouse_middle.svg.gz has changed
Binary file image/w/app/images/mouse_none.svg.gz has changed
Binary file image/w/app/images/mouse_right.svg.gz has changed
Binary file image/w/app/images/settings.svg.gz has changed
Binary file image/w/app/images/warning.svg.gz has changed
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
Binary file image/w/app/localization.js.gz has changed
Binary file image/w/app/sounds/bell.mp3 has changed
Binary file image/w/app/sounds/bell.oga has changed
--- 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;
-  }
-}
Binary file image/w/app/ui.js.gz has changed
Binary file image/w/app/webutil.js.gz has changed
Binary file image/w/core/base64.js.gz has changed
Binary file image/w/core/des.js.gz has changed
Binary file image/w/core/display.js.gz has changed
Binary file image/w/core/encodings.js.gz has changed
Binary file image/w/core/inflator.js.gz has changed
Binary file image/w/core/input/mouse.js.gz has changed
Binary file image/w/core/rfb.js.gz has changed
--- 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) {
-        }
-    },
-};
Binary file image/w/core/util/browser.js.gz has changed
Binary file image/w/core/util/events.js.gz has changed
Binary file image/w/core/util/eventtarget.js.gz has changed
Binary file image/w/core/util/logging.js.gz has changed
Binary file image/w/core/util/polyfill.js.gz has changed
Binary file image/w/core/util/strings.js.gz has changed
Binary file image/w/core/websock.js.gz has changed
Binary file image/w/index.html.gz has changed
Binary file image/w/js/modl/babel.js.gz has changed
Binary file image/w/js/modl/brloader.js.gz has changed
Binary file image/w/js/utils/common.js.gz has changed
Binary file image/w/js/zlib/adler32.js.gz has changed
Binary file image/w/js/zlib/constants.js.gz has changed
Binary file image/w/js/zlib/crc32.js.gz has changed
Binary file image/w/js/zlib/deflate.js.gz has changed
Binary file image/w/js/zlib/gzheader.js.gz has changed
Binary file image/w/js/zlib/inffast.js.gz has changed
Binary file image/w/js/zlib/inflate.js.gz has changed
Binary file image/w/js/zlib/inftrees.js.gz has changed
Binary file image/w/js/zlib/messages.js.gz has changed
Binary file image/w/js/zlib/trees.js.gz has changed
Binary file image/w/js/zlib/zstream.js.gz has changed
Binary file image/w/vnc.html.gz has changed
--- 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;
--- 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;
--- 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"
--- 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);
--- 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);
 	}
--- 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

mercurial