/*
* noVNC: HTML5 VNC client
- * Copyright (C) 2012 Joel Martin
- * Copyright (C) 2018 Samuel Mannehed for Cendio AB
- * Copyright (C) 2018 Pierre Ossman for Cendio AB
+ * Copyright (C) 2019 The noVNC Authors
* Licensed under MPL 2.0 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
constructor() {
this._tiles = 0;
this._lastsubencoding = 0;
+ this._tileBuffer = new Uint8Array(16 * 16 * 4);
}
decodeRect(x, y, width, height, sock, display, depth) {
if (this._tiles === 0) {
- this._tiles_x = Math.ceil(width / 16);
- this._tiles_y = Math.ceil(height / 16);
- this._total_tiles = this._tiles_x * this._tiles_y;
- this._tiles = this._total_tiles;
+ this._tilesX = Math.ceil(width / 16);
+ this._tilesY = Math.ceil(height / 16);
+ this._totalTiles = this._tilesX * this._tilesY;
+ this._tiles = this._totalTiles;
}
while (this._tiles > 0) {
return false;
}
- let rQ = sock.get_rQ();
- let rQi = sock.get_rQi();
+ let rQ = sock.rQ;
+ let rQi = sock.rQi;
let subencoding = rQ[rQi]; // Peek
if (subencoding > 30) { // Raw
- throw Error("Illegal hextile subencoding (subencoding: " +
+ throw new Error("Illegal hextile subencoding (subencoding: " +
subencoding + ")");
}
- const curr_tile = this._total_tiles - this._tiles;
- const tile_x = curr_tile % this._tiles_x;
- const tile_y = Math.floor(curr_tile / this._tiles_x);
- const tx = x + tile_x * 16;
- const ty = y + tile_y * 16;
+ const currTile = this._totalTiles - this._tiles;
+ const tileX = currTile % this._tilesX;
+ const tileY = Math.floor(currTile / this._tilesX);
+ const tx = x + tileX * 16;
+ const ty = y + tileY * 16;
const tw = Math.min(16, (x + width) - tx);
const th = Math.min(16, (y + height) - ty);
rQi += 4;
}
- display.startTile(tx, ty, tw, th, this._background);
+ this._startTile(tx, ty, tw, th, this._background);
if (subencoding & 0x08) { // AnySubrects
let subrects = rQ[rQi];
rQi++;
const sw = (wh >> 4) + 1;
const sh = (wh & 0x0f) + 1;
- display.subTile(sx, sy, sw, sh, color);
+ this._subTile(sx, sy, sw, sh, color);
}
}
- display.finishTile();
+ this._finishTile(display);
}
- sock.set_rQi(rQi);
+ sock.rQi = rQi;
this._lastsubencoding = subencoding;
this._tiles--;
}
return true;
}
+
+ // start updating a tile
+ _startTile(x, y, width, height, color) {
+ this._tileX = x;
+ this._tileY = y;
+ this._tileW = width;
+ this._tileH = height;
+
+ const red = color[2];
+ const green = color[1];
+ const blue = color[0];
+
+ const data = this._tileBuffer;
+ for (let i = 0; i < width * height * 4; i += 4) {
+ data[i] = blue;
+ data[i + 1] = green;
+ data[i + 2] = red;
+ data[i + 3] = 255;
+ }
+ }
+
+ // update sub-rectangle of the current tile
+ _subTile(x, y, w, h, color) {
+ const red = color[2];
+ const green = color[1];
+ const blue = color[0];
+ const xend = x + w;
+ const yend = y + h;
+
+ const data = this._tileBuffer;
+ const width = this._tileW;
+ for (let j = y; j < yend; j++) {
+ for (let i = x; i < xend; i++) {
+ const p = (i + (j * width)) * 4;
+ data[p] = blue;
+ data[p + 1] = green;
+ data[p + 2] = red;
+ data[p + 3] = 255;
+ }
+ }
+ }
+
+ // draw the current tile to the screen
+ _finishTile(display) {
+ display.blitImage(this._tileX, this._tileY,
+ this._tileW, this._tileH,
+ this._tileBuffer, 0);
+ }
}