@novnc/novnc 1.3.0-g1075cd8 → 1.3.0-g145d235
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/core/display.js +12 -0
- package/core/rfb.js +161 -80
- package/docs/API.md +61 -0
- package/lib/base64.js +20 -35
- package/lib/decoders/copyrect.js +1 -12
- package/lib/decoders/hextile.js +12 -44
- package/lib/decoders/jpeg.js +1 -44
- package/lib/decoders/raw.js +5 -22
- package/lib/decoders/rre.js +1 -16
- package/lib/decoders/tight.js +8 -76
- package/lib/decoders/tightpng.js +2 -24
- package/lib/decoders/zrle.js +2 -51
- package/lib/deflator.js +4 -21
- package/lib/des.js +19 -35
- package/lib/display.js +57 -105
- package/lib/encodings.js +1 -10
- package/lib/inflator.js +1 -17
- package/lib/input/domkeytable.js +77 -48
- package/lib/input/fixedkeys.js +8 -3
- package/lib/input/gesturehandler.js +81 -151
- package/lib/input/keyboard.js +48 -88
- package/lib/input/keysym.js +15 -272
- package/lib/input/keysymdef.js +5 -7
- package/lib/input/util.js +42 -84
- package/lib/input/vkeys.js +0 -3
- package/lib/input/xtscancodes.js +2 -170
- package/lib/ra2.js +37 -261
- package/lib/rfb.js +416 -1000
- package/lib/util/browser.js +16 -25
- package/lib/util/cursor.js +20 -64
- package/lib/util/element.js +3 -5
- package/lib/util/events.js +23 -30
- package/lib/util/eventtarget.js +1 -14
- package/lib/util/int.js +1 -2
- package/lib/util/logging.js +1 -19
- package/lib/util/md5.js +7 -27
- package/lib/util/strings.js +3 -5
- package/lib/vendor/pako/lib/utils/common.js +8 -17
- package/lib/vendor/pako/lib/zlib/adler32.js +3 -7
- package/lib/vendor/pako/lib/zlib/constants.js +2 -5
- package/lib/vendor/pako/lib/zlib/crc32.js +5 -12
- package/lib/vendor/pako/lib/zlib/deflate.js +212 -617
- package/lib/vendor/pako/lib/zlib/gzheader.js +1 -13
- package/lib/vendor/pako/lib/zlib/inffast.js +60 -176
- package/lib/vendor/pako/lib/zlib/inflate.js +397 -887
- package/lib/vendor/pako/lib/zlib/inftrees.js +62 -168
- package/lib/vendor/pako/lib/zlib/messages.js +1 -11
- package/lib/vendor/pako/lib/zlib/trees.js +245 -587
- package/lib/vendor/pako/lib/zlib/zstream.js +2 -18
- package/lib/websock.js +31 -84
- package/package.json +1 -1
package/core/display.js
CHANGED
|
@@ -224,6 +224,18 @@ export default class Display {
|
|
|
224
224
|
this.viewportChangePos(0, 0);
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
getImageData() {
|
|
228
|
+
return this._drawCtx.getImageData(0, 0, this.width, this.height);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
toDataURL(type, encoderOptions) {
|
|
232
|
+
return this._backbuffer.toDataURL(type, encoderOptions);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
toBlob(callback, type, quality) {
|
|
236
|
+
return this._backbuffer.toBlob(callback, type, quality);
|
|
237
|
+
}
|
|
238
|
+
|
|
227
239
|
// Track what parts of the visible canvas that need updating
|
|
228
240
|
_damage(x, y, w, h) {
|
|
229
241
|
if (x < this._damageBounds.left) {
|
package/core/rfb.js
CHANGED
|
@@ -54,6 +54,21 @@ const GESTURE_SCRLSENS = 50;
|
|
|
54
54
|
const DOUBLE_TAP_TIMEOUT = 1000;
|
|
55
55
|
const DOUBLE_TAP_THRESHOLD = 50;
|
|
56
56
|
|
|
57
|
+
// Security types
|
|
58
|
+
const securityTypeNone = 1;
|
|
59
|
+
const securityTypeVNCAuth = 2;
|
|
60
|
+
const securityTypeRA2ne = 6;
|
|
61
|
+
const securityTypeTight = 16;
|
|
62
|
+
const securityTypeVeNCrypt = 19;
|
|
63
|
+
const securityTypeXVP = 22;
|
|
64
|
+
const securityTypeARD = 30;
|
|
65
|
+
|
|
66
|
+
// Special Tight security types
|
|
67
|
+
const securityTypeUnixLogon = 129;
|
|
68
|
+
|
|
69
|
+
// VeNCrypt security types
|
|
70
|
+
const securityTypePlain = 256;
|
|
71
|
+
|
|
57
72
|
// Extended clipboard pseudo-encoding formats
|
|
58
73
|
const extendedClipboardFormatText = 1;
|
|
59
74
|
/*eslint-disable no-unused-vars */
|
|
@@ -79,6 +94,12 @@ export default class RFB extends EventTargetMixin {
|
|
|
79
94
|
throw new Error("Must specify URL, WebSocket or RTCDataChannel");
|
|
80
95
|
}
|
|
81
96
|
|
|
97
|
+
// We rely on modern APIs which might not be available in an
|
|
98
|
+
// insecure context
|
|
99
|
+
if (!window.isSecureContext) {
|
|
100
|
+
Log.Error("noVNC requires a secure context (TLS). Expect crashes!");
|
|
101
|
+
}
|
|
102
|
+
|
|
82
103
|
super();
|
|
83
104
|
|
|
84
105
|
this._target = target;
|
|
@@ -396,7 +417,7 @@ export default class RFB extends EventTargetMixin {
|
|
|
396
417
|
|
|
397
418
|
sendCredentials(creds) {
|
|
398
419
|
this._rfbCredentials = creds;
|
|
399
|
-
|
|
420
|
+
this._resumeAuthentication();
|
|
400
421
|
}
|
|
401
422
|
|
|
402
423
|
sendCtrlAltDel() {
|
|
@@ -479,6 +500,18 @@ export default class RFB extends EventTargetMixin {
|
|
|
479
500
|
}
|
|
480
501
|
}
|
|
481
502
|
|
|
503
|
+
getImageData() {
|
|
504
|
+
return this._display.getImageData();
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
toDataURL(type, encoderOptions) {
|
|
508
|
+
return this._display.toDataURL(type, encoderOptions);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
toBlob(callback, type, quality) {
|
|
512
|
+
return this._display.toBlob(callback, type, quality);
|
|
513
|
+
}
|
|
514
|
+
|
|
482
515
|
// ===== PRIVATE METHODS =====
|
|
483
516
|
|
|
484
517
|
_connect() {
|
|
@@ -916,8 +949,15 @@ export default class RFB extends EventTargetMixin {
|
|
|
916
949
|
}
|
|
917
950
|
}
|
|
918
951
|
break;
|
|
952
|
+
case 'connecting':
|
|
953
|
+
while (this._rfbConnectionState === 'connecting') {
|
|
954
|
+
if (!this._initMsg()) {
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
break;
|
|
919
959
|
default:
|
|
920
|
-
|
|
960
|
+
Log.Error("Got data while in an invalid state");
|
|
921
961
|
break;
|
|
922
962
|
}
|
|
923
963
|
}
|
|
@@ -1326,6 +1366,21 @@ export default class RFB extends EventTargetMixin {
|
|
|
1326
1366
|
this._rfbInitState = 'Security';
|
|
1327
1367
|
}
|
|
1328
1368
|
|
|
1369
|
+
_isSupportedSecurityType(type) {
|
|
1370
|
+
const clientTypes = [
|
|
1371
|
+
securityTypeNone,
|
|
1372
|
+
securityTypeVNCAuth,
|
|
1373
|
+
securityTypeRA2ne,
|
|
1374
|
+
securityTypeTight,
|
|
1375
|
+
securityTypeVeNCrypt,
|
|
1376
|
+
securityTypeXVP,
|
|
1377
|
+
securityTypeARD,
|
|
1378
|
+
securityTypePlain,
|
|
1379
|
+
];
|
|
1380
|
+
|
|
1381
|
+
return clientTypes.includes(type);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1329
1384
|
_negotiateSecurity() {
|
|
1330
1385
|
if (this._rfbVersion >= 3.7) {
|
|
1331
1386
|
// Server sends supported list, client decides
|
|
@@ -1336,28 +1391,23 @@ export default class RFB extends EventTargetMixin {
|
|
|
1336
1391
|
this._rfbInitState = "SecurityReason";
|
|
1337
1392
|
this._securityContext = "no security types";
|
|
1338
1393
|
this._securityStatus = 1;
|
|
1339
|
-
return
|
|
1394
|
+
return true;
|
|
1340
1395
|
}
|
|
1341
1396
|
|
|
1342
1397
|
const types = this._sock.rQshiftBytes(numTypes);
|
|
1343
1398
|
Log.Debug("Server security types: " + types);
|
|
1344
1399
|
|
|
1345
|
-
// Look for
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
this.
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
} else if (types.includes(30)) {
|
|
1357
|
-
this._rfbAuthScheme = 30; // ARD Auth
|
|
1358
|
-
} else if (types.includes(19)) {
|
|
1359
|
-
this._rfbAuthScheme = 19; // VeNCrypt Auth
|
|
1360
|
-
} else {
|
|
1400
|
+
// Look for a matching security type in the order that the
|
|
1401
|
+
// server prefers
|
|
1402
|
+
this._rfbAuthScheme = -1;
|
|
1403
|
+
for (let type of types) {
|
|
1404
|
+
if (this._isSupportedSecurityType(type)) {
|
|
1405
|
+
this._rfbAuthScheme = type;
|
|
1406
|
+
break;
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
if (this._rfbAuthScheme === -1) {
|
|
1361
1411
|
return this._fail("Unsupported security types (types: " + types + ")");
|
|
1362
1412
|
}
|
|
1363
1413
|
|
|
@@ -1371,14 +1421,14 @@ export default class RFB extends EventTargetMixin {
|
|
|
1371
1421
|
this._rfbInitState = "SecurityReason";
|
|
1372
1422
|
this._securityContext = "authentication scheme";
|
|
1373
1423
|
this._securityStatus = 1;
|
|
1374
|
-
return
|
|
1424
|
+
return true;
|
|
1375
1425
|
}
|
|
1376
1426
|
}
|
|
1377
1427
|
|
|
1378
1428
|
this._rfbInitState = 'Authentication';
|
|
1379
1429
|
Log.Debug('Authenticating using scheme: ' + this._rfbAuthScheme);
|
|
1380
1430
|
|
|
1381
|
-
return
|
|
1431
|
+
return true;
|
|
1382
1432
|
}
|
|
1383
1433
|
|
|
1384
1434
|
_handleSecurityReason() {
|
|
@@ -1428,7 +1478,7 @@ export default class RFB extends EventTargetMixin {
|
|
|
1428
1478
|
this._rfbCredentials.username +
|
|
1429
1479
|
this._rfbCredentials.target;
|
|
1430
1480
|
this._sock.sendString(xvpAuthStr);
|
|
1431
|
-
this._rfbAuthScheme =
|
|
1481
|
+
this._rfbAuthScheme = securityTypeVNCAuth;
|
|
1432
1482
|
return this._negotiateAuthentication();
|
|
1433
1483
|
}
|
|
1434
1484
|
|
|
@@ -1486,49 +1536,66 @@ export default class RFB extends EventTargetMixin {
|
|
|
1486
1536
|
subtypes.push(this._sock.rQshift32());
|
|
1487
1537
|
}
|
|
1488
1538
|
|
|
1489
|
-
//
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1539
|
+
// Look for a matching security type in the order that the
|
|
1540
|
+
// server prefers
|
|
1541
|
+
this._rfbAuthScheme = -1;
|
|
1542
|
+
for (let type of subtypes) {
|
|
1543
|
+
// Avoid getting in to a loop
|
|
1544
|
+
if (type === securityTypeVeNCrypt) {
|
|
1545
|
+
continue;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
if (this._isSupportedSecurityType(type)) {
|
|
1549
|
+
this._rfbAuthScheme = type;
|
|
1550
|
+
break;
|
|
1551
|
+
}
|
|
1496
1552
|
}
|
|
1497
|
-
}
|
|
1498
1553
|
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
if (this._rfbCredentials.username === undefined ||
|
|
1502
|
-
this._rfbCredentials.password === undefined) {
|
|
1503
|
-
this.dispatchEvent(new CustomEvent(
|
|
1504
|
-
"credentialsrequired",
|
|
1505
|
-
{ detail: { types: ["username", "password"] } }));
|
|
1506
|
-
return false;
|
|
1554
|
+
if (this._rfbAuthScheme === -1) {
|
|
1555
|
+
return this._fail("Unsupported security types (types: " + subtypes + ")");
|
|
1507
1556
|
}
|
|
1508
1557
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
(user.length >> 24) & 0xFF,
|
|
1514
|
-
(user.length >> 16) & 0xFF,
|
|
1515
|
-
(user.length >> 8) & 0xFF,
|
|
1516
|
-
user.length & 0xFF
|
|
1517
|
-
]);
|
|
1518
|
-
this._sock.send([
|
|
1519
|
-
(pass.length >> 24) & 0xFF,
|
|
1520
|
-
(pass.length >> 16) & 0xFF,
|
|
1521
|
-
(pass.length >> 8) & 0xFF,
|
|
1522
|
-
pass.length & 0xFF
|
|
1523
|
-
]);
|
|
1524
|
-
this._sock.sendString(user);
|
|
1525
|
-
this._sock.sendString(pass);
|
|
1558
|
+
this._sock.send([this._rfbAuthScheme >> 24,
|
|
1559
|
+
this._rfbAuthScheme >> 16,
|
|
1560
|
+
this._rfbAuthScheme >> 8,
|
|
1561
|
+
this._rfbAuthScheme]);
|
|
1526
1562
|
|
|
1527
|
-
this.
|
|
1563
|
+
this._rfbVeNCryptState == 4;
|
|
1528
1564
|
return true;
|
|
1529
1565
|
}
|
|
1530
1566
|
}
|
|
1531
1567
|
|
|
1568
|
+
_negotiatePlainAuth() {
|
|
1569
|
+
if (this._rfbCredentials.username === undefined ||
|
|
1570
|
+
this._rfbCredentials.password === undefined) {
|
|
1571
|
+
this.dispatchEvent(new CustomEvent(
|
|
1572
|
+
"credentialsrequired",
|
|
1573
|
+
{ detail: { types: ["username", "password"] } }));
|
|
1574
|
+
return false;
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
const user = encodeUTF8(this._rfbCredentials.username);
|
|
1578
|
+
const pass = encodeUTF8(this._rfbCredentials.password);
|
|
1579
|
+
|
|
1580
|
+
this._sock.send([
|
|
1581
|
+
(user.length >> 24) & 0xFF,
|
|
1582
|
+
(user.length >> 16) & 0xFF,
|
|
1583
|
+
(user.length >> 8) & 0xFF,
|
|
1584
|
+
user.length & 0xFF
|
|
1585
|
+
]);
|
|
1586
|
+
this._sock.send([
|
|
1587
|
+
(pass.length >> 24) & 0xFF,
|
|
1588
|
+
(pass.length >> 16) & 0xFF,
|
|
1589
|
+
(pass.length >> 8) & 0xFF,
|
|
1590
|
+
pass.length & 0xFF
|
|
1591
|
+
]);
|
|
1592
|
+
this._sock.sendString(user);
|
|
1593
|
+
this._sock.sendString(pass);
|
|
1594
|
+
|
|
1595
|
+
this._rfbInitState = "SecurityResult";
|
|
1596
|
+
return true;
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1532
1599
|
_negotiateStdVNCAuth() {
|
|
1533
1600
|
if (this._sock.rQwait("auth challenge", 16)) { return false; }
|
|
1534
1601
|
|
|
@@ -1655,7 +1722,7 @@ export default class RFB extends EventTargetMixin {
|
|
|
1655
1722
|
this._rfbCredentials.ardCredentials = encrypted;
|
|
1656
1723
|
this._rfbCredentials.ardPublicKey = clientPublicKey;
|
|
1657
1724
|
|
|
1658
|
-
|
|
1725
|
+
this._resumeAuthentication();
|
|
1659
1726
|
}
|
|
1660
1727
|
|
|
1661
1728
|
_negotiateTightUnixAuth() {
|
|
@@ -1765,12 +1832,12 @@ export default class RFB extends EventTargetMixin {
|
|
|
1765
1832
|
case 'STDVNOAUTH__': // no auth
|
|
1766
1833
|
this._rfbInitState = 'SecurityResult';
|
|
1767
1834
|
return true;
|
|
1768
|
-
case 'STDVVNCAUTH_':
|
|
1769
|
-
this._rfbAuthScheme =
|
|
1770
|
-
return
|
|
1771
|
-
case 'TGHTULGNAUTH':
|
|
1772
|
-
this._rfbAuthScheme =
|
|
1773
|
-
return
|
|
1835
|
+
case 'STDVVNCAUTH_':
|
|
1836
|
+
this._rfbAuthScheme = securityTypeVNCAuth;
|
|
1837
|
+
return true;
|
|
1838
|
+
case 'TGHTULGNAUTH':
|
|
1839
|
+
this._rfbAuthScheme = securityTypeUnixLogon;
|
|
1840
|
+
return true;
|
|
1774
1841
|
default:
|
|
1775
1842
|
return this._fail("Unsupported tiny auth scheme " +
|
|
1776
1843
|
"(scheme: " + authType + ")");
|
|
@@ -1807,7 +1874,7 @@ export default class RFB extends EventTargetMixin {
|
|
|
1807
1874
|
}).then(() => {
|
|
1808
1875
|
this.dispatchEvent(new CustomEvent('securityresult'));
|
|
1809
1876
|
this._rfbInitState = "SecurityResult";
|
|
1810
|
-
|
|
1877
|
+
return true;
|
|
1811
1878
|
}).finally(() => {
|
|
1812
1879
|
this._rfbRSAAESAuthenticationState.removeEventListener(
|
|
1813
1880
|
"serververification", this._eventHandlers.handleRSAAESServerVerification);
|
|
@@ -1821,33 +1888,32 @@ export default class RFB extends EventTargetMixin {
|
|
|
1821
1888
|
|
|
1822
1889
|
_negotiateAuthentication() {
|
|
1823
1890
|
switch (this._rfbAuthScheme) {
|
|
1824
|
-
case
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
return true;
|
|
1828
|
-
}
|
|
1829
|
-
this._rfbInitState = 'ClientInitialisation';
|
|
1830
|
-
return this._initMsg();
|
|
1891
|
+
case securityTypeNone:
|
|
1892
|
+
this._rfbInitState = 'SecurityResult';
|
|
1893
|
+
return true;
|
|
1831
1894
|
|
|
1832
|
-
case
|
|
1895
|
+
case securityTypeXVP:
|
|
1833
1896
|
return this._negotiateXvpAuth();
|
|
1834
1897
|
|
|
1835
|
-
case
|
|
1898
|
+
case securityTypeARD:
|
|
1836
1899
|
return this._negotiateARDAuth();
|
|
1837
1900
|
|
|
1838
|
-
case
|
|
1901
|
+
case securityTypeVNCAuth:
|
|
1839
1902
|
return this._negotiateStdVNCAuth();
|
|
1840
1903
|
|
|
1841
|
-
case
|
|
1904
|
+
case securityTypeTight:
|
|
1842
1905
|
return this._negotiateTightAuth();
|
|
1843
1906
|
|
|
1844
|
-
case
|
|
1907
|
+
case securityTypeVeNCrypt:
|
|
1845
1908
|
return this._negotiateVeNCryptAuth();
|
|
1846
1909
|
|
|
1847
|
-
case
|
|
1910
|
+
case securityTypePlain:
|
|
1911
|
+
return this._negotiatePlainAuth();
|
|
1912
|
+
|
|
1913
|
+
case securityTypeUnixLogon:
|
|
1848
1914
|
return this._negotiateTightUnixAuth();
|
|
1849
1915
|
|
|
1850
|
-
case
|
|
1916
|
+
case securityTypeRA2ne:
|
|
1851
1917
|
return this._negotiateRA2neAuth();
|
|
1852
1918
|
|
|
1853
1919
|
default:
|
|
@@ -1857,6 +1923,13 @@ export default class RFB extends EventTargetMixin {
|
|
|
1857
1923
|
}
|
|
1858
1924
|
|
|
1859
1925
|
_handleSecurityResult() {
|
|
1926
|
+
// There is no security choice, and hence no security result
|
|
1927
|
+
// until RFB 3.7
|
|
1928
|
+
if (this._rfbVersion < 3.7) {
|
|
1929
|
+
this._rfbInitState = 'ClientInitialisation';
|
|
1930
|
+
return true;
|
|
1931
|
+
}
|
|
1932
|
+
|
|
1860
1933
|
if (this._sock.rQwait('VNC auth response ', 4)) { return false; }
|
|
1861
1934
|
|
|
1862
1935
|
const status = this._sock.rQshift32();
|
|
@@ -1864,13 +1937,13 @@ export default class RFB extends EventTargetMixin {
|
|
|
1864
1937
|
if (status === 0) { // OK
|
|
1865
1938
|
this._rfbInitState = 'ClientInitialisation';
|
|
1866
1939
|
Log.Debug('Authentication OK');
|
|
1867
|
-
return
|
|
1940
|
+
return true;
|
|
1868
1941
|
} else {
|
|
1869
1942
|
if (this._rfbVersion >= 3.8) {
|
|
1870
1943
|
this._rfbInitState = "SecurityReason";
|
|
1871
1944
|
this._securityContext = "security result";
|
|
1872
1945
|
this._securityStatus = status;
|
|
1873
|
-
return
|
|
1946
|
+
return true;
|
|
1874
1947
|
} else {
|
|
1875
1948
|
this.dispatchEvent(new CustomEvent(
|
|
1876
1949
|
"securityfailure",
|
|
@@ -2046,6 +2119,14 @@ export default class RFB extends EventTargetMixin {
|
|
|
2046
2119
|
}
|
|
2047
2120
|
}
|
|
2048
2121
|
|
|
2122
|
+
// Resume authentication handshake after it was paused for some
|
|
2123
|
+
// reason, e.g. waiting for a password from the user
|
|
2124
|
+
_resumeAuthentication() {
|
|
2125
|
+
// We use setTimeout() so it's run in its own context, just like
|
|
2126
|
+
// it originally did via the WebSocket's event handler
|
|
2127
|
+
setTimeout(this._initMsg.bind(this), 0);
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2049
2130
|
_handleSetColourMapMsg() {
|
|
2050
2131
|
Log.Debug("SetColorMapEntries");
|
|
2051
2132
|
|
package/docs/API.md
CHANGED
|
@@ -155,6 +155,15 @@ protocol stream.
|
|
|
155
155
|
[`RFB.clipboardPasteFrom()`](#rfbclipboardpastefrom)
|
|
156
156
|
- Send clipboard contents to server.
|
|
157
157
|
|
|
158
|
+
[`RFB.getImageData()`](#rfbgetimagedata)
|
|
159
|
+
- Return the current content of the screen as an ImageData array.
|
|
160
|
+
|
|
161
|
+
[`RFB.toDataURL()`](#rfbtodataurl)
|
|
162
|
+
- Return the current content of the screen as data-url encoded image file.
|
|
163
|
+
|
|
164
|
+
[`RFB.toBlob()`](#rfbtoblob)
|
|
165
|
+
- Return the current content of the screen as Blob encoded image file.
|
|
166
|
+
|
|
158
167
|
### Details
|
|
159
168
|
|
|
160
169
|
#### RFB()
|
|
@@ -423,3 +432,55 @@ to the remote server.
|
|
|
423
432
|
|
|
424
433
|
**`text`**
|
|
425
434
|
- A `DOMString` specifying the clipboard data to send.
|
|
435
|
+
|
|
436
|
+
#### RFB.getImageData()
|
|
437
|
+
|
|
438
|
+
The `RFB.getImageData()` method is used to return the current content of the
|
|
439
|
+
screen encoded as [`ImageData`](https://developer.mozilla.org/en-US/docs/Web/API/ImageData).
|
|
440
|
+
|
|
441
|
+
##### Syntax
|
|
442
|
+
|
|
443
|
+
RFB.getImageData();
|
|
444
|
+
|
|
445
|
+
#### RFB.toDataURL()
|
|
446
|
+
|
|
447
|
+
The `RFB.toDataURL()` method is used to return the current content of the
|
|
448
|
+
screen encoded as a data URL that could for example be put in the `src` attribute
|
|
449
|
+
of an `img` tag.
|
|
450
|
+
|
|
451
|
+
##### Syntax
|
|
452
|
+
|
|
453
|
+
RFB.toDataURL();
|
|
454
|
+
RFB.toDataURL(type);
|
|
455
|
+
RFB.toDataURL(type, encoderOptions);
|
|
456
|
+
|
|
457
|
+
###### Parameters
|
|
458
|
+
|
|
459
|
+
**`type`** *Optional*
|
|
460
|
+
- A string indicating the requested MIME type of the image
|
|
461
|
+
|
|
462
|
+
**`encoderOptions`** *Optional*
|
|
463
|
+
- A number between 0 and 1 indicating the image quality.
|
|
464
|
+
|
|
465
|
+
#### RFB.toBlob()
|
|
466
|
+
|
|
467
|
+
The `RFB.toBlob()` method is used to return the current content of the
|
|
468
|
+
screen encoded as [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
|
|
469
|
+
|
|
470
|
+
##### Syntax
|
|
471
|
+
|
|
472
|
+
RFB.toDataURL(callback);
|
|
473
|
+
RFB.toDataURL(callback, type);
|
|
474
|
+
RFB.toDataURL(callback, type, quality);
|
|
475
|
+
|
|
476
|
+
###### Parameters
|
|
477
|
+
|
|
478
|
+
**`callback`**
|
|
479
|
+
- A callback function which will receive the resulting [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
|
|
480
|
+
as the single argument
|
|
481
|
+
|
|
482
|
+
**`type`** *Optional*
|
|
483
|
+
- A string indicating the requested MIME type of the image
|
|
484
|
+
|
|
485
|
+
**`encoderOptions`** *Optional*
|
|
486
|
+
- A number between 0 and 1 indicating the image quality.
|
package/lib/base64.js
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
4
|
-
|
|
5
4
|
Object.defineProperty(exports, "__esModule", {
|
|
6
5
|
value: true
|
|
7
6
|
});
|
|
8
7
|
exports["default"] = void 0;
|
|
9
|
-
|
|
10
8
|
var Log = _interopRequireWildcard(require("./util/logging.js"));
|
|
11
|
-
|
|
12
9
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
13
|
-
|
|
14
10
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
15
|
-
|
|
16
11
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
17
12
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
18
13
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
@@ -26,18 +21,18 @@ var _default = {
|
|
|
26
21
|
|
|
27
22
|
var result = '';
|
|
28
23
|
var length = data.length;
|
|
29
|
-
var lengthpad = length % 3;
|
|
24
|
+
var lengthpad = length % 3;
|
|
25
|
+
// Convert every three bytes to 4 ascii characters.
|
|
30
26
|
|
|
31
27
|
for (var i = 0; i < length - 2; i += 3) {
|
|
32
28
|
result += this.toBase64Table[data[i] >> 2];
|
|
33
29
|
result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
|
|
34
30
|
result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
|
|
35
31
|
result += this.toBase64Table[data[i + 2] & 0x3f];
|
|
36
|
-
}
|
|
37
|
-
|
|
32
|
+
}
|
|
38
33
|
|
|
34
|
+
// Convert the remaining 1 or 2 bytes, pad out to 4 characters.
|
|
39
35
|
var j = length - lengthpad;
|
|
40
|
-
|
|
41
36
|
if (lengthpad === 2) {
|
|
42
37
|
result += this.toBase64Table[data[j] >> 2];
|
|
43
38
|
result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)];
|
|
@@ -49,67 +44,57 @@ var _default = {
|
|
|
49
44
|
result += this.toBase64Table[64];
|
|
50
45
|
result += this.toBase64Table[64];
|
|
51
46
|
}
|
|
52
|
-
|
|
53
47
|
return result;
|
|
54
48
|
},
|
|
55
|
-
|
|
56
49
|
/* Convert Base64 data to a string */
|
|
57
|
-
|
|
58
50
|
/* eslint-disable comma-spacing */
|
|
59
51
|
toBinaryTable: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1],
|
|
60
|
-
|
|
61
|
-
/* eslint-enable comma-spacing */
|
|
62
|
-
decode: function decode(data) {
|
|
52
|
+
/* eslint-enable comma-spacing */decode: function decode(data) {
|
|
63
53
|
var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
64
54
|
var dataLength = data.indexOf('=') - offset;
|
|
65
|
-
|
|
66
55
|
if (dataLength < 0) {
|
|
67
56
|
dataLength = data.length - offset;
|
|
68
57
|
}
|
|
69
|
-
/* Every four characters is 3 resulting numbers */
|
|
70
|
-
|
|
71
58
|
|
|
59
|
+
/* Every four characters is 3 resulting numbers */
|
|
72
60
|
var resultLength = (dataLength >> 2) * 3 + Math.floor(dataLength % 4 / 1.5);
|
|
73
|
-
var result = new Array(resultLength);
|
|
61
|
+
var result = new Array(resultLength);
|
|
74
62
|
|
|
75
|
-
|
|
63
|
+
// Convert one by one.
|
|
76
64
|
|
|
65
|
+
var leftbits = 0; // number of bits decoded, but yet to be appended
|
|
77
66
|
var leftdata = 0; // bits decoded, but yet to be appended
|
|
78
|
-
|
|
79
67
|
for (var idx = 0, i = offset; i < data.length; i++) {
|
|
80
68
|
var c = this.toBinaryTable[data.charCodeAt(i) & 0x7f];
|
|
81
|
-
var padding = data.charAt(i) === this.base64Pad;
|
|
82
|
-
|
|
69
|
+
var padding = data.charAt(i) === this.base64Pad;
|
|
70
|
+
// Skip illegal characters and whitespace
|
|
83
71
|
if (c === -1) {
|
|
84
72
|
Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
|
|
85
73
|
continue;
|
|
86
|
-
}
|
|
87
|
-
|
|
74
|
+
}
|
|
88
75
|
|
|
76
|
+
// Collect data into leftdata, update bitcount
|
|
89
77
|
leftdata = leftdata << 6 | c;
|
|
90
|
-
leftbits += 6;
|
|
78
|
+
leftbits += 6;
|
|
91
79
|
|
|
80
|
+
// If we have 8 or more bits, append 8 bits to the result
|
|
92
81
|
if (leftbits >= 8) {
|
|
93
|
-
leftbits -= 8;
|
|
94
|
-
|
|
82
|
+
leftbits -= 8;
|
|
83
|
+
// Append if not padding.
|
|
95
84
|
if (!padding) {
|
|
96
85
|
result[idx++] = leftdata >> leftbits & 0xff;
|
|
97
86
|
}
|
|
98
|
-
|
|
99
87
|
leftdata &= (1 << leftbits) - 1;
|
|
100
88
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
89
|
+
}
|
|
103
90
|
|
|
91
|
+
// If there are any bits left, the base64 string was corrupted
|
|
104
92
|
if (leftbits) {
|
|
105
93
|
var err = new Error('Corrupted base64 string');
|
|
106
94
|
err.name = 'Base64-Error';
|
|
107
95
|
throw err;
|
|
108
96
|
}
|
|
109
|
-
|
|
110
97
|
return result;
|
|
111
98
|
}
|
|
112
|
-
};
|
|
113
|
-
/* End of Base64 namespace */
|
|
114
|
-
|
|
99
|
+
}; /* End of Base64 namespace */
|
|
115
100
|
exports["default"] = _default;
|
package/lib/decoders/copyrect.js
CHANGED
|
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports["default"] = void 0;
|
|
7
|
-
|
|
8
7
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
9
|
-
|
|
10
8
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
11
|
-
|
|
12
9
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
13
|
-
|
|
14
10
|
/*
|
|
15
11
|
* noVNC: HTML5 VNC client
|
|
16
12
|
* Copyright (C) 2019 The noVNC Authors
|
|
@@ -18,32 +14,25 @@ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _d
|
|
|
18
14
|
*
|
|
19
15
|
* See README.md for usage and integration instructions.
|
|
20
16
|
*
|
|
21
|
-
*/
|
|
22
|
-
var CopyRectDecoder = /*#__PURE__*/function () {
|
|
17
|
+
*/var CopyRectDecoder = /*#__PURE__*/function () {
|
|
23
18
|
function CopyRectDecoder() {
|
|
24
19
|
_classCallCheck(this, CopyRectDecoder);
|
|
25
20
|
}
|
|
26
|
-
|
|
27
21
|
_createClass(CopyRectDecoder, [{
|
|
28
22
|
key: "decodeRect",
|
|
29
23
|
value: function decodeRect(x, y, width, height, sock, display, depth) {
|
|
30
24
|
if (sock.rQwait("COPYRECT", 4)) {
|
|
31
25
|
return false;
|
|
32
26
|
}
|
|
33
|
-
|
|
34
27
|
var deltaX = sock.rQshift16();
|
|
35
28
|
var deltaY = sock.rQshift16();
|
|
36
|
-
|
|
37
29
|
if (width === 0 || height === 0) {
|
|
38
30
|
return true;
|
|
39
31
|
}
|
|
40
|
-
|
|
41
32
|
display.copyImage(deltaX, deltaY, x, y, width, height);
|
|
42
33
|
return true;
|
|
43
34
|
}
|
|
44
35
|
}]);
|
|
45
|
-
|
|
46
36
|
return CopyRectDecoder;
|
|
47
37
|
}();
|
|
48
|
-
|
|
49
38
|
exports["default"] = CopyRectDecoder;
|