mirror of
https://github.com/novnc/noVNC.git
synced 2026-05-26 15:13:34 +00:00
There might be operations pending in the render queue. Make sure these are fully handled before we consider the test run over.
199 lines
5.1 KiB
JavaScript
199 lines
5.1 KiB
JavaScript
/*
|
|
* noVNC: HTML5 VNC client
|
|
* Copyright (C) 2012 Joel Martin
|
|
* Licensed under MPL 2.0 (see LICENSE.txt)
|
|
*/
|
|
|
|
"use strict";
|
|
/*jslint browser: true, white: false */
|
|
/*global Util, VNC_frame_data, finish */
|
|
|
|
var rfb, mode, test_state, frame_idx, frame_length,
|
|
iteration, iterations, istart_time, encoding,
|
|
|
|
// Pre-declarations for jslint
|
|
send_array, next_iteration, end_iteration, queue_next_packet,
|
|
do_packet, enable_test_mode;
|
|
|
|
// Override send_array
|
|
send_array = function (arr) {
|
|
// Stub out send_array
|
|
};
|
|
|
|
// Immediate polyfill
|
|
if (window.setImmediate === undefined) {
|
|
var _immediateIdCounter = 1;
|
|
var _immediateFuncs = {};
|
|
|
|
window.setImmediate = function (func) {
|
|
var index = Util._immediateIdCounter++;
|
|
_immediateFuncs[index] = func;
|
|
window.postMessage("noVNC immediate trigger:" + index, "*");
|
|
return index;
|
|
};
|
|
|
|
window.clearImmediate = function (id) {
|
|
_immediateFuncs[id];
|
|
};
|
|
|
|
var _onMessage = function (event) {
|
|
if ((typeof event.data !== "string") ||
|
|
(event.data.indexOf("noVNC immediate trigger:") !== 0)) {
|
|
return;
|
|
}
|
|
|
|
var index = event.data.slice("noVNC immediate trigger:".length);
|
|
|
|
var callback = _immediateFuncs[index];
|
|
if (callback === undefined) {
|
|
return;
|
|
}
|
|
|
|
delete _immediateFuncs[index];
|
|
|
|
callback();
|
|
};
|
|
window.addEventListener("message", _onMessage);
|
|
}
|
|
|
|
enable_test_mode = function () {
|
|
rfb._sock.send = send_array;
|
|
rfb._sock.close = function () {};
|
|
rfb._sock.flush = function () {};
|
|
rfb._checkEvents = function () {};
|
|
rfb.connect = function (host, port, password, path) {
|
|
this._rfb_host = host;
|
|
this._rfb_port = port;
|
|
this._rfb_password = (password !== undefined) ? password : "";
|
|
this._rfb_path = (path !== undefined) ? path : "";
|
|
this._sock.init('binary', 'ws');
|
|
this._rfb_connection_state = 'connecting';
|
|
this._rfb_init_state = 'ProtocolVersion';
|
|
};
|
|
};
|
|
|
|
next_iteration = function () {
|
|
rfb = new RFB({'target': document.getElementById('VNC_canvas'),
|
|
'view_only': true,
|
|
'onDisconnected': disconnected,
|
|
'onNotification': notification});
|
|
enable_test_mode();
|
|
|
|
// Missing in older recordings
|
|
if (typeof VNC_frame_encoding === 'undefined') {
|
|
var frame = VNC_frame_data[0];
|
|
var start = frame.indexOf('{', 1) + 1;
|
|
if (frame.slice(start).startsWith('UkZC')) {
|
|
encoding = 'base64';
|
|
} else {
|
|
encoding = 'binary';
|
|
}
|
|
} else {
|
|
encoding = VNC_frame_encoding;
|
|
}
|
|
|
|
if (iteration === 0) {
|
|
frame_length = VNC_frame_data.length;
|
|
test_state = 'running';
|
|
}
|
|
|
|
if (test_state !== 'running') { return; }
|
|
|
|
iteration += 1;
|
|
if (iteration > iterations) {
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
frame_idx = 0;
|
|
istart_time = (new Date()).getTime();
|
|
rfb.connect('test', 0, "bogus");
|
|
|
|
queue_next_packet();
|
|
|
|
};
|
|
|
|
end_iteration = function () {
|
|
if (rfb._display.pending()) {
|
|
rfb._display.set_onFlush(function () {
|
|
if (rfb._flushing) {
|
|
rfb._onFlush();
|
|
}
|
|
end_iteration();
|
|
});
|
|
rfb._display.flush();
|
|
} else {
|
|
next_iteration();
|
|
}
|
|
};
|
|
|
|
queue_next_packet = function () {
|
|
var frame, foffset, toffset, delay;
|
|
if (test_state !== 'running') { return; }
|
|
|
|
frame = VNC_frame_data[frame_idx];
|
|
while ((frame_idx < frame_length) && (frame.charAt(0) === "}")) {
|
|
//Util.Debug("Send frame " + frame_idx);
|
|
frame_idx += 1;
|
|
frame = VNC_frame_data[frame_idx];
|
|
}
|
|
|
|
if (frame === 'EOF') {
|
|
Util.Debug("Finished, found EOF");
|
|
end_iteration();
|
|
return;
|
|
}
|
|
if (frame_idx >= frame_length) {
|
|
Util.Debug("Finished, no more frames");
|
|
end_iteration();
|
|
return;
|
|
}
|
|
|
|
if (mode === 'realtime') {
|
|
foffset = frame.slice(1, frame.indexOf('{', 1));
|
|
toffset = (new Date()).getTime() - istart_time;
|
|
delay = foffset - toffset;
|
|
if (delay < 1) {
|
|
delay = 1;
|
|
}
|
|
|
|
setTimeout(do_packet, delay);
|
|
} else {
|
|
window.setImmediate(do_packet);
|
|
}
|
|
};
|
|
|
|
var bytes_processed = 0;
|
|
|
|
do_packet = function () {
|
|
// Avoid having an excessive queue buildup
|
|
if (rfb._flushing && (mode !== 'realtime')) {
|
|
rfb._display.set_onFlush(function () {
|
|
rfb._display.set_onFlush(rfb._onFlush.bind(rfb));
|
|
rfb._onFlush();
|
|
do_packet();
|
|
});
|
|
return;
|
|
}
|
|
|
|
//Util.Debug("Processing frame: " + frame_idx);
|
|
var frame = VNC_frame_data[frame_idx],
|
|
start = frame.indexOf('{', 1) + 1;
|
|
var u8;
|
|
if (encoding === 'base64') {
|
|
u8 = Base64.decode(frame.slice(start));
|
|
start = 0;
|
|
} else {
|
|
u8 = new Uint8Array(frame.length - start);
|
|
for (var i = 0; i < frame.length - start; i++) {
|
|
u8[i] = frame.charCodeAt(start + i);
|
|
}
|
|
}
|
|
bytes_processed += u8.length;
|
|
rfb._sock._recv_message({'data' : u8});
|
|
frame_idx += 1;
|
|
|
|
queue_next_packet();
|
|
};
|
|
|