viewer-side keymap
it's useful when dealing with broken vnc server implementations, namely qemu/kvm.
This commit is contained in:
parent
77c250c442
commit
e37086c1e1
|
|
@ -17,6 +17,7 @@ is not limited to):
|
|||
include/vnc.js
|
||||
include/websock.js
|
||||
include/webutil.js
|
||||
include/keymap.js
|
||||
|
||||
The HTML, CSS, font and images files that included with the noVNC
|
||||
source distibution (or repository) are not considered part of the
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -126,7 +126,9 @@ var that = {}, // Public API methods
|
|||
mouse_buttonMask = 0,
|
||||
mouse_arr = [],
|
||||
viewportDragging = false,
|
||||
viewportDragPos = {};
|
||||
viewportDragPos = {},
|
||||
|
||||
keymap = null;
|
||||
|
||||
// Configuration attributes
|
||||
Util.conf_defaults(conf, that, defaults, [
|
||||
|
|
@ -604,6 +606,11 @@ keyPress = function(keysym, down, km) {
|
|||
|
||||
if (conf.view_only) { return; } // View only, skip keyboard events
|
||||
|
||||
// Remap the modifiers with apppropriate ones depending on the
|
||||
// keyboard type of the vnc server if this is a presskey event.
|
||||
if (!!keymap && down === 2)
|
||||
km = remapModifiers(km, keysym);
|
||||
|
||||
// Generate all modifier keys' events on demand.
|
||||
// Send key events for modifiers to the vnc server when:
|
||||
// 1. the status of modifers have been changed
|
||||
|
|
@ -639,10 +646,44 @@ keyPress = function(keysym, down, km) {
|
|||
// This is a keydown or keyup event.
|
||||
arr = arr.concat(keyEvent(keysym, down));
|
||||
}
|
||||
|
||||
if (!!keymap && down === 2) {
|
||||
// Turn off SHIFT and ALTGR every time when emulating modifiers.
|
||||
if (remote_status.shift) {
|
||||
arr = arr.concat(keyEvent(0xFFE1, 0)); // SHIFT up
|
||||
remote_status.shift = false;
|
||||
}
|
||||
if (remote_status.altgr) {
|
||||
arr = arr.concat(keyEvent(0xFE03, 0)); // ALTGR up
|
||||
remote_status.altgr = false;
|
||||
}
|
||||
}
|
||||
|
||||
arr = arr.concat(fbUpdateRequests());
|
||||
ws.send(arr);
|
||||
};
|
||||
|
||||
// Remap the modifiers depending on keyboard types. It depends on keyboards
|
||||
// whether a certain keycode should be issued with modifiers. For example,
|
||||
// the US keyboard issues '@' with SHIFT, the Japanese keyboard issues '@'
|
||||
// without any modifers, and the German keyboard issues '@' with ALTGR.
|
||||
// When the keyboard types are different between the viewer and the vnc
|
||||
// server, the server is expected to generate fake modifer key events
|
||||
// if needed. But unfortunately there are a lot of VNC servers that can't
|
||||
// handle this. Then there is no choice but to make noVNC take care of it
|
||||
// on behalf of them.
|
||||
function remapModifiers(km, keysym)
|
||||
{
|
||||
var remap = {'altKey': km.altKey, 'ctrlKey': km.ctrlKey,
|
||||
'shiftKey': km.shiftKey, 'altgrKey': km.altgrKey};
|
||||
var key = keymap[keysym];
|
||||
if (typeof key !== "undefined") {
|
||||
remap.altgrKey = key.altgr;
|
||||
remap.shiftKey = key.shift;
|
||||
}
|
||||
return remap;
|
||||
}
|
||||
|
||||
mouseButton = function(x, y, down, bmask) {
|
||||
if (down) {
|
||||
mouse_buttonMask |= bmask;
|
||||
|
|
@ -1897,6 +1938,14 @@ that.testMode = function(override_send, data_mode) {
|
|||
};
|
||||
};
|
||||
|
||||
that.setKeymap = function(kb) {
|
||||
if (!kb || kb === 'default') {
|
||||
keymap = null;
|
||||
} else {
|
||||
keymap = Kmap.getKeymap(kb);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return constructor(); // Return the public API interface
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
// Load supporting scripts
|
||||
window.onscriptsload = function () { UI.load(); };
|
||||
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
|
||||
"input.js", "display.js", "jsunzip.js", "rfb.js"]);
|
||||
"input.js", "display.js", "jsunzip.js", "rfb.js",
|
||||
"keymap.js"]);
|
||||
|
||||
var UI = {
|
||||
|
||||
|
|
@ -31,7 +32,7 @@ load: function (callback) {
|
|||
|
||||
// Render default UI and initialize settings menu
|
||||
start: function(callback) {
|
||||
var html = '', i, sheet, sheets, llevels;
|
||||
var html = '', i, sheet, sheets, llevels, kbtypes;
|
||||
|
||||
// Stylesheet selection dropdown
|
||||
sheet = WebUtil.selectStylesheet();
|
||||
|
|
@ -46,6 +47,19 @@ start: function(callback) {
|
|||
UI.addOption($D('noVNC_logging'),llevels[i], llevels[i]);
|
||||
}
|
||||
|
||||
// Keyboard type selection dropdown
|
||||
kbtypes = ['default', 'ar', 'bepo', 'da', 'de', 'de-ch', 'en-gb',
|
||||
'en-us', 'es', 'et', 'fi', 'fo', 'fr', 'fr-be', 'fr-ca',
|
||||
'fr-ch', 'hr', 'hu', 'is', 'it', 'ja', 'lt', 'lv', 'mk',
|
||||
'nl', 'nl-be', 'no', 'pl', 'pt', 'pt-br', 'ru', 'sl',
|
||||
'sv', 'th', 'tr'];
|
||||
|
||||
for (i = 0; i < kbtypes.length; i += 1) {
|
||||
UI.addOption($D('noVNC_keymap'), kbtypes[i], kbtypes[i]);
|
||||
}
|
||||
|
||||
UI.initSetting('keymap', 'default');
|
||||
|
||||
// Settings with immediate effects
|
||||
UI.initSetting('logging', 'warn');
|
||||
WebUtil.init_logging(UI.getSetting('logging'));
|
||||
|
|
@ -71,6 +85,7 @@ start: function(callback) {
|
|||
UI.rfb = RFB({'target': $D('noVNC_canvas'),
|
||||
'onUpdateState': UI.updateState,
|
||||
'onClipboard': UI.clipReceive});
|
||||
UI.rfb.setKeymap(UI.getSetting('keymap'));
|
||||
UI.updateVisualState();
|
||||
|
||||
// Unfocus clipboard when over the VNC area
|
||||
|
|
@ -326,6 +341,7 @@ toggleSettingsPanel: function() {
|
|||
UI.updateSetting('repeaterID');
|
||||
UI.updateSetting('stylesheet');
|
||||
UI.updateSetting('logging');
|
||||
UI.updateSetting('keymap');
|
||||
|
||||
UI.openSettingsMenu();
|
||||
}
|
||||
|
|
@ -370,8 +386,10 @@ settingsApply: function() {
|
|||
UI.saveSetting('repeaterID');
|
||||
UI.saveSetting('stylesheet');
|
||||
UI.saveSetting('logging');
|
||||
UI.saveSetting('keymap');
|
||||
|
||||
// Settings with immediate (non-connected related) effect
|
||||
UI.rfb.setKeymap(UI.getSetting('keymap'));
|
||||
WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
|
||||
WebUtil.init_logging(UI.getSetting('logging'));
|
||||
UI.setViewClip();
|
||||
|
|
|
|||
6
vnc.html
6
vnc.html
|
|
@ -138,6 +138,12 @@
|
|||
<select id="noVNC_logging" name="vncLogging">
|
||||
</select></label>
|
||||
</li>
|
||||
|
||||
<!-- keyboard selection dropdown -->
|
||||
<li><label><strong>Keyboard: </strong>
|
||||
<select id="noVNC_keymap" name="vncKeymap">
|
||||
</select></label>
|
||||
</li>
|
||||
<hr>
|
||||
<li><input type="button" id="noVNC_apply" value="Apply"></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@
|
|||
|
||||
// Load supporting scripts
|
||||
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
|
||||
"input.js", "display.js", "jsunzip.js", "rfb.js"]);
|
||||
"input.js", "display.js", "jsunzip.js", "rfb.js",
|
||||
"keymap.js"]);
|
||||
|
||||
var rfb;
|
||||
|
||||
|
|
@ -126,6 +127,7 @@
|
|||
'view_only': WebUtil.getQueryVar('view_only', false),
|
||||
'updateState': updateState,
|
||||
'onPasswordRequired': passwordRequired});
|
||||
rfb.setKeymap(WebUtil.getQueryVar('keymap', 'default'));
|
||||
rfb.connect(host, port, password, path);
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue