]>
Commit | Line | Data |
---|---|---|
d595e656 JM |
1 | /* |
2 | * noVNC: HTML5 VNC client | |
d58f8b51 | 3 | * Copyright (C) 2012 Joel Martin |
1d728ace | 4 | * Licensed under MPL 2.0 (see LICENSE.txt) |
d595e656 JM |
5 | */ |
6 | ||
7 | "use strict"; | |
8 | /*jslint browser: true, white: false */ | |
9 | /*global Util, VNC_frame_data, finish */ | |
10 | ||
b8bd88d0 | 11 | var rfb, mode, test_state, frame_idx, frame_length, |
d951b409 | 12 | iteration, iterations, istart_time, encoding, |
d595e656 JM |
13 | |
14 | // Pre-declarations for jslint | |
18e96092 PO |
15 | send_array, next_iteration, end_iteration, queue_next_packet, |
16 | do_packet, enable_test_mode; | |
b8bd88d0 JM |
17 | |
18 | // Override send_array | |
19 | send_array = function (arr) { | |
20 | // Stub out send_array | |
d595e656 | 21 | }; |
b8bd88d0 | 22 | |
e12e2759 PO |
23 | // Immediate polyfill |
24 | if (window.setImmediate === undefined) { | |
25 | var _immediateIdCounter = 1; | |
26 | var _immediateFuncs = {}; | |
27 | ||
28 | window.setImmediate = function (func) { | |
29 | var index = Util._immediateIdCounter++; | |
30 | _immediateFuncs[index] = func; | |
31 | window.postMessage("noVNC immediate trigger:" + index, "*"); | |
32 | return index; | |
33 | }; | |
34 | ||
35 | window.clearImmediate = function (id) { | |
36 | _immediateFuncs[id]; | |
37 | }; | |
38 | ||
39 | var _onMessage = function (event) { | |
40 | if ((typeof event.data !== "string") || | |
41 | (event.data.indexOf("noVNC immediate trigger:") !== 0)) { | |
42 | return; | |
43 | } | |
44 | ||
45 | var index = event.data.slice("noVNC immediate trigger:".length); | |
46 | ||
47 | var callback = _immediateFuncs[index]; | |
48 | if (callback === undefined) { | |
49 | return; | |
50 | } | |
51 | ||
52 | delete _immediateFuncs[index]; | |
53 | ||
54 | callback(); | |
55 | }; | |
56 | window.addEventListener("message", _onMessage); | |
57 | } | |
58 | ||
efed2eea | 59 | enable_test_mode = function () { |
efed2eea SR |
60 | rfb._sock.send = send_array; |
61 | rfb._sock.close = function () {}; | |
62 | rfb._sock.flush = function () {}; | |
63 | rfb._checkEvents = function () {}; | |
64 | rfb.connect = function (host, port, password, path) { | |
65 | this._rfb_host = host; | |
66 | this._rfb_port = port; | |
67 | this._rfb_password = (password !== undefined) ? password : ""; | |
68 | this._rfb_path = (path !== undefined) ? path : ""; | |
38781d93 | 69 | this._sock.init('binary', 'ws'); |
f9e26cdb PO |
70 | this._rfb_connection_state = 'connecting'; |
71 | this._rfb_init_state = 'ProtocolVersion'; | |
efed2eea SR |
72 | }; |
73 | }; | |
74 | ||
d595e656 | 75 | next_iteration = function () { |
ae510306 | 76 | rfb = new RFB({'target': document.getElementById('VNC_canvas'), |
7632c576 | 77 | 'view_only': true, |
f9e26cdb PO |
78 | 'onDisconnected': disconnected, |
79 | 'onNotification': notification}); | |
efed2eea SR |
80 | enable_test_mode(); |
81 | ||
d951b409 PO |
82 | // Missing in older recordings |
83 | if (typeof VNC_frame_encoding === 'undefined') { | |
84 | var frame = VNC_frame_data[0]; | |
85 | var start = frame.indexOf('{', 1) + 1; | |
86 | if (frame.slice(start).startsWith('UkZC')) { | |
87 | encoding = 'base64'; | |
88 | } else { | |
89 | encoding = 'binary'; | |
90 | } | |
91 | } else { | |
92 | encoding = VNC_frame_encoding; | |
93 | } | |
94 | ||
b8bd88d0 JM |
95 | if (iteration === 0) { |
96 | frame_length = VNC_frame_data.length; | |
97 | test_state = 'running'; | |
b8bd88d0 | 98 | } |
38781d93 | 99 | |
b8bd88d0 JM |
100 | if (test_state !== 'running') { return; } |
101 | ||
d595e656 | 102 | iteration += 1; |
b8bd88d0 JM |
103 | if (iteration > iterations) { |
104 | finish(); | |
105 | return; | |
106 | } | |
107 | ||
108 | frame_idx = 0; | |
109 | istart_time = (new Date()).getTime(); | |
110 | rfb.connect('test', 0, "bogus"); | |
111 | ||
112 | queue_next_packet(); | |
113 | ||
d595e656 | 114 | }; |
b8bd88d0 | 115 | |
18e96092 PO |
116 | end_iteration = function () { |
117 | if (rfb._display.pending()) { | |
118 | rfb._display.set_onFlush(function () { | |
119 | if (rfb._flushing) { | |
120 | rfb._onFlush(); | |
121 | } | |
122 | end_iteration(); | |
123 | }); | |
124 | rfb._display.flush(); | |
125 | } else { | |
126 | next_iteration(); | |
127 | } | |
128 | }; | |
129 | ||
d595e656 JM |
130 | queue_next_packet = function () { |
131 | var frame, foffset, toffset, delay; | |
b8bd88d0 JM |
132 | if (test_state !== 'running') { return; } |
133 | ||
134 | frame = VNC_frame_data[frame_idx]; | |
135 | while ((frame_idx < frame_length) && (frame.charAt(0) === "}")) { | |
136 | //Util.Debug("Send frame " + frame_idx); | |
137 | frame_idx += 1; | |
138 | frame = VNC_frame_data[frame_idx]; | |
139 | } | |
140 | ||
141 | if (frame === 'EOF') { | |
142 | Util.Debug("Finished, found EOF"); | |
18e96092 | 143 | end_iteration(); |
b8bd88d0 JM |
144 | return; |
145 | } | |
146 | if (frame_idx >= frame_length) { | |
147 | Util.Debug("Finished, no more frames"); | |
18e96092 | 148 | end_iteration(); |
b8bd88d0 JM |
149 | return; |
150 | } | |
151 | ||
152 | if (mode === 'realtime') { | |
153 | foffset = frame.slice(1, frame.indexOf('{', 1)); | |
154 | toffset = (new Date()).getTime() - istart_time; | |
155 | delay = foffset - toffset; | |
156 | if (delay < 1) { | |
157 | delay = 1; | |
158 | } | |
159 | ||
160 | setTimeout(do_packet, delay); | |
161 | } else { | |
e12e2759 | 162 | window.setImmediate(do_packet); |
b8bd88d0 | 163 | } |
d595e656 | 164 | }; |
b8bd88d0 | 165 | |
e7e66602 JM |
166 | var bytes_processed = 0; |
167 | ||
d595e656 | 168 | do_packet = function () { |
18e96092 PO |
169 | // Avoid having an excessive queue buildup |
170 | if (rfb._flushing && (mode !== 'realtime')) { | |
171 | rfb._display.set_onFlush(function () { | |
172 | rfb._display.set_onFlush(rfb._onFlush.bind(rfb)); | |
173 | rfb._onFlush(); | |
174 | do_packet(); | |
175 | }); | |
176 | return; | |
177 | } | |
178 | ||
b8bd88d0 | 179 | //Util.Debug("Processing frame: " + frame_idx); |
e7e66602 JM |
180 | var frame = VNC_frame_data[frame_idx], |
181 | start = frame.indexOf('{', 1) + 1; | |
d951b409 PO |
182 | var u8; |
183 | if (encoding === 'base64') { | |
184 | u8 = Base64.decode(frame.slice(start)); | |
185 | start = 0; | |
186 | } else { | |
187 | u8 = new Uint8Array(frame.length - start); | |
e7e66602 JM |
188 | for (var i = 0; i < frame.length - start; i++) { |
189 | u8[i] = frame.charCodeAt(start + i); | |
190 | } | |
e7e66602 | 191 | } |
d951b409 PO |
192 | bytes_processed += u8.length; |
193 | rfb._sock._recv_message({'data' : u8}); | |
b8bd88d0 JM |
194 | frame_idx += 1; |
195 | ||
196 | queue_next_packet(); | |
d595e656 | 197 | }; |
b8bd88d0 | 198 |