summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Henrique Barboza <danielhb@linux.vnet.ibm.com>2016-04-11 07:11:05 -0300
committerDaniel Henrique Barboza <danielhb@linux.vnet.ibm.com>2016-08-26 17:34:39 -0300
commit8f06673a25c18f6a0cb4ae46db6ad7083875becc (patch)
tree1a76f3aa9d5d1ca4cd5f9116a68c543068133076
parent99feba6ba8fee5b3a2b2dc99dc25e9179c560d31 (diff)
downloadnovnc-8f06673a25c18f6a0cb4ae46db6ad7083875becc.tar.gz
QEMU RFB extension - rfb.js and input.js changes
In input.js, a new keyboard handler was added to deal exclusively with the QEMU key event extension. '_onKeyPress()' signature was changed to allow the same method to treat both cases. The extension will only be enabled if the browser has support for the KeyboardEvent.code property. Changes in rfb.js: - added a new extension code, QEMUExtendedKeyEvent, value -258. - handleKeyPress now receives 'keyevent' instead of 'keysym' and 'down'. Both values are retrieved from keyevent as they were in the previous signature. This method now can send QEMU RFB extended key messages if the flag was set to 'true'. - tests/test.rfb.js were changed folowing the onKeyPress() signature change. - added a new function to send the QEMU extended key message. Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com>
-rw-r--r--include/input.js10
-rw-r--r--include/rfb.js71
-rw-r--r--tests/test.rfb.js6
3 files changed, 81 insertions, 6 deletions
diff --git a/include/input.js b/include/input.js
index fa6ba44..eb4d18a 100644
--- a/include/input.js
+++ b/include/input.js
@@ -51,10 +51,18 @@ var Keyboard, Mouse;
if (this._onKeyPress) {
Util.Debug("onKeyPress " + (e.type == 'keydown' ? "down" : "up") +
", keysym: " + e.keysym.keysym + "(" + e.keysym.keyname + ")");
- this._onKeyPress(e.keysym.keysym, e.type == 'keydown');
+ this._onKeyPress(e);
}
},
+ setQEMUVNCKeyboardHandler: function () {
+ this._handler = new QEMUKeyEventDecoder(kbdUtil.ModifierSync(),
+ TrackQEMUKeyState(
+ this._handleRfbEvent.bind(this)
+ )
+ );
+ },
+
_handleKeyDown: function (e) {
if (!this._focused) { return true; }
diff --git a/include/rfb.js b/include/rfb.js
index bc5555a..9935962 100644
--- a/include/rfb.js
+++ b/include/rfb.js
@@ -58,7 +58,8 @@ var RFB;
['ExtendedDesktopSize', -308 ],
['xvp', -309 ],
['Fence', -312 ],
- ['ContinuousUpdates', -313 ]
+ ['ContinuousUpdates', -313 ],
+ ['QEMUExtendedKeyEvent', -258 ]
];
this._encHandlers = {};
@@ -129,6 +130,9 @@ var RFB;
this._viewportDragPos = {};
this._viewportHasMoved = false;
+ // QEMU Extended Key Event support - default to false
+ this._qemuExtKeyEventSupported = false;
+
// set the default value on user-facing properties
Util.set_defaults(this, defaults, {
'target': 'null', // VNC display rendering Canvas object
@@ -560,9 +564,22 @@ var RFB;
}
},
- _handleKeyPress: function (keysym, down) {
+ _handleKeyPress: function (keyevent) {
if (this._view_only) { return; } // View only, skip keyboard, events
- RFB.messages.keyEvent(this._sock, keysym, down);
+
+ var down = (keyevent.type == 'keydown');
+ if (this._qemuExtKeyEventSupported) {
+ var scancode = XtScancode[keyevent.code];
+ if (scancode) {
+ var keysym = keyevent.keysym;
+ RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode);
+ } else {
+ Util.Error('Unable to find a xt scancode for code = ' + keyevent.code);
+ }
+ } else {
+ keysym = keyevent.keysym.keysym;
+ RFB.messages.keyEvent(this._sock, keysym, down);
+ }
},
_handleMouseButton: function (x, y, down, bmask) {
@@ -1348,6 +1365,42 @@ var RFB;
sock.flush();
},
+ QEMUExtendedKeyEvent: function (sock, keysym, down, keycode) {
+ function getRFBkeycode(xt_scancode) {
+ var upperByte = (keycode >> 8);
+ var lowerByte = (keycode & 0x00ff);
+ if (upperByte === 0xe0 && lowerByte < 0x7f) {
+ lowerByte = lowerByte | 0x80;
+ return lowerByte;
+ }
+ return xt_scancode
+ }
+
+ var buff = sock._sQ;
+ var offset = sock._sQlen;
+
+ buff[offset] = 255; // msg-type
+ buff[offset + 1] = 0; // sub msg-type
+
+ buff[offset + 2] = (down >> 8);
+ buff[offset + 3] = down;
+
+ buff[offset + 4] = (keysym >> 24);
+ buff[offset + 5] = (keysym >> 16);
+ buff[offset + 6] = (keysym >> 8);
+ buff[offset + 7] = keysym;
+
+ var RFBkeycode = getRFBkeycode(keycode)
+
+ buff[offset + 8] = (RFBkeycode >> 24);
+ buff[offset + 9] = (RFBkeycode >> 16);
+ buff[offset + 10] = (RFBkeycode >> 8);
+ buff[offset + 11] = RFBkeycode;
+
+ sock._sQlen += 12;
+ sock.flush();
+ },
+
pointerEvent: function (sock, x, y, mask) {
var buff = sock._sQ;
var offset = sock._sQlen;
@@ -2259,6 +2312,16 @@ var RFB;
compress_lo: function () {
Util.Error("Server sent compress level pseudo-encoding");
- }
+ },
+
+ QEMUExtendedKeyEvent: function () {
+ this._FBU.rects--;
+
+ var keyboardEvent = document.createEvent("keyboardEvent");
+ if (keyboardEvent.code !== undefined) {
+ this._qemuExtKeyEventSupported = true;
+ this._keyboard.setQEMUVNCKeyboardHandler();
+ }
+ },
};
})();
diff --git a/tests/test.rfb.js b/tests/test.rfb.js
index 65ce5f8..06eeebe 100644
--- a/tests/test.rfb.js
+++ b/tests/test.rfb.js
@@ -1927,7 +1927,11 @@ describe('Remote Frame Buffer Protocol Client', function() {
});
it('should send a key message on a key press', function () {
- client._keyboard._onKeyPress(1234, 1);
+ var keyevent = {};
+ keyevent.type = 'keydown';
+ keyevent.keysym = {};
+ keyevent.keysym.keysym = 1234;
+ client._keyboard._onKeyPress(keyevent);
var key_msg = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}};
RFB.messages.keyEvent(key_msg, 1234, 1);
expect(client._sock).to.have.sent(key_msg._sQ);