]> git.proxmox.com Git - mirror_novnc.git/blob - core/decoders/hextile.js
Standardize on camelCase in Decoders
[mirror_novnc.git] / core / decoders / hextile.js
1 /*
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2019 The noVNC Authors
4 * Licensed under MPL 2.0 (see LICENSE.txt)
5 *
6 * See README.md for usage and integration instructions.
7 *
8 */
9
10 import * as Log from '../util/logging.js';
11
12 export default class HextileDecoder {
13 constructor() {
14 this._tiles = 0;
15 this._lastsubencoding = 0;
16 }
17
18 decodeRect(x, y, width, height, sock, display, depth) {
19 if (this._tiles === 0) {
20 this._tilesX = Math.ceil(width / 16);
21 this._tilesY = Math.ceil(height / 16);
22 this._totalTiles = this._tilesX * this._tilesY;
23 this._tiles = this._totalTiles;
24 }
25
26 while (this._tiles > 0) {
27 let bytes = 1;
28
29 if (sock.rQwait("HEXTILE", bytes)) {
30 return false;
31 }
32
33 let rQ = sock.rQ;
34 let rQi = sock.rQi;
35
36 let subencoding = rQ[rQi]; // Peek
37 if (subencoding > 30) { // Raw
38 throw new Error("Illegal hextile subencoding (subencoding: " +
39 subencoding + ")");
40 }
41
42 const currTile = this._totalTiles - this._tiles;
43 const tileX = currTile % this._tilesX;
44 const tileY = Math.floor(currTile / this._tilesX);
45 const tx = x + tileX * 16;
46 const ty = y + tileY * 16;
47 const tw = Math.min(16, (x + width) - tx);
48 const th = Math.min(16, (y + height) - ty);
49
50 // Figure out how much we are expecting
51 if (subencoding & 0x01) { // Raw
52 bytes += tw * th * 4;
53 } else {
54 if (subencoding & 0x02) { // Background
55 bytes += 4;
56 }
57 if (subencoding & 0x04) { // Foreground
58 bytes += 4;
59 }
60 if (subencoding & 0x08) { // AnySubrects
61 bytes++; // Since we aren't shifting it off
62
63 if (sock.rQwait("HEXTILE", bytes)) {
64 return false;
65 }
66
67 let subrects = rQ[rQi + bytes - 1]; // Peek
68 if (subencoding & 0x10) { // SubrectsColoured
69 bytes += subrects * (4 + 2);
70 } else {
71 bytes += subrects * 2;
72 }
73 }
74 }
75
76 if (sock.rQwait("HEXTILE", bytes)) {
77 return false;
78 }
79
80 // We know the encoding and have a whole tile
81 rQi++;
82 if (subencoding === 0) {
83 if (this._lastsubencoding & 0x01) {
84 // Weird: ignore blanks are RAW
85 Log.Debug(" Ignoring blank after RAW");
86 } else {
87 display.fillRect(tx, ty, tw, th, this._background);
88 }
89 } else if (subencoding & 0x01) { // Raw
90 display.blitImage(tx, ty, tw, th, rQ, rQi);
91 rQi += bytes - 1;
92 } else {
93 if (subencoding & 0x02) { // Background
94 this._background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
95 rQi += 4;
96 }
97 if (subencoding & 0x04) { // Foreground
98 this._foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
99 rQi += 4;
100 }
101
102 display.startTile(tx, ty, tw, th, this._background);
103 if (subencoding & 0x08) { // AnySubrects
104 let subrects = rQ[rQi];
105 rQi++;
106
107 for (let s = 0; s < subrects; s++) {
108 let color;
109 if (subencoding & 0x10) { // SubrectsColoured
110 color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]];
111 rQi += 4;
112 } else {
113 color = this._foreground;
114 }
115 const xy = rQ[rQi];
116 rQi++;
117 const sx = (xy >> 4);
118 const sy = (xy & 0x0f);
119
120 const wh = rQ[rQi];
121 rQi++;
122 const sw = (wh >> 4) + 1;
123 const sh = (wh & 0x0f) + 1;
124
125 display.subTile(sx, sy, sw, sh, color);
126 }
127 }
128 display.finishTile();
129 }
130 sock.rQi = rQi;
131 this._lastsubencoding = subencoding;
132 this._tiles--;
133 }
134
135 return true;
136 }
137 }