fb_height = 0,
fb_name = "",
- cuttext = 'none', // ServerCutText wait state
- cuttext_length = 0,
-
scan_imgQ_rate = 100,
last_req_time = 0,
rre_chunk_sz = 100,
return rQ.slice(rQi-len, rQi);
}
+// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
+// to be available in the receive queue. Return true if we need to
+// wait (and possibly print a debug message), otherwise false.
+function rQwait(msg, num, goback) {
+ if (typeof num !== 'number') { num = FBU.bytes; }
+ var rQlen = rQ.length - rQi; // Skip rQlen() function call
+ if (rQlen < num) {
+ if (goback) {
+ if (rQi < goback) {
+ throw("rQwait cannot backup " + goback + " bytes");
+ }
+ rQi -= goback;
+ }
+ //Util.Debug(" waiting for " + (num-rQlen) +
+ // " " + msg + " byte(s)");
+ return true; // true means need more data
+ }
+ return false;
+}
+
+
//
// Setup routines
//
init_vars = function() {
/* Reset state */
- cuttext = 'none';
- cuttext_length = 0;
rQ = [];
rQi = 0;
sQ = "";
init_msg = function() {
//Util.Debug(">> init_msg [rfb_state '" + rfb_state + "']");
- var strlen, reason, reason_len, sversion, cversion,
+ var strlen, reason, length, sversion, cversion,
i, types, num_types, challenge, response, bpp, depth,
big_endian, true_color, name_length;
case 'Security' :
if (rfb_version >= 3.7) {
num_types = rQ[rQi++];
- if (rQlen() < num_types) {
- rQi--;
- Util.Debug(" waiting for security types");
- return;
- }
+ if (rQwait("security type", num_types, 1)) { return false; }
if (num_types === 0) {
strlen = rQshift32();
reason = rQshiftStr(strlen);
send_array([rfb_auth_scheme]);
} else {
- if (rQlen() < 4) {
- Util.Debug(" waiting for security scheme bytes");
- return;
- }
+ if (rQwait("security scheme", 4)) { return false; }
rfb_auth_scheme = rQshift32();
}
updateState('Authentication',
//Util.Debug("Security auth scheme: " + rfb_auth_scheme);
switch (rfb_auth_scheme) {
case 0: // connection failed
- if (rQlen() < 4) {
- Util.Debug(" waiting for auth reason bytes");
- return;
- }
+ if (rQwait("auth reason", 4)) { return false; }
strlen = rQshift32();
reason = rQshiftStr(strlen);
updateState('failed',
updateState('password', "Password Required");
return;
}
- if (rQlen() < 16) {
- Util.Debug(" waiting for auth challenge bytes");
- return;
- }
+ if (rQwait("auth challenge", 16)) { return false; }
challenge = rQshiftBytes(16);
//Util.Debug("Password: " + rfb_password);
//Util.Debug("Challenge: " + challenge +
break;
case 1: // failed
if (rfb_version >= 3.8) {
- reason_len = rQshift32();
- if (rQlen() < reason_len) {
- Util.Debug(" waiting for SecurityResult reason bytes");
- rQi -= 8; // Unshift the status and length
- return;
+ length = rQshift32();
+ if (rQwait("SecurityResult reason", length, 8)) {
+ return false;
}
reason = rQshiftStr(reason_len);
updateState('failed', reason);
normal_msg = function() {
//Util.Debug(">> normal_msg");
- var ret = true, msg_type,
+ var ret = true, msg_type, length,
c, first_colour, num_colours, red, green, blue;
if (FBU.rects > 0) {
msg_type = 0;
- } else if (cuttext !== 'none') {
- msg_type = 3;
} else {
msg_type = rQ[rQi++];
}
break;
case 3: // ServerCutText
Util.Debug("ServerCutText");
- Util.Debug("rQ:" + rQ.slice(0,20));
- if (cuttext === 'none') {
- cuttext = 'header';
- }
- if (cuttext === 'header') {
- if (rQlen() < 7) {
- //Util.Debug("waiting for ServerCutText header");
- return false;
- }
- rQshiftBytes(3); // Padding
- cuttext_length = rQshift32();
- }
- cuttext = 'bytes';
- if (rQlen() < cuttext_length) {
- //Util.Debug("waiting for ServerCutText bytes");
- return false;
- }
- conf.clipboardReceive(that, rQshiftStr(cuttext_length));
- cuttext = 'none';
+ if (rQwait("ServerCutText header", 7, 1)) { return false; }
+ rQshiftBytes(3); // Padding
+ length = rQshift32();
+ if (rQwait("ServerCutText", length, 8)) { return false; }
+
+ conf.clipboardReceive(that, rQshiftStr(length));
break;
default:
updateState('failed',
if (FBU.rects === 0) {
//Util.Debug("New FBU: rQ.slice(0,20): " + rQ.slice(0,20));
- if (rQlen() < 3) {
+ if (rQwait("FBU header", 3)) {
if (rQi === 0) {
rQ.unshift(0); // FBU msg_type
} else {
rQi -= 1;
}
- //Util.Debug(" waiting for FBU header bytes");
return false;
}
rQi++;
if (rfb_state !== "normal") {
return false;
}
- if (rQlen() < FBU.bytes) {
- //Util.Debug(" waiting for " + (FBU.bytes - rQlen()) + " FBU bytes");
- return false;
- }
+ if (rQwait("FBU")) { return false; }
if (FBU.bytes === 0) {
- if (rQlen() < 12) {
- //Util.Debug(" waiting for rect header bytes");
- return false;
- }
+ if (rQwait("rect header", 12)) { return false; }
/* New FramebufferUpdate */
hdr = rQshiftBytes(12);
FBU.lines = FBU.height;
}
FBU.bytes = FBU.width * fb_Bpp; // At least a line
- if (rQlen() < FBU.bytes) {
- //Util.Debug(" waiting for " +
- // (FBU.bytes - rQlen()) + " RAW bytes");
- return false;
- }
+ if (rQwait("RAW")) { return false; }
cur_y = FBU.y + (FBU.height - FBU.lines);
cur_height = Math.min(FBU.lines,
Math.floor(rQlen()/(FBU.width * fb_Bpp)));
var old_x, old_y;
- if (rQlen() < 4) {
- //Util.Debug(" waiting for " +
- // (FBU.bytes - rQlen()) + " COPYRECT bytes");
- return false;
- }
+ if (rQwait("COPYRECT", 4)) { return false; }
old_x = rQshift16();
old_y = rQshift16();
canvas.copyImage(old_x, old_y, FBU.x, FBU.y, FBU.width, FBU.height);
var color, x, y, width, height, chunk;
if (FBU.subrects === 0) {
- if (rQlen() < 4 + fb_Bpp) {
- //Util.Debug(" waiting for " +
- // (4 + fb_Bpp - rQlen()) + " RRE bytes");
- return false;
- }
+ if (rQwait("RRE", 4+fb_Bpp)) { return false; }
FBU.subrects = rQshift32();
color = rQshiftBytes(fb_Bpp); // Background
canvas.fillRect(FBU.x, FBU.y, FBU.width, FBU.height, color);
/* FBU.bytes comes in as 1, rQlen() at least 1 */
while (FBU.tiles > 0) {
FBU.bytes = 1;
- if (rQlen() < FBU.bytes) {
- //Util.Debug(" waiting for HEXTILE subencoding byte");
- return false;
- }
+ if (rQwait("HEXTILE subencoding")) { return false; }
//Util.Debug(" 2 rQ length: " + rQlen() + " rQ[rQi]: " + rQ[rQi] + " rQ.slice(rQi,rQi+20): " + rQ.slice(rQi,rQi+20) + ", FBU.rects: " + FBU.rects + ", FBU.tiles: " + FBU.tiles);
subencoding = rQ[rQi]; // Peek
if (subencoding > 30) { // Raw
}
if (subencoding & 0x08) { // AnySubrects
FBU.bytes += 1; // Since we aren't shifting it off
- if (rQlen() < FBU.bytes) {
- /* Wait for subrects byte */
- //Util.Debug(" waiting for hextile subrects header byte");
- return false;
- }
+ if (rQwait("hextile subrects header")) { return false; }
subrects = rQ[rQi + FBU.bytes-1]; // Peek
if (subencoding & 0x10) { // SubrectsColoured
FBU.bytes += subrects * (fb_Bpp + 2);
" last:" + rQ.slice(FBU.bytes-10, FBU.bytes) +
" next:" + rQ.slice(FBU.bytes-1, FBU.bytes+10));
*/
- if (rQlen() < FBU.bytes) {
- //Util.Debug(" waiting for " +
- // (FBU.bytes - rQlen()) + " hextile bytes");
- return false;
- }
+ if (rQwait("hextile")) { return false; }
/* We know the encoding and have a whole tile */
FBU.subencoding = rQ[rQi];
//Util.Debug(" starting rQ.slice(rQi,rQi+20): " + rQ.slice(rQi,rQi+20) + " (" + rQlen() + ")");
FBU.bytes = 1; // compression-control byte
- if (rQlen() < FBU.bytes) {
- Util.Debug(" waiting for TIGHT compression-control byte");
- return false;
- }
+ if (rQwait("TIGHT compression-control")) { return false; }
// Get 'compact length' header and data size
getCLength = function (arr, offset) {
case "png": FBU.bytes += 3; break; // max clength
}
- if (rQlen() < FBU.bytes) {
- Util.Debug(" waiting for TIGHT " + cmode + " bytes");
- return false;
- }
+ if (rQwait("TIGHT " + cmode)) { return false; }
//Util.Debug(" rQ.slice(0,20): " + rQ.slice(0,20) + " (" + rQlen() + ")");
//Util.Debug(" cmode: " + cmode);
case "png":
clength = getCLength(rQ, rQi+1);
FBU.bytes = 1 + clength[0] + clength[1]; // ctl + clength size + jpeg-data
- if (rQlen() < FBU.bytes) {
- Util.Debug(" waiting for TIGHT " + cmode + " bytes");
- return false;
- }
+ if (rQwait("TIGHT " + cmode)) { return false; }
// We have everything, render it
//Util.Debug(" png, rQlen(): " + rQlen() + ", clength[0]: " + clength[0] + ", clength[1]: " + clength[1]);
pixelslength = w * h * fb_Bpp;
masklength = Math.floor((w + 7) / 8) * h;
- if (rQlen() < (pixelslength + masklength)) {
- //Util.Debug("waiting for cursor encoding bytes");
- FBU.bytes = pixelslength + masklength;
- return false;
- }
+ FBU.bytes = pixelslength + masklength;
+ if (rQwait("cursor encoding")) { return false; }
//Util.Debug(" set_cursor, x: " + x + ", y: " + y + ", w: " + w + ", h: " + h);