diff --git a/core/encodings.js b/core/encodings.js index 9fd38d58..e8b0479e 100644 --- a/core/encodings.js +++ b/core/encodings.js @@ -20,6 +20,7 @@ export const encodings = { pseudoEncodingLastRect: -224, pseudoEncodingCursor: -239, pseudoEncodingQEMUExtendedKeyEvent: -258, + pseudoEncodingDesktopName: -307, pseudoEncodingExtendedDesktopSize: -308, pseudoEncodingXvp: -309, pseudoEncodingFence: -312, diff --git a/core/rfb.js b/core/rfb.js index 1761500a..f1f8cd7c 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -464,6 +464,13 @@ export default class RFB extends EventTargetMixin { this.focus(); } + _setDesktopName(name) { + this._fb_name = name; + this.dispatchEvent(new CustomEvent( + "desktopname", + { detail: { name: this._fb_name } })); + } + _windowResize(event) { // If the window resized then our screen element might have // as well. Update the viewport dimensions. @@ -1148,7 +1155,7 @@ export default class RFB extends EventTargetMixin { /* Connection name/title */ const name_length = this._sock.rQshift32(); if (this._sock.rQwait('server init name', name_length, 24)) { return false; } - this._fb_name = decodeUTF8(this._sock.rQshiftStr(name_length)); + let name = decodeUTF8(this._sock.rQshiftStr(name_length)); if (this._rfb_tightvnc) { if (this._sock.rQwait('TightVNC extended server init header', 8, 24 + name_length)) { return false; } @@ -1188,10 +1195,7 @@ export default class RFB extends EventTargetMixin { ", blue_shift: " + blue_shift); // we're past the point where we could backtrack, so it's safe to call this - this.dispatchEvent(new CustomEvent( - "desktopname", - { detail: { name: this._fb_name } })); - + this._setDesktopName(name); this._resize(width, height); if (!this._viewOnly) { this._keyboard.grab(); } @@ -1237,6 +1241,7 @@ export default class RFB extends EventTargetMixin { encs.push(encodings.pseudoEncodingXvp); encs.push(encodings.pseudoEncodingFence); encs.push(encodings.pseudoEncodingContinuousUpdates); + encs.push(encodings.pseudoEncodingDesktopName); if (this._fb_depth == 24) { encs.push(encodings.pseudoEncodingCursor); @@ -1503,6 +1508,9 @@ export default class RFB extends EventTargetMixin { } return true; + case encodings.pseudoEncodingDesktopName: + return this._handleDesktopName(); + case encodings.pseudoEncodingDesktopSize: this._resize(this._FBU.width, this._FBU.height); return true; @@ -1552,6 +1560,25 @@ export default class RFB extends EventTargetMixin { return true; } + _handleDesktopName() { + if (this._sock.rQwait("DesktopName", 4)) { + return false; + } + + let length = this._sock.rQshift32(); + + if (this._sock.rQwait("DesktopName", length, 4)) { + return false; + } + + let name = this._sock.rQshiftStr(length); + name = decodeUTF8(name); + + this._setDesktopName(name); + + return true; + } + _handleExtendedDesktopSize() { if (this._sock.rQwait("ExtendedDesktopSize", 4)) { return false; diff --git a/tests/test.rfb.js b/tests/test.rfb.js index 1563a1e2..720d92df 100644 --- a/tests/test.rfb.js +++ b/tests/test.rfb.js @@ -41,6 +41,13 @@ function push32(arr, num) { num & 0xFF); } +function pushString(arr, string) { + let utf8 = unescape(encodeURIComponent(string)); + for (let i = 0; i < utf8.length; i++) { + arr.push(utf8.charCodeAt(i)); + } +} + describe('Remote Frame Buffer Protocol Client', function () { let clock; let raf; @@ -2128,6 +2135,21 @@ describe('Remote Frame Buffer Protocol Client', function () { send_fbu_msg([{ x: 0, y: 0, width: 0, height: 0, encoding: -224}], [[]], client, 100); expect(client._FBU.rects).to.equal(0); }); + + it('should handle the DesktopName pseudo-encoding', function () { + let data = []; + push32(data, 9); + pushString(data, "some name"); + + const spy = sinon.spy(); + client.addEventListener("desktopname", spy); + + send_fbu_msg([{ x: 0, y: 0, width: 0, height: 0, encoding: -307 }], [data], client); + + expect(client._fb_name).to.equal('some name'); + expect(spy).to.have.been.calledOnce; + expect(spy.args[0][0].detail.name).to.equal('some name'); + }); }); });