@novnc/novnc 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTHORS +13 -0
- package/LICENSE.txt +2 -1
- package/README.md +69 -3
- package/core/base64.js +35 -41
- package/core/decoders/copyrect.js +22 -0
- package/core/decoders/hextile.js +137 -0
- package/core/decoders/raw.js +56 -0
- package/core/decoders/rre.js +44 -0
- package/core/decoders/tight.js +315 -0
- package/core/decoders/tightpng.js +27 -0
- package/core/deflator.js +85 -0
- package/core/des.js +90 -95
- package/core/display.js +254 -297
- package/core/encodings.js +7 -3
- package/core/inflator.js +48 -20
- package/core/input/domkeytable.js +21 -24
- package/core/input/fixedkeys.js +3 -1
- package/core/input/gesturehandler.js +567 -0
- package/core/input/keyboard.js +194 -120
- package/core/input/keysym.js +2 -0
- package/core/input/keysymdef.js +3 -3
- package/core/input/util.js +53 -12
- package/core/input/vkeys.js +2 -1
- package/core/rfb.js +1937 -1496
- package/core/util/browser.js +80 -29
- package/core/util/cursor.js +253 -0
- package/core/util/element.js +32 -0
- package/core/util/events.js +59 -55
- package/core/util/eventtarget.js +25 -30
- package/core/util/int.js +15 -0
- package/core/util/logging.js +21 -16
- package/core/util/polyfill.js +15 -8
- package/core/util/strings.js +21 -8
- package/core/websock.js +145 -167
- package/docs/API.md +31 -10
- package/lib/base64.js +115 -0
- package/lib/decoders/copyrect.js +44 -0
- package/lib/decoders/hextile.js +173 -0
- package/lib/decoders/raw.js +78 -0
- package/lib/decoders/rre.js +65 -0
- package/lib/decoders/tight.js +350 -0
- package/lib/decoders/tightpng.js +67 -0
- package/lib/deflator.js +99 -0
- package/lib/des.js +314 -0
- package/lib/display.js +733 -0
- package/lib/encodings.js +64 -0
- package/lib/inflator.js +87 -0
- package/lib/input/domkeytable.js +282 -0
- package/lib/input/fixedkeys.js +123 -0
- package/lib/input/gesturehandler.js +642 -0
- package/lib/input/keyboard.js +429 -0
- package/lib/input/keysym.js +1135 -0
- package/lib/input/keysymdef.js +1354 -0
- package/lib/input/util.js +304 -0
- package/lib/input/vkeys.js +127 -0
- package/lib/input/xtscancodes.js +505 -0
- package/lib/rfb.js +3448 -0
- package/lib/util/browser.js +131 -0
- package/lib/util/cursor.js +314 -0
- package/lib/util/element.js +43 -0
- package/lib/util/events.js +142 -0
- package/lib/util/eventtarget.js +64 -0
- package/lib/util/int.js +22 -0
- package/lib/util/logging.js +79 -0
- package/lib/util/polyfill.js +72 -0
- package/lib/util/strings.js +38 -0
- package/lib/vendor/pako/lib/utils/common.js +67 -0
- package/lib/vendor/pako/lib/zlib/adler32.js +33 -0
- package/lib/vendor/pako/lib/zlib/constants.js +51 -0
- package/lib/vendor/pako/lib/zlib/crc32.js +42 -0
- package/lib/vendor/pako/lib/zlib/deflate.js +2159 -0
- package/lib/vendor/pako/lib/zlib/gzheader.js +53 -0
- package/lib/vendor/pako/lib/zlib/inffast.js +445 -0
- package/lib/vendor/pako/lib/zlib/inflate.js +2114 -0
- package/lib/vendor/pako/lib/zlib/inftrees.js +418 -0
- package/lib/vendor/pako/lib/zlib/messages.js +36 -0
- package/lib/vendor/pako/lib/zlib/trees.js +1499 -0
- package/lib/vendor/pako/lib/zlib/zstream.js +46 -0
- package/lib/vendor/promise.js +255 -0
- package/lib/websock.js +374 -0
- package/package.json +48 -28
- package/vendor/pako/lib/zlib/deflate.js +30 -30
- package/vendor/pako/lib/zlib/inflate.js +17 -17
- package/core/input/mouse.js +0 -280
- package/docs/API-internal.md +0 -125
- package/docs/EMBEDDING.md +0 -83
- package/docs/VERSION +0 -1
package/AUTHORS
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
maintainers:
|
|
2
|
+
- Joel Martin (@kanaka)
|
|
3
|
+
- Solly Ross (@directxman12)
|
|
4
|
+
- Samuel Mannehed for Cendio AB (@samhed)
|
|
5
|
+
- Pierre Ossman for Cendio AB (@CendioOssman)
|
|
6
|
+
maintainersEmeritus:
|
|
7
|
+
- @astrand
|
|
8
|
+
contributors:
|
|
9
|
+
# There are a bunch of people that should be here.
|
|
10
|
+
# If you want to be on this list, feel free send a PR
|
|
11
|
+
# to add yourself.
|
|
12
|
+
- jalf <git@jalf.dk>
|
|
13
|
+
- NTT corp.
|
package/LICENSE.txt
CHANGED
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## noVNC: HTML VNC Client Library and Application
|
|
2
2
|
|
|
3
|
-
[](https://github.com/novnc/noVNC/actions?query=workflow%3ATest)
|
|
4
|
+
[](https://github.com/novnc/noVNC/actions?query=workflow%3ALint)
|
|
4
5
|
|
|
5
6
|
### Description
|
|
6
7
|
|
|
@@ -24,6 +25,7 @@ for a more complete list with additional info and links.
|
|
|
24
25
|
- [Browser Requirements](#browser-requirements)
|
|
25
26
|
- [Server Requirements](#server-requirements)
|
|
26
27
|
- [Quick Start](#quick-start)
|
|
28
|
+
- [Installation from Snap Package](#installation-from-snap-package)
|
|
27
29
|
- [Integration and Deployment](#integration-and-deployment)
|
|
28
30
|
- [Authors/Contributors](#authorscontributors)
|
|
29
31
|
|
|
@@ -67,6 +69,8 @@ Please tweet [@noVNC](http://www.twitter.com/noVNC) if you do.
|
|
|
67
69
|
* Supports scaling, clipping and resizing the desktop
|
|
68
70
|
* Local cursor rendering
|
|
69
71
|
* Clipboard copy/paste
|
|
72
|
+
* Translations
|
|
73
|
+
* Touch gestures for emulating common mouse actions
|
|
70
74
|
* Licensed mainly under the [MPL 2.0](http://www.mozilla.org/MPL/2.0/), see
|
|
71
75
|
[the license document](LICENSE.txt) for details
|
|
72
76
|
|
|
@@ -87,7 +91,7 @@ noVNC uses many modern web technologies so a formal requirement list is
|
|
|
87
91
|
not available. However these are the minimum versions we are currently
|
|
88
92
|
aware of:
|
|
89
93
|
|
|
90
|
-
* Chrome 49, Firefox 44, Safari
|
|
94
|
+
* Chrome 49, Firefox 44, Safari 11, Opera 36, IE 11, Edge 12
|
|
91
95
|
|
|
92
96
|
|
|
93
97
|
### Server Requirements
|
|
@@ -114,6 +118,66 @@ proxy.
|
|
|
114
118
|
script. Hit the Connect button, enter a password if the VNC server has one
|
|
115
119
|
configured, and enjoy!
|
|
116
120
|
|
|
121
|
+
### Installation from Snap Package
|
|
122
|
+
Running the command below will install the latest release of noVNC from Snap:
|
|
123
|
+
|
|
124
|
+
`sudo snap install novnc`
|
|
125
|
+
|
|
126
|
+
#### Running noVNC
|
|
127
|
+
|
|
128
|
+
You can run the Snap-package installed novnc directly with, for example:
|
|
129
|
+
|
|
130
|
+
`novnc --listen 6081 --vnc localhost:5901 # /snap/bin/novnc if /snap/bin is not in your PATH`
|
|
131
|
+
|
|
132
|
+
#### Running as a Service (Daemon)
|
|
133
|
+
The Snap package also has the capability to run a 'novnc' service which can be
|
|
134
|
+
configured to listen on multiple ports connecting to multiple VNC servers
|
|
135
|
+
(effectively a service runing multiple instances of novnc).
|
|
136
|
+
Instructions (with example values):
|
|
137
|
+
|
|
138
|
+
List current services (out-of-box this will be blank):
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
sudo snap get novnc services
|
|
142
|
+
Key Value
|
|
143
|
+
services.n6080 {...}
|
|
144
|
+
services.n6081 {...}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Create a new service that listens on port 6082 and connects to the VNC server
|
|
148
|
+
running on port 5902 on localhost:
|
|
149
|
+
|
|
150
|
+
`sudo snap set novnc services.n6082.listen=6082 services.n6082.vnc=localhost:5902`
|
|
151
|
+
|
|
152
|
+
(Any services you define with 'snap set' will be automatically started)
|
|
153
|
+
Note that the name of the service, 'n6082' in this example, can be anything
|
|
154
|
+
as long as it doesn't start with a number or contain spaces/special characters.
|
|
155
|
+
|
|
156
|
+
View the configuration of the service just created:
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
sudo snap get novnc services.n6082
|
|
160
|
+
Key Value
|
|
161
|
+
services.n6082.listen 6082
|
|
162
|
+
services.n6082.vnc localhost:5902
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Disable a service (note that because of a limitation in Snap it's currently not
|
|
166
|
+
possible to unset config variables, setting them to blank values is the way
|
|
167
|
+
to disable a service):
|
|
168
|
+
|
|
169
|
+
`sudo snap set novnc services.n6082.listen='' services.n6082.vnc=''`
|
|
170
|
+
|
|
171
|
+
(Any services you set to blank with 'snap set' like this will be automatically stopped)
|
|
172
|
+
|
|
173
|
+
Verify that the service is disabled (blank values):
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
sudo snap get novnc services.n6082
|
|
177
|
+
Key Value
|
|
178
|
+
services.n6082.listen
|
|
179
|
+
services.n6082.vnc
|
|
180
|
+
```
|
|
117
181
|
|
|
118
182
|
### Integration and Deployment
|
|
119
183
|
|
|
@@ -126,10 +190,12 @@ or deploying the noVNC application in production environments:
|
|
|
126
190
|
|
|
127
191
|
### Authors/Contributors
|
|
128
192
|
|
|
193
|
+
See [AUTHORS](AUTHORS) for a (full-ish) list of authors. If you're not on
|
|
194
|
+
that list and you think you should be, feel free to send a PR to fix that.
|
|
195
|
+
|
|
129
196
|
* Core team:
|
|
130
197
|
* [Joel Martin](https://github.com/kanaka)
|
|
131
198
|
* [Samuel Mannehed](https://github.com/samhed) (Cendio)
|
|
132
|
-
* [Peter Åstrand](https://github.com/astrand) (Cendio)
|
|
133
199
|
* [Solly Ross](https://github.com/DirectXMan12) (Red Hat / OpenStack)
|
|
134
200
|
* [Pierre Ossman](https://github.com/CendioOssman) (Cendio)
|
|
135
201
|
|
package/core/base64.js
CHANGED
|
@@ -8,45 +8,43 @@ import * as Log from './util/logging.js';
|
|
|
8
8
|
|
|
9
9
|
export default {
|
|
10
10
|
/* Convert data (an array of integers) to a Base64 string. */
|
|
11
|
-
toBase64Table
|
|
12
|
-
base64Pad
|
|
11
|
+
toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''),
|
|
12
|
+
base64Pad: '=',
|
|
13
13
|
|
|
14
|
-
encode
|
|
14
|
+
encode(data) {
|
|
15
15
|
"use strict";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
var lengthpad = (length % 3);
|
|
16
|
+
let result = '';
|
|
17
|
+
const length = data.length;
|
|
18
|
+
const lengthpad = (length % 3);
|
|
20
19
|
// Convert every three bytes to 4 ascii characters.
|
|
21
20
|
|
|
22
|
-
for (
|
|
23
|
-
result += toBase64Table[data[i] >> 2];
|
|
24
|
-
result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
|
|
25
|
-
result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
|
|
26
|
-
result += toBase64Table[data[i + 2] & 0x3f];
|
|
21
|
+
for (let i = 0; i < (length - 2); i += 3) {
|
|
22
|
+
result += this.toBase64Table[data[i] >> 2];
|
|
23
|
+
result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
|
|
24
|
+
result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
|
|
25
|
+
result += this.toBase64Table[data[i + 2] & 0x3f];
|
|
27
26
|
}
|
|
28
27
|
|
|
29
28
|
// Convert the remaining 1 or 2 bytes, pad out to 4 characters.
|
|
30
|
-
|
|
29
|
+
const j = length - lengthpad;
|
|
31
30
|
if (lengthpad === 2) {
|
|
32
|
-
|
|
33
|
-
result += toBase64Table[data[j] >>
|
|
34
|
-
result += toBase64Table[(
|
|
35
|
-
result += toBase64Table[
|
|
36
|
-
result += toBase64Table[64];
|
|
31
|
+
result += this.toBase64Table[data[j] >> 2];
|
|
32
|
+
result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
|
|
33
|
+
result += this.toBase64Table[(data[j + 1] & 0x0f) << 2];
|
|
34
|
+
result += this.toBase64Table[64];
|
|
37
35
|
} else if (lengthpad === 1) {
|
|
38
|
-
|
|
39
|
-
result += toBase64Table[data[j]
|
|
40
|
-
result += toBase64Table[
|
|
41
|
-
result += toBase64Table[64];
|
|
42
|
-
result += toBase64Table[64];
|
|
36
|
+
result += this.toBase64Table[data[j] >> 2];
|
|
37
|
+
result += this.toBase64Table[(data[j] & 0x03) << 4];
|
|
38
|
+
result += this.toBase64Table[64];
|
|
39
|
+
result += this.toBase64Table[64];
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
return result;
|
|
46
43
|
},
|
|
47
44
|
|
|
48
45
|
/* Convert Base64 data to a string */
|
|
49
|
-
|
|
46
|
+
/* eslint-disable comma-spacing */
|
|
47
|
+
toBinaryTable: [
|
|
50
48
|
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
|
51
49
|
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
|
52
50
|
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
|
|
@@ -56,27 +54,23 @@ export default {
|
|
|
56
54
|
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
|
|
57
55
|
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
|
|
58
56
|
],
|
|
57
|
+
/* eslint-enable comma-spacing */
|
|
59
58
|
|
|
60
|
-
decode
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
var toBinaryTable = this.toBinaryTable;
|
|
64
|
-
var base64Pad = this.base64Pad;
|
|
65
|
-
var result, result_length;
|
|
66
|
-
var leftbits = 0; // number of bits decoded, but yet to be appended
|
|
67
|
-
var leftdata = 0; // bits decoded, but yet to be appended
|
|
68
|
-
var data_length = data.indexOf('=') - offset;
|
|
69
|
-
|
|
70
|
-
if (data_length < 0) { data_length = data.length - offset; }
|
|
59
|
+
decode(data, offset = 0) {
|
|
60
|
+
let dataLength = data.indexOf('=') - offset;
|
|
61
|
+
if (dataLength < 0) { dataLength = data.length - offset; }
|
|
71
62
|
|
|
72
63
|
/* Every four characters is 3 resulting numbers */
|
|
73
|
-
|
|
74
|
-
result = new Array(
|
|
64
|
+
const resultLength = (dataLength >> 2) * 3 + Math.floor((dataLength % 4) / 1.5);
|
|
65
|
+
const result = new Array(resultLength);
|
|
75
66
|
|
|
76
67
|
// Convert one by one.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
68
|
+
|
|
69
|
+
let leftbits = 0; // number of bits decoded, but yet to be appended
|
|
70
|
+
let leftdata = 0; // bits decoded, but yet to be appended
|
|
71
|
+
for (let idx = 0, i = offset; i < data.length; i++) {
|
|
72
|
+
const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
|
|
73
|
+
const padding = (data.charAt(i) === this.base64Pad);
|
|
80
74
|
// Skip illegal characters and whitespace
|
|
81
75
|
if (c === -1) {
|
|
82
76
|
Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
|
|
@@ -100,7 +94,7 @@ export default {
|
|
|
100
94
|
|
|
101
95
|
// If there are any bits left, the base64 string was corrupted
|
|
102
96
|
if (leftbits) {
|
|
103
|
-
err = new Error('Corrupted base64 string');
|
|
97
|
+
const err = new Error('Corrupted base64 string');
|
|
104
98
|
err.name = 'Base64-Error';
|
|
105
99
|
throw err;
|
|
106
100
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
export default class CopyRectDecoder {
|
|
11
|
+
decodeRect(x, y, width, height, sock, display, depth) {
|
|
12
|
+
if (sock.rQwait("COPYRECT", 4)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let deltaX = sock.rQshift16();
|
|
17
|
+
let deltaY = sock.rQshift16();
|
|
18
|
+
display.copyImage(deltaX, deltaY, x, y, width, height);
|
|
19
|
+
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
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
|
+
export default class RawDecoder {
|
|
11
|
+
constructor() {
|
|
12
|
+
this._lines = 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
decodeRect(x, y, width, height, sock, display, depth) {
|
|
16
|
+
if (this._lines === 0) {
|
|
17
|
+
this._lines = height;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const pixelSize = depth == 8 ? 1 : 4;
|
|
21
|
+
const bytesPerLine = width * pixelSize;
|
|
22
|
+
|
|
23
|
+
if (sock.rQwait("RAW", bytesPerLine)) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const curY = y + (height - this._lines);
|
|
28
|
+
const currHeight = Math.min(this._lines,
|
|
29
|
+
Math.floor(sock.rQlen / bytesPerLine));
|
|
30
|
+
let data = sock.rQ;
|
|
31
|
+
let index = sock.rQi;
|
|
32
|
+
|
|
33
|
+
// Convert data if needed
|
|
34
|
+
if (depth == 8) {
|
|
35
|
+
const pixels = width * currHeight;
|
|
36
|
+
const newdata = new Uint8Array(pixels * 4);
|
|
37
|
+
for (let i = 0; i < pixels; i++) {
|
|
38
|
+
newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3;
|
|
39
|
+
newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x3) * 255 / 3;
|
|
40
|
+
newdata[i * 4 + 2] = ((data[index + i] >> 4) & 0x3) * 255 / 3;
|
|
41
|
+
newdata[i * 4 + 4] = 0;
|
|
42
|
+
}
|
|
43
|
+
data = newdata;
|
|
44
|
+
index = 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
display.blitImage(x, curY, width, currHeight, data, index);
|
|
48
|
+
sock.rQskipBytes(currHeight * bytesPerLine);
|
|
49
|
+
this._lines -= currHeight;
|
|
50
|
+
if (this._lines > 0) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
export default class RREDecoder {
|
|
11
|
+
constructor() {
|
|
12
|
+
this._subrects = 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
decodeRect(x, y, width, height, sock, display, depth) {
|
|
16
|
+
if (this._subrects === 0) {
|
|
17
|
+
if (sock.rQwait("RRE", 4 + 4)) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
this._subrects = sock.rQshift32();
|
|
22
|
+
|
|
23
|
+
let color = sock.rQshiftBytes(4); // Background
|
|
24
|
+
display.fillRect(x, y, width, height, color);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
while (this._subrects > 0) {
|
|
28
|
+
if (sock.rQwait("RRE", 4 + 8)) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let color = sock.rQshiftBytes(4);
|
|
33
|
+
let sx = sock.rQshift16();
|
|
34
|
+
let sy = sock.rQshift16();
|
|
35
|
+
let swidth = sock.rQshift16();
|
|
36
|
+
let sheight = sock.rQshift16();
|
|
37
|
+
display.fillRect(x + sx, y + sy, swidth, sheight, color);
|
|
38
|
+
|
|
39
|
+
this._subrects--;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|