mirror of
https://github.com/novnc/noVNC.git
synced 2026-06-08 13:24:38 +00:00
Use Typed Arrays for the send queue
This commit converts the send queue to use typed arrays, and converts message creation functions in 'rfb.js' to create messages directly into the socket's send queue. This commit also removes the separate mouse array, which is no longer needed.
This commit is contained in:
256
include/rfb.js
256
include/rfb.js
@@ -259,14 +259,14 @@ var RFB;
|
||||
if (this._rfb_state !== 'normal' || this._view_only) { return false; }
|
||||
Util.Info("Sending Ctrl-Alt-Del");
|
||||
|
||||
var arr = [];
|
||||
arr = arr.concat(RFB.messages.keyEvent(XK_Control_L, 1));
|
||||
arr = arr.concat(RFB.messages.keyEvent(XK_Alt_L, 1));
|
||||
arr = arr.concat(RFB.messages.keyEvent(XK_Delete, 1));
|
||||
arr = arr.concat(RFB.messages.keyEvent(XK_Delete, 0));
|
||||
arr = arr.concat(RFB.messages.keyEvent(XK_Alt_L, 0));
|
||||
arr = arr.concat(RFB.messages.keyEvent(XK_Control_L, 0));
|
||||
this._sock.send(arr);
|
||||
RFB.messages.keyEvent(this._sock, XK_Control_L, 1);
|
||||
RFB.messages.keyEvent(this._sock, XK_Alt_L, 1);
|
||||
RFB.messages.keyEvent(this._sock, XK_Delete, 1);
|
||||
RFB.messages.keyEvent(this._sock, XK_Delete, 0);
|
||||
RFB.messages.keyEvent(this._sock, XK_Alt_L, 0);
|
||||
RFB.messages.keyEvent(this._sock, XK_Control_L, 0);
|
||||
|
||||
this._sock.flush();
|
||||
},
|
||||
|
||||
xvpOp: function (ver, op) {
|
||||
@@ -292,21 +292,22 @@ var RFB;
|
||||
// followed by an up key.
|
||||
sendKey: function (code, down) {
|
||||
if (this._rfb_state !== "normal" || this._view_only) { return false; }
|
||||
var arr = [];
|
||||
if (typeof down !== 'undefined') {
|
||||
Util.Info("Sending key code (" + (down ? "down" : "up") + "): " + code);
|
||||
arr = arr.concat(RFB.messages.keyEvent(code, down ? 1 : 0));
|
||||
RFB.messages.keyEvent(this._sock, code, down ? 1 : 0);
|
||||
} else {
|
||||
Util.Info("Sending key code (down + up): " + code);
|
||||
arr = arr.concat(RFB.messages.keyEvent(code, 1));
|
||||
arr = arr.concat(RFB.messages.keyEvent(code, 0));
|
||||
RFB.messages.keyEvent(this._sock, code, 1);
|
||||
RFB.messages.keyEvent(this._sock, code, 0);
|
||||
}
|
||||
this._sock.send(arr);
|
||||
|
||||
this._sock.flush();
|
||||
},
|
||||
|
||||
clipboardPasteFrom: function (text) {
|
||||
if (this._rfb_state !== 'normal') { return; }
|
||||
this._sock.send(RFB.messages.clientCutText(text));
|
||||
RFB.messages.clientCutText(this._sock, text);
|
||||
this._sock.flush();
|
||||
},
|
||||
|
||||
setDesktopSize: function (width, height) {
|
||||
@@ -572,16 +573,10 @@ var RFB;
|
||||
}
|
||||
},
|
||||
|
||||
_checkEvents: function () {
|
||||
if (this._rfb_state === 'normal' && !this._viewportDragging && this._mouse_arr.length > 0) {
|
||||
this._sock.send(this._mouse_arr);
|
||||
this._mouse_arr = [];
|
||||
}
|
||||
},
|
||||
|
||||
_handleKeyPress: function (keysym, down) {
|
||||
if (this._view_only) { return; } // View only, skip keyboard, events
|
||||
this._sock.send(RFB.messages.keyEvent(keysym, down));
|
||||
RFB.messages.keyEvent(this._sock, keysym, down);
|
||||
this._sock.flush();
|
||||
},
|
||||
|
||||
_handleMouseButton: function (x, y, down, bmask) {
|
||||
@@ -605,10 +600,8 @@ var RFB;
|
||||
|
||||
if (this._view_only) { return; } // View only, skip mouse events
|
||||
|
||||
this._mouse_arr = this._mouse_arr.concat(
|
||||
RFB.messages.pointerEvent(this._display.absX(x), this._display.absY(y), this._mouse_buttonMask));
|
||||
this._sock.send(this._mouse_arr);
|
||||
this._mouse_arr = [];
|
||||
if (this._rfb_state !== "normal") { return; }
|
||||
RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask);
|
||||
},
|
||||
|
||||
_handleMouseMove: function (x, y) {
|
||||
@@ -625,10 +618,8 @@ var RFB;
|
||||
|
||||
if (this._view_only) { return; } // View only, skip mouse events
|
||||
|
||||
this._mouse_arr = this._mouse_arr.concat(
|
||||
RFB.messages.pointerEvent(this._display.absX(x), this._display.absY(y), this._mouse_buttonMask));
|
||||
|
||||
this._checkEvents();
|
||||
if (this._rfb_state !== "normal") { return; }
|
||||
RFB.messages.pointerEvent(this._sock, this._display.absX(x), this._display.absY(y), this._mouse_buttonMask);
|
||||
},
|
||||
|
||||
// Message Handlers
|
||||
@@ -895,7 +886,7 @@ var RFB;
|
||||
/* Screen size */
|
||||
this._fb_width = this._sock.rQshift16();
|
||||
this._fb_height = this._sock.rQshift16();
|
||||
this._dest_buff = new Uint8Array(this._fb_width * this._fb_height * 4);
|
||||
this._destBuff = new Uint8Array(this._fb_width * this._fb_height * 4);
|
||||
|
||||
/* PIXEL_FORMAT */
|
||||
var bpp = this._sock.rQshift8();
|
||||
@@ -991,18 +982,13 @@ var RFB;
|
||||
this._fb_depth = 1;
|
||||
}
|
||||
|
||||
var response = RFB.messages.pixelFormat(this._fb_Bpp, this._fb_depth, this._true_color);
|
||||
response = response.concat(
|
||||
RFB.messages.clientEncodings(this._encodings, this._local_cursor, this._true_color));
|
||||
response = response.concat(
|
||||
RFB.messages.fbUpdateRequests(this._display.getCleanDirtyReset(),
|
||||
this._fb_width, this._fb_height));
|
||||
RFB.messages.pixelFormat(this._sock, this._fb_Bpp, this._fb_depth, this._true_color);
|
||||
RFB.messages.clientEncodings(this._sock, this._encodings, this._local_cursor, this._true_color);
|
||||
RFB.messages.fbUpdateRequests(this._sock, this._display.getCleanDirtyReset(), this._fb_width, this._fb_height);
|
||||
|
||||
this._timing.fbu_rt_start = (new Date()).getTime();
|
||||
this._timing.pixels = 0;
|
||||
this._sock.send(response);
|
||||
|
||||
this._checkEvents();
|
||||
this._sock.flush();
|
||||
|
||||
if (this._encrypt) {
|
||||
this._updateState('normal', 'Connected (encrypted) to: ' + this._fb_name);
|
||||
@@ -1104,8 +1090,8 @@ var RFB;
|
||||
case 0: // FramebufferUpdate
|
||||
var ret = this._framebufferUpdate();
|
||||
if (ret) {
|
||||
this._sock.send(RFB.messages.fbUpdateRequests(this._display.getCleanDirtyReset(),
|
||||
this._fb_width, this._fb_height));
|
||||
RFB.messages.fbUpdateRequests(this._sock, this._display.getCleanDirtyReset(), this._fb_width, this._fb_height);
|
||||
this._sock.flush();
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -1279,64 +1265,111 @@ var RFB;
|
||||
|
||||
// Class Methods
|
||||
RFB.messages = {
|
||||
keyEvent: function (keysym, down) {
|
||||
var arr = [4];
|
||||
arr.push8(down);
|
||||
arr.push16(0);
|
||||
arr.push32(keysym);
|
||||
return arr;
|
||||
keyEvent: function (sock, keysym, down) {
|
||||
var buff = sock._sQ;
|
||||
var offset = sock._sQlen;
|
||||
|
||||
buff[offset] = 4; // msg-type
|
||||
buff[offset + 1] = down;
|
||||
|
||||
buff[offset + 2] = 0;
|
||||
buff[offset + 3] = 0;
|
||||
|
||||
buff[offset + 4] = (keysym >> 24);
|
||||
buff[offset + 5] = (keysym >> 16);
|
||||
buff[offset + 6] = (keysym >> 8);
|
||||
buff[offset + 7] = keysym;
|
||||
|
||||
sock._sQlen += 8;
|
||||
},
|
||||
|
||||
pointerEvent: function (x, y, mask) {
|
||||
var arr = [5]; // msg-type
|
||||
arr.push8(mask);
|
||||
arr.push16(x);
|
||||
arr.push16(y);
|
||||
return arr;
|
||||
pointerEvent: function (sock, x, y, mask) {
|
||||
var buff = sock._sQ;
|
||||
var offset = sock._sQlen;
|
||||
|
||||
buff[offset] = 5; // msg-type
|
||||
|
||||
buff[offset + 1] = mask;
|
||||
|
||||
buff[offset + 2] = x >> 8;
|
||||
buff[offset + 3] = x;
|
||||
|
||||
buff[offset + 4] = y >> 8;
|
||||
buff[offset + 5] = y;
|
||||
|
||||
sock._sQlen += 6;
|
||||
},
|
||||
|
||||
// TODO(directxman12): make this unicode compatible?
|
||||
clientCutText: function (text) {
|
||||
var arr = [6]; // msg-type
|
||||
arr.push8(0); // padding
|
||||
arr.push8(0); // padding
|
||||
arr.push8(0); // padding
|
||||
arr.push32(text.length);
|
||||
clientCutText: function (sock, text) {
|
||||
var buff = sock._sQ;
|
||||
var offset = sock._sQlen;
|
||||
|
||||
buff[offset] = 6; // msg-type
|
||||
|
||||
buff[offset + 1] = 0; // padding
|
||||
buff[offset + 2] = 0; // padding
|
||||
buff[offset + 3] = 0; // padding
|
||||
|
||||
var n = text.length;
|
||||
|
||||
buff[offset + 4] = n >> 24;
|
||||
buff[offset + 5] = n >> 16;
|
||||
buff[offset + 6] = n >> 8;
|
||||
buff[offset + 7] = n;
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
arr.push(text.charCodeAt(i));
|
||||
buff[offset + 8 + i] = text.charCodeAt(i);
|
||||
}
|
||||
|
||||
return arr;
|
||||
sock._sQlen += 8 + n;
|
||||
},
|
||||
|
||||
pixelFormat: function (bpp, depth, true_color) {
|
||||
var arr = [0]; // msg-type
|
||||
arr.push8(0); // padding
|
||||
arr.push8(0); // padding
|
||||
arr.push8(0); // padding
|
||||
pixelFormat: function (sock, bpp, depth, true_color) {
|
||||
var buff = sock._sQ;
|
||||
var offset = sock._sQlen;
|
||||
|
||||
arr.push8(bpp * 8); // bits-per-pixel
|
||||
arr.push8(depth * 8); // depth
|
||||
arr.push8(0); // little-endian
|
||||
arr.push8(true_color ? 1 : 0); // true-color
|
||||
buff[offset] = 0; // msg-type
|
||||
|
||||
arr.push16(255); // red-max
|
||||
arr.push16(255); // green-max
|
||||
arr.push16(255); // blue-max
|
||||
arr.push8(16); // red-shift
|
||||
arr.push8(8); // green-shift
|
||||
arr.push8(0); // blue-shift
|
||||
buff[offset + 1] = 0; // padding
|
||||
buff[offset + 2] = 0; // padding
|
||||
buff[offset + 3] = 0; // padding
|
||||
|
||||
arr.push8(0); // padding
|
||||
arr.push8(0); // padding
|
||||
arr.push8(0); // padding
|
||||
return arr;
|
||||
buff[offset + 4] = bpp * 8; // bits-per-pixel
|
||||
buff[offset + 5] = depth * 8; // depth
|
||||
buff[offset + 6] = 0; // little-endian
|
||||
buff[offset + 7] = true_color ? 1 : 0; // true-color
|
||||
|
||||
buff[offset + 8] = 0; // red-max
|
||||
buff[offset + 9] = 255; // red-max
|
||||
|
||||
buff[offset + 10] = 0; // green-max
|
||||
buff[offset + 11] = 255; // green-max
|
||||
|
||||
buff[offset + 12] = 0; // blue-max
|
||||
buff[offset + 13] = 255; // blue-max
|
||||
|
||||
buff[offset + 14] = 16; // red-shift
|
||||
buff[offset + 15] = 8; // green-shift
|
||||
buff[offset + 16] = 0; // blue-shift
|
||||
|
||||
buff[offset + 17] = 0; // padding
|
||||
buff[offset + 18] = 0; // padding
|
||||
buff[offset + 19] = 0; // padding
|
||||
|
||||
sock._sQlen += 20;
|
||||
},
|
||||
|
||||
clientEncodings: function (encodings, local_cursor, true_color) {
|
||||
var i, encList = [];
|
||||
clientEncodings: function (sock, encodings, local_cursor, true_color) {
|
||||
var buff = sock._sQ;
|
||||
var offset = sock._sQlen;
|
||||
|
||||
buff[offset] = 2; // msg-type
|
||||
buff[offset + 1] = 0; // padding
|
||||
|
||||
// offset + 2 and offset + 3 are encoding count
|
||||
|
||||
var i, j = offset + 4, cnt = 0;
|
||||
for (i = 0; i < encodings.length; i++) {
|
||||
if (encodings[i][0] === "Cursor" && !local_cursor) {
|
||||
Util.Debug("Skipping Cursor pseudo-encoding");
|
||||
@@ -1344,23 +1377,25 @@ var RFB;
|
||||
// TODO: remove this when we have tight+non-true-color
|
||||
Util.Warn("Skipping tight as it is only supported with true color");
|
||||
} else {
|
||||
encList.push(encodings[i][1]);
|
||||
var enc = encodings[i][1];
|
||||
buff[j] = enc >> 24;
|
||||
buff[j + 1] = enc >> 16;
|
||||
buff[j + 2] = enc >> 8;
|
||||
buff[j + 3] = enc;
|
||||
|
||||
j += 4;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
var arr = [2]; // msg-type
|
||||
arr.push8(0); // padding
|
||||
buff[offset + 2] = cnt >> 8;
|
||||
buff[offset + 3] = cnt;
|
||||
|
||||
arr.push16(encList.length); // encoding count
|
||||
for (i = 0; i < encList.length; i++) {
|
||||
arr.push32(encList[i]);
|
||||
}
|
||||
|
||||
return arr;
|
||||
sock._sQlen += j - offset;
|
||||
},
|
||||
|
||||
fbUpdateRequests: function (cleanDirty, fb_width, fb_height) {
|
||||
var arr = [];
|
||||
fbUpdateRequests: function (sock, cleanDirty, fb_width, fb_height) {
|
||||
var offsetIncrement = 0;
|
||||
|
||||
var cb = cleanDirty.cleanBox;
|
||||
var w, h;
|
||||
@@ -1368,7 +1403,7 @@ var RFB;
|
||||
w = typeof cb.w === "undefined" ? fb_width : cb.w;
|
||||
h = typeof cb.h === "undefined" ? fb_height : cb.h;
|
||||
// Request incremental for clean box
|
||||
arr = arr.concat(RFB.messages.fbUpdateRequest(1, cb.x, cb.y, w, h));
|
||||
RFB.messages.fbUpdateRequest(sock, 1, cb.x, cb.y, w, h);
|
||||
}
|
||||
|
||||
for (var i = 0; i < cleanDirty.dirtyBoxes.length; i++) {
|
||||
@@ -1376,24 +1411,33 @@ var RFB;
|
||||
// Force all (non-incremental) for dirty box
|
||||
w = typeof db.w === "undefined" ? fb_width : db.w;
|
||||
h = typeof db.h === "undefined" ? fb_height : db.h;
|
||||
arr = arr.concat(RFB.messages.fbUpdateRequest(0, db.x, db.y, w, h));
|
||||
RFB.messages.fbUpdateRequest(sock, 0, db.x, db.y, w, h);
|
||||
}
|
||||
|
||||
return arr;
|
||||
},
|
||||
|
||||
fbUpdateRequest: function (incremental, x, y, w, h) {
|
||||
fbUpdateRequest: function (sock, incremental, x, y, w, h) {
|
||||
var buff = sock._sQ;
|
||||
var offset = sock._sQlen;
|
||||
|
||||
if (typeof(x) === "undefined") { x = 0; }
|
||||
if (typeof(y) === "undefined") { y = 0; }
|
||||
|
||||
var arr = [3]; // msg-type
|
||||
arr.push8(incremental);
|
||||
arr.push16(x);
|
||||
arr.push16(y);
|
||||
arr.push16(w);
|
||||
arr.push16(h);
|
||||
buff[offset] = 3; // msg-type
|
||||
buff[offset + 1] = incremental;
|
||||
|
||||
return arr;
|
||||
buff[offset + 2] = (x >> 8) & 0xFF;
|
||||
buff[offset + 3] = x & 0xFF;
|
||||
|
||||
buff[offset + 4] = (y >> 8) & 0xFF;
|
||||
buff[offset + 5] = y & 0xFF;
|
||||
|
||||
buff[offset + 6] = (w >> 8) & 0xFF;
|
||||
buff[offset + 7] = w & 0xFF;
|
||||
|
||||
buff[offset + 8] = (h >> 8) & 0xFF;
|
||||
buff[offset + 9] = h & 0xFF;
|
||||
|
||||
sock._sQlen += 10;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user