[go: nahoru, domu]

Skip to content

Commit

Permalink
Use Typed Arrays for the send queue
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
DirectXMan12 committed Aug 6, 2015
1 parent d1800d0 commit 9ff86fb
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 219 deletions.
262 changes: 153 additions & 109 deletions include/rfb.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -1279,121 +1265,179 @@ 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

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

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

arr.push8(0); // padding
arr.push8(0); // padding
arr.push8(0); // padding
return arr;
pixelFormat: function (sock, bpp, depth, true_color) {
var buff = sock._sQ;
var offset = sock._sQlen;

buff[offset] = 0; // msg-type

buff[offset + 1] = 0; // padding
buff[offset + 2] = 0; // padding
buff[offset + 3] = 0; // padding

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");
} else if (encodings[i][0] === "TIGHT" && !true_color) {
// 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;
if (cb.w > 0 && cb.h > 0) {
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++) {
var db = cleanDirty.dirtyBoxes[i];
// 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;

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;

return arr;
sock._sQlen += 10;
}
};

Expand Down
Loading

0 comments on commit 9ff86fb

Please sign in to comment.