Merge pull request #596 from danielhb/master
QEMU RFB extension Fixes #21 🎉 (again)
This commit is contained in:
commit
f4f4e8993d
|
@ -17,6 +17,7 @@ is not limited to):
|
||||||
include/util.js
|
include/util.js
|
||||||
include/websock.js
|
include/websock.js
|
||||||
include/webutil.js
|
include/webutil.js
|
||||||
|
include/xtscancodes.js
|
||||||
|
|
||||||
The HTML, CSS, font and images files that included with the noVNC
|
The HTML, CSS, font and images files that included with the noVNC
|
||||||
source distibution (or repository) are not considered part of the
|
source distibution (or repository) are not considered part of the
|
||||||
|
|
|
@ -51,10 +51,18 @@ var Keyboard, Mouse;
|
||||||
if (this._onKeyPress) {
|
if (this._onKeyPress) {
|
||||||
Util.Debug("onKeyPress " + (e.type == 'keydown' ? "down" : "up") +
|
Util.Debug("onKeyPress " + (e.type == 'keydown' ? "down" : "up") +
|
||||||
", keysym: " + e.keysym.keysym + "(" + e.keysym.keyname + ")");
|
", 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) {
|
_handleKeyDown: function (e) {
|
||||||
if (!this._focused) { return true; }
|
if (!this._focused) { return true; }
|
||||||
|
|
||||||
|
|
|
@ -285,6 +285,137 @@ var kbdUtil = (function() {
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
function QEMUKeyEventDecoder(modifierState, next) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function sendAll(evts) {
|
||||||
|
for (var i = 0; i < evts.length; ++i) {
|
||||||
|
next(evts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var numPadCodes = ["Numpad0", "Numpad1", "Numpad2",
|
||||||
|
"Numpad3", "Numpad4", "Numpad5", "Numpad6",
|
||||||
|
"Numpad7", "Numpad8", "Numpad9", "NumpadDecimal"];
|
||||||
|
|
||||||
|
var numLockOnKeySyms = {
|
||||||
|
"Numpad0": 0xffb0, "Numpad1": 0xffb1, "Numpad2": 0xffb2,
|
||||||
|
"Numpad3": 0xffb3, "Numpad4": 0xffb4, "Numpad5": 0xffb5,
|
||||||
|
"Numpad6": 0xffb6, "Numpad7": 0xffb7, "Numpad8": 0xffb8,
|
||||||
|
"Numpad9": 0xffb9, "NumpadDecimal": 0xffac
|
||||||
|
};
|
||||||
|
|
||||||
|
var numLockOnKeyCodes = [96, 97, 98, 99, 100, 101, 102,
|
||||||
|
103, 104, 105, 108, 110];
|
||||||
|
|
||||||
|
function isNumPadMultiKey(evt) {
|
||||||
|
return (numPadCodes.indexOf(evt.code) !== -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNumPadKeySym(evt) {
|
||||||
|
if (numLockOnKeyCodes.indexOf(evt.keyCode) !== -1) {
|
||||||
|
return numLockOnKeySyms[evt.code];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function process(evt, type) {
|
||||||
|
var result = {type: type};
|
||||||
|
result.code = evt.code;
|
||||||
|
result.keysym = 0;
|
||||||
|
|
||||||
|
if (isNumPadMultiKey(evt)) {
|
||||||
|
result.keysym = getNumPadKeySym(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier();
|
||||||
|
var isShift = evt.keyCode === 0x10 || evt.key === 'Shift';
|
||||||
|
|
||||||
|
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!kbdUtil.nonCharacterKey(evt));
|
||||||
|
|
||||||
|
next(result);
|
||||||
|
return suppress;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
keydown: function(evt) {
|
||||||
|
sendAll(modifierState.keydown(evt));
|
||||||
|
return process(evt, 'keydown');
|
||||||
|
},
|
||||||
|
keypress: function(evt) {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
keyup: function(evt) {
|
||||||
|
sendAll(modifierState.keyup(evt));
|
||||||
|
return process(evt, 'keyup');
|
||||||
|
},
|
||||||
|
syncModifiers: function(evt) {
|
||||||
|
sendAll(modifierState.syncAny(evt));
|
||||||
|
},
|
||||||
|
releaseAll: function() { next({type: 'releaseall'}); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function TrackQEMUKeyState(next) {
|
||||||
|
"use strict";
|
||||||
|
var state = [];
|
||||||
|
|
||||||
|
return function (evt) {
|
||||||
|
var last = state.length !== 0 ? state[state.length-1] : null;
|
||||||
|
|
||||||
|
switch (evt.type) {
|
||||||
|
case 'keydown':
|
||||||
|
|
||||||
|
if (!last || last.code !== evt.code) {
|
||||||
|
last = {code: evt.code};
|
||||||
|
|
||||||
|
if (state.length > 0 && state[state.length-1].code == 'ControlLeft') {
|
||||||
|
if (evt.code !== 'AltRight') {
|
||||||
|
next({code: 'ControlLeft', type: 'keydown', keysym: 0});
|
||||||
|
} else {
|
||||||
|
state.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.push(last);
|
||||||
|
}
|
||||||
|
if (evt.code !== 'ControlLeft') {
|
||||||
|
next(evt);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'keyup':
|
||||||
|
if (state.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var idx = null;
|
||||||
|
// do we have a matching key tracked as being down?
|
||||||
|
for (var i = 0; i !== state.length; ++i) {
|
||||||
|
if (state[i].code === evt.code) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if we couldn't find a match (it happens), assume it was the last key pressed
|
||||||
|
if (idx === null) {
|
||||||
|
if (evt.code === 'ControlLeft') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
idx = state.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.splice(idx, 1);
|
||||||
|
next(evt);
|
||||||
|
break;
|
||||||
|
case 'releaseall':
|
||||||
|
/* jshint shadow: true */
|
||||||
|
for (var i = 0; i < state.length; ++i) {
|
||||||
|
next({code: state[i].code, keysym: 0, type: 'keyup'});
|
||||||
|
}
|
||||||
|
/* jshint shadow: false */
|
||||||
|
state = [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Takes a DOM keyboard event and:
|
// Takes a DOM keyboard event and:
|
||||||
// - determines which keysym it represents
|
// - determines which keysym it represents
|
||||||
// - determines a keyId identifying the key that was pressed (corresponding to the key/keyCode properties on the DOM event)
|
// - determines a keyId identifying the key that was pressed (corresponding to the key/keyCode properties on the DOM event)
|
||||||
|
|
|
@ -58,7 +58,8 @@ var RFB;
|
||||||
['ExtendedDesktopSize', -308 ],
|
['ExtendedDesktopSize', -308 ],
|
||||||
['xvp', -309 ],
|
['xvp', -309 ],
|
||||||
['Fence', -312 ],
|
['Fence', -312 ],
|
||||||
['ContinuousUpdates', -313 ]
|
['ContinuousUpdates', -313 ],
|
||||||
|
['QEMUExtendedKeyEvent', -258 ]
|
||||||
];
|
];
|
||||||
|
|
||||||
this._encHandlers = {};
|
this._encHandlers = {};
|
||||||
|
@ -129,6 +130,9 @@ var RFB;
|
||||||
this._viewportDragPos = {};
|
this._viewportDragPos = {};
|
||||||
this._viewportHasMoved = false;
|
this._viewportHasMoved = false;
|
||||||
|
|
||||||
|
// QEMU Extended Key Event support - default to false
|
||||||
|
this._qemuExtKeyEventSupported = false;
|
||||||
|
|
||||||
// set the default value on user-facing properties
|
// set the default value on user-facing properties
|
||||||
Util.set_defaults(this, defaults, {
|
Util.set_defaults(this, defaults, {
|
||||||
'target': 'null', // VNC display rendering Canvas object
|
'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
|
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 {
|
||||||
|
Util.Error('Unable to find a xt scancode for code = ' + keyevent.code);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keysym = keyevent.keysym.keysym;
|
||||||
RFB.messages.keyEvent(this._sock, keysym, down);
|
RFB.messages.keyEvent(this._sock, keysym, down);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleMouseButton: function (x, y, down, bmask) {
|
_handleMouseButton: function (x, y, down, bmask) {
|
||||||
|
@ -1348,6 +1365,42 @@ var RFB;
|
||||||
sock.flush();
|
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) {
|
pointerEvent: function (sock, x, y, mask) {
|
||||||
var buff = sock._sQ;
|
var buff = sock._sQ;
|
||||||
var offset = sock._sQlen;
|
var offset = sock._sQlen;
|
||||||
|
@ -2259,6 +2312,16 @@ var RFB;
|
||||||
|
|
||||||
compress_lo: function () {
|
compress_lo: function () {
|
||||||
Util.Error("Server sent compress level pseudo-encoding");
|
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();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -18,8 +18,9 @@ var UI;
|
||||||
// Load supporting scripts
|
// Load supporting scripts
|
||||||
window.onscriptsload = function () { UI.load(); };
|
window.onscriptsload = function () { UI.load(); };
|
||||||
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
|
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
|
||||||
"keysymdef.js", "keyboard.js", "input.js", "display.js",
|
"keysymdef.js", "xtscancodes.js", "keyboard.js",
|
||||||
"rfb.js", "keysym.js", "inflator.js"]);
|
"input.js", "display.js", "rfb.js", "keysym.js",
|
||||||
|
"inflator.js"]);
|
||||||
|
|
||||||
UI = {
|
UI = {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
var XtScancode = {};
|
||||||
|
XtScancode["Escape"] = 0x0001;
|
||||||
|
XtScancode["Digit1"] = 0x0002;
|
||||||
|
XtScancode["Digit2"] = 0x0003;
|
||||||
|
XtScancode["Digit3"] = 0x0004;
|
||||||
|
XtScancode["Digit4"] = 0x0005;
|
||||||
|
XtScancode["Digit5"] = 0x0006;
|
||||||
|
XtScancode["Digit6"] = 0x0007;
|
||||||
|
XtScancode["Digit7"] = 0x0008;
|
||||||
|
XtScancode["Digit8"] = 0x0009;
|
||||||
|
XtScancode["Digit9"] = 0x000A;
|
||||||
|
XtScancode["Digit0"] = 0x000B;
|
||||||
|
XtScancode["Minus"] = 0x000C;
|
||||||
|
XtScancode["Equal"] = 0x000D;
|
||||||
|
XtScancode["Backspace"] = 0x000E;
|
||||||
|
XtScancode["Tab"] = 0x000F;
|
||||||
|
XtScancode["KeyQ"] = 0x0010;
|
||||||
|
XtScancode["KeyW"] = 0x0011;
|
||||||
|
XtScancode["KeyE"] = 0x0012;
|
||||||
|
XtScancode["KeyR"] = 0x0013;
|
||||||
|
XtScancode["KeyT"] = 0x0014;
|
||||||
|
XtScancode["KeyY"] = 0x0015;
|
||||||
|
XtScancode["KeyU"] = 0x0016;
|
||||||
|
XtScancode["KeyI"] = 0x0017;
|
||||||
|
XtScancode["KeyO"] = 0x0018;
|
||||||
|
XtScancode["KeyP"] = 0x0019;
|
||||||
|
XtScancode["BracketLeft"] = 0x001A;
|
||||||
|
XtScancode["BracketRight"] = 0x001B;
|
||||||
|
XtScancode["Enter"] = 0x001C;
|
||||||
|
XtScancode["ControlLeft"] = 0x001D;
|
||||||
|
XtScancode["KeyA"] = 0x001E;
|
||||||
|
XtScancode["KeyS"] = 0x001F;
|
||||||
|
XtScancode["KeyD"] = 0x0020;
|
||||||
|
XtScancode["KeyF"] = 0x0021;
|
||||||
|
XtScancode["KeyG"] = 0x0022;
|
||||||
|
XtScancode["KeyH"] = 0x0023;
|
||||||
|
XtScancode["KeyJ"] = 0x0024;
|
||||||
|
XtScancode["KeyK"] = 0x0025;
|
||||||
|
XtScancode["KeyL"] = 0x0026;
|
||||||
|
XtScancode["Semicolon"] = 0x0027;
|
||||||
|
XtScancode["Quote"] = 0x0028;
|
||||||
|
XtScancode["Backquote"] = 0x0029;
|
||||||
|
XtScancode["ShiftLeft"] = 0x002A;
|
||||||
|
XtScancode["Backslash"] = 0x002B;
|
||||||
|
XtScancode["KeyZ"] = 0x002C;
|
||||||
|
XtScancode["KeyX"] = 0x002D;
|
||||||
|
XtScancode["KeyC"] = 0x002E;
|
||||||
|
XtScancode["KeyV"] = 0x002F;
|
||||||
|
XtScancode["KeyB"] = 0x0030;
|
||||||
|
XtScancode["KeyN"] = 0x0031;
|
||||||
|
XtScancode["KeyM"] = 0x0032;
|
||||||
|
XtScancode["Comma"] = 0x0033;
|
||||||
|
XtScancode["Period"] = 0x0034;
|
||||||
|
XtScancode["Slash"] = 0x0035;
|
||||||
|
XtScancode["ShiftRight"] = 0x0036;
|
||||||
|
XtScancode["NumpadMultiply"] = 0x0037;
|
||||||
|
XtScancode["AltLeft"] = 0x0038;
|
||||||
|
XtScancode["Space"] = 0x0039;
|
||||||
|
XtScancode["CapsLock"] = 0x003A;
|
||||||
|
XtScancode["F1"] = 0x003B;
|
||||||
|
XtScancode["F2"] = 0x003C;
|
||||||
|
XtScancode["F3"] = 0x003D;
|
||||||
|
XtScancode["F4"] = 0x003E;
|
||||||
|
XtScancode["F5"] = 0x003F;
|
||||||
|
XtScancode["F6"] = 0x0040;
|
||||||
|
XtScancode["F7"] = 0x0041;
|
||||||
|
XtScancode["F8"] = 0x0042;
|
||||||
|
XtScancode["F9"] = 0x0043;
|
||||||
|
XtScancode["F10"] = 0x0044;
|
||||||
|
XtScancode["Pause"] = 0xE045;
|
||||||
|
XtScancode["ScrollLock"] = 0x0046;
|
||||||
|
XtScancode["Numpad7"] = 0x0047;
|
||||||
|
XtScancode["Numpad8"] = 0x0048;
|
||||||
|
XtScancode["Numpad9"] = 0x0049;
|
||||||
|
XtScancode["NumpadSubtract"] = 0x004A;
|
||||||
|
XtScancode["Numpad4"] = 0x004B;
|
||||||
|
XtScancode["Numpad5"] = 0x004C;
|
||||||
|
XtScancode["Numpad6"] = 0x004D;
|
||||||
|
XtScancode["NumpadAdd"] = 0x004E;
|
||||||
|
XtScancode["Numpad1"] = 0x004F;
|
||||||
|
XtScancode["Numpad2"] = 0x0050;
|
||||||
|
XtScancode["Numpad3"] = 0x0051;
|
||||||
|
XtScancode["Numpad0"] = 0x0052;
|
||||||
|
XtScancode["NumpadDecimal"] = 0x0053;
|
||||||
|
XtScancode["IntlBackslash"] = 0x0056;
|
||||||
|
XtScancode["F11"] = 0x0057;
|
||||||
|
XtScancode["F12"] = 0x0058;
|
||||||
|
XtScancode["IntlYen"] = 0x007D;
|
||||||
|
XtScancode["MediaTrackPrevious"] = 0xE010;
|
||||||
|
XtScancode["MediaTrackNext"] = 0xE019;
|
||||||
|
XtScancode["NumpadEnter"] = 0xE01C;
|
||||||
|
XtScancode["ControlRight"] = 0xE01D;
|
||||||
|
XtScancode["VolumeMute"] = 0xE020;
|
||||||
|
XtScancode["MediaPlayPause"] = 0xE022;
|
||||||
|
XtScancode["MediaStop"] = 0xE024;
|
||||||
|
XtScancode["VolumeDown"] = 0xE02E;
|
||||||
|
XtScancode["VolumeUp"] = 0xE030;
|
||||||
|
XtScancode["BrowserHome"] = 0xE032;
|
||||||
|
XtScancode["NumpadDivide"] = 0xE035;
|
||||||
|
XtScancode["PrintScreen"] = 0xE037;
|
||||||
|
XtScancode["AltRight"] = 0xE038;
|
||||||
|
XtScancode["NumLock"] = 0x0045;
|
||||||
|
XtScancode["Home"] = 0xE047;
|
||||||
|
XtScancode["ArrowUp"] = 0xE048;
|
||||||
|
XtScancode["PageUp"] = 0xE049;
|
||||||
|
XtScancode["ArrowLeft"] = 0xE04B;
|
||||||
|
XtScancode["ArrowRight"] = 0xE04D;
|
||||||
|
XtScancode["End"] = 0xE04F;
|
||||||
|
XtScancode["ArrowDown"] = 0xE050;
|
||||||
|
XtScancode["PageDown"] = 0xE051;
|
||||||
|
XtScancode["Insert"] = 0xE052;
|
||||||
|
XtScancode["Delete"] = 0xE053;
|
||||||
|
XtScancode["OSLeft"] = 0xE05B;
|
||||||
|
XtScancode["OSRight"] = 0xE05C;
|
||||||
|
XtScancode["ContextMenu"] = 0xE05D;
|
||||||
|
XtScancode["BrowserSearch"] = 0xE065;
|
||||||
|
XtScancode["BrowserFavorites"] = 0xE066;
|
||||||
|
XtScancode["BrowserRefresh"] = 0xE067;
|
||||||
|
XtScancode["BrowserStop"] = 0xE068;
|
||||||
|
XtScancode["BrowserForward"] = 0xE069;
|
||||||
|
XtScancode["BrowserBack"] = 0xE06A;
|
||||||
|
XtScancode["NumpadComma"] = 0x007E;
|
||||||
|
XtScancode["NumpadEqual"] = 0x0059;
|
||||||
|
XtScancode["F13"] = 0x0064;
|
||||||
|
XtScancode["F14"] = 0x0065;
|
||||||
|
XtScancode["F15"] = 0x0066;
|
||||||
|
XtScancode["F16"] = 0x0067;
|
||||||
|
XtScancode["F17"] = 0x0068;
|
||||||
|
XtScancode["F18"] = 0x0069;
|
||||||
|
XtScancode["F19"] = 0x006A;
|
||||||
|
XtScancode["F20"] = 0x006B;
|
||||||
|
XtScancode["F21"] = 0x006C;
|
||||||
|
XtScancode["F22"] = 0x006D;
|
||||||
|
XtScancode["F23"] = 0x006E;
|
||||||
|
XtScancode["F24"] = 0x0076;
|
||||||
|
XtScancode["KanaMode"] = 0x0070;
|
||||||
|
XtScancode["Lang2"] = 0x0071;
|
||||||
|
XtScancode["Lang1"] = 0x0072;
|
||||||
|
XtScancode["IntlRo"] = 0x0073;
|
||||||
|
XtScancode["Convert"] = 0x0079;
|
||||||
|
XtScancode["NonConvert"] = 0x007B;
|
||||||
|
XtScancode["LaunchApp2"] = 0xE021;
|
||||||
|
XtScancode["Power"] = 0xE05E;
|
||||||
|
XtScancode["LaunchApp1"] = 0xE06B;
|
||||||
|
XtScancode["LaunchMail"] = 0xE06C;
|
||||||
|
XtScancode["MediaSelect"] = 0xE06D;
|
|
@ -115,6 +115,7 @@ module.exports = function(config) {
|
||||||
'include/base64.js',
|
'include/base64.js',
|
||||||
'include/keysym.js',
|
'include/keysym.js',
|
||||||
'include/keysymdef.js',
|
'include/keysymdef.js',
|
||||||
|
'include/xtscancodes.js',
|
||||||
'include/keyboard.js',
|
'include/keyboard.js',
|
||||||
'include/input.js',
|
'include/input.js',
|
||||||
'include/websock.js',
|
'include/websock.js',
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<script src="../include/base64.js"></script>
|
<script src="../include/base64.js"></script>
|
||||||
<script src="../include/keysym.js"></script>
|
<script src="../include/keysym.js"></script>
|
||||||
<script src="../include/keysymdef.js"></script>
|
<script src="../include/keysymdef.js"></script>
|
||||||
|
<script src="../include/xtscancodes.js"></script>
|
||||||
<script src="../include/keyboard.js"></script>
|
<script src="../include/keyboard.js"></script>
|
||||||
<script src="../include/input.js"></script>
|
<script src="../include/input.js"></script>
|
||||||
<script src="../include/display.js"></script>
|
<script src="../include/display.js"></script>
|
||||||
|
|
|
@ -1927,7 +1927,11 @@ describe('Remote Frame Buffer Protocol Client', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should send a key message on a key press', 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 () {}};
|
var key_msg = {_sQ: new Uint8Array(8), _sQlen: 0, flush: function () {}};
|
||||||
RFB.messages.keyEvent(key_msg, 1234, 1);
|
RFB.messages.keyEvent(key_msg, 1234, 1);
|
||||||
expect(client._sock).to.have.sent(key_msg._sQ);
|
expect(client._sock).to.have.sent(key_msg._sQ);
|
||||||
|
|
|
@ -50,8 +50,9 @@
|
||||||
|
|
||||||
// Load supporting scripts
|
// Load supporting scripts
|
||||||
Util.load_scripts(["base64.js", "websock.js", "des.js", "keysym.js",
|
Util.load_scripts(["base64.js", "websock.js", "des.js", "keysym.js",
|
||||||
"keysymdef.js", "keyboard.js", "input.js", "display.js",
|
"keysymdef.js", "xtscancodes.js", "keyboard.js",
|
||||||
"rfb.js", "playback.js", "inflator.js", fname]);
|
"input.js", "display.js", "rfb.js", "playback.js",
|
||||||
|
"inflator.js", fname]);
|
||||||
} else {
|
} else {
|
||||||
msg("Must specifiy data=FOO.js in query string.");
|
msg("Must specifiy data=FOO.js in query string.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,9 @@
|
||||||
message("Loading " + fname);
|
message("Loading " + fname);
|
||||||
// Load supporting scripts
|
// Load supporting scripts
|
||||||
Util.load_scripts(["base64.js", "websock.js", "des.js", "keysym.js",
|
Util.load_scripts(["base64.js", "websock.js", "des.js", "keysym.js",
|
||||||
"keysymdef.js", "keyboard.js", "input.js", "display.js",
|
"keysymdef.js", "xtscancodes.js", "keyboard.js",
|
||||||
"rfb.js", "playback.js", "inflator.js", fname]);
|
"input.js", "display.js", "rfb.js", "playback.js",
|
||||||
|
"inflator.js", fname]);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
message("Must specify data=FOO in query string.");
|
message("Must specify data=FOO in query string.");
|
||||||
|
|
|
@ -78,8 +78,9 @@
|
||||||
|
|
||||||
// Load supporting scripts
|
// Load supporting scripts
|
||||||
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
|
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
|
||||||
"keysymdef.js", "keyboard.js", "input.js", "display.js",
|
"keysymdef.js", "xtscancodes.js", "keyboard.js",
|
||||||
"inflator.js", "rfb.js", "keysym.js"]);
|
"input.js", "display.js", "inflator.js", "rfb.js",
|
||||||
|
"keysym.js"]);
|
||||||
|
|
||||||
var rfb;
|
var rfb;
|
||||||
var resizeTimeout;
|
var resizeTimeout;
|
||||||
|
|
Loading…
Reference in New Issue