// Send the key events
for (i = 0; i < backspaces; i++) {
- UI.rfb.sendKey(KeyTable.XK_BackSpace);
+ UI.rfb.sendKey(KeyTable.XK_BackSpace, "Backspace");
}
for (i = newLen - inputs; i < newLen; i++) {
UI.rfb.sendKey(keysyms.lookup(newValue.charCodeAt(i)));
},
sendEsc: function() {
- UI.rfb.sendKey(KeyTable.XK_Escape);
+ UI.rfb.sendKey(KeyTable.XK_Escape, "Escape");
},
sendTab: function() {
toggleCtrl: function() {
var btn = document.getElementById('noVNC_toggle_ctrl_button');
if (btn.classList.contains("noVNC_selected")) {
- UI.rfb.sendKey(KeyTable.XK_Control_L, false);
+ UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
btn.classList.remove("noVNC_selected");
} else {
- UI.rfb.sendKey(KeyTable.XK_Control_L, true);
+ UI.rfb.sendKey(KeyTable.XK_Control_L, "ControlLeft", true);
btn.classList.add("noVNC_selected");
}
},
toggleAlt: function() {
var btn = document.getElementById('noVNC_toggle_alt_button');
if (btn.classList.contains("noVNC_selected")) {
- UI.rfb.sendKey(KeyTable.XK_Alt_L, false);
+ UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
btn.classList.remove("noVNC_selected");
} else {
- UI.rfb.sendKey(KeyTable.XK_Alt_L, true);
+ UI.rfb.sendKey(KeyTable.XK_Alt_L, "AltLeft", true);
btn.classList.add("noVNC_selected");
}
},
if (this._rfb_connection_state !== 'connected' || this._view_only) { return false; }
Log.Info("Sending Ctrl-Alt-Del");
- RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 1);
- RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 1);
- RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 1);
- RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 0);
- RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 0);
- RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 0);
+ this.sendKey(KeyTable.XK_Control_L, "ControlLeft", true);
+ this.sendKey(KeyTable.XK_Alt_L, "AltLeft", true);
+ this.sendKey(KeyTable.XK_Delete, "Delete", true);
+ this.sendKey(KeyTable.XK_Delete, "Delete", false);
+ this.sendKey(KeyTable.XK_Alt_L, "AltLeft", false);
+ this.sendKey(KeyTable.XK_Control_L, "ControlLeft", false);
+
return true;
},
// Send a key press. If 'down' is not specified then send a down key
// followed by an up key.
- sendKey: function (keysym, down) {
+ sendKey: function (keysym, code, down) {
if (this._rfb_connection_state !== 'connected' || this._view_only) { return false; }
- if (typeof down !== 'undefined') {
+
+ if (down === undefined) {
+ this.sendKey(keysym, code, true);
+ this.sendKey(keysym, code, false);
+ return true;
+ }
+
+ if (this._qemuExtKeyEventSupported) {
+ var scancode = XtScancode[code];
+
+ if (scancode === undefined) {
+ Log.Error('Unable to find a xt scancode for code: ' + code);
+ // FIXME: not in the spec, but this is what
+ // gtk-vnc does
+ scancode = 0;
+ }
+
+ Log.Info("Sending key (" + (down ? "down" : "up") + "): keysym " + keysym + ", scancode " + scancode);
+
+ RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode);
+ } else {
Log.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym);
RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0);
- } else {
- Log.Info("Sending keysym (down + up): " + keysym);
- RFB.messages.keyEvent(this._sock, keysym, 1);
- RFB.messages.keyEvent(this._sock, keysym, 0);
}
+
return true;
},
},
_handleKeyPress: function (keyevent) {
- if (this._view_only) { return; } // View only, skip keyboard, events
-
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 {
- Log.Error('Unable to find a xt scancode for code = ' + keyevent.code);
- }
- } else {
- keysym = keyevent.keysym;
- RFB.messages.keyEvent(this._sock, keysym, down);
- }
+ this.sendKey(keyevent.keysym, keyevent.code, down);
},
_handleMouseButton: function (x, y, down, bmask) {
it('should send a single key with the given code and state (down = true)', function () {
var expected = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}};
RFB.messages.keyEvent(expected, 123, 1);
- client.sendKey(123, true);
+ client.sendKey(123, 'Key123', true);
expect(client._sock).to.have.sent(expected._sQ);
});
var expected = {_sQ: new Uint8Array(16), _sQlen: 0, flush: function () {}};
RFB.messages.keyEvent(expected, 123, 1);
RFB.messages.keyEvent(expected, 123, 0);
- client.sendKey(123);
+ client.sendKey(123, 'Key123');
expect(client._sock).to.have.sent(expected._sQ);
});
it('should not send the key if we are not in a normal state', function () {
client._rfb_connection_state = "broken";
- client.sendKey(123);
+ client.sendKey(123, 'Key123');
expect(client._sock.flush).to.not.have.been.called;
});
it('should not send the key if we are set as view_only', function () {
client._view_only = true;
- client.sendKey(123);
+ client.sendKey(123, 'Key123');
expect(client._sock.flush).to.not.have.been.called;
});
+
+ it('should send QEMU extended events if supported', function () {
+ client._qemuExtKeyEventSupported = true;
+ var expected = {_sQ: new Uint8Array(12), _sQlen: 0, flush: function () {}};
+ RFB.messages.QEMUExtendedKeyEvent(expected, 0x20, true, 0x0039);
+ client.sendKey(0x20, 'Space', true);
+ expect(client._sock).to.have.sent(expected._sQ);
+ });
});
describe('#clipboardPasteFrom', function () {
client._sock.open('ws://', 'binary');
client._sock._websocket._open();
sinon.spy(client._sock, 'flush');
+ client._rfb_connection_state = 'connected';
+ client._view_only = false;
});
it('should send a key message on a key press', function () {