diff --git a/guacamole-common-js/pom.xml b/guacamole-common-js/pom.xml index 27626a977..d79ba6436 100644 --- a/guacamole-common-js/pom.xml +++ b/guacamole-common-js/pom.xml @@ -5,7 +5,7 @@ net.sourceforge.guacamole guacamole-common-js pom - 0.7.1 + 0.7.2 guacamole-common-js http://guac-dev.org/ diff --git a/guacamole-common-js/src/main/resources/keyboard.js b/guacamole-common-js/src/main/resources/keyboard.js index fa3a7ee01..ad9b63a13 100644 --- a/guacamole-common-js/src/main/resources/keyboard.js +++ b/guacamole-common-js/src/main/resources/keyboard.js @@ -81,43 +81,43 @@ Guacamole.Keyboard = function(element) { * @private */ var unshiftedKeysym = { - 8: 0xFF08, // backspace - 9: 0xFF09, // tab - 13: 0xFF0D, // enter - 16: 0xFFE1, // shift - 17: 0xFFE3, // ctrl - 18: 0xFFE9, // alt - 19: 0xFF13, // pause/break - 20: 0xFFE5, // caps lock - 27: 0xFF1B, // escape - 32: 0x0020, // space - 33: 0xFF55, // page up - 34: 0xFF56, // page down - 35: 0xFF57, // end - 36: 0xFF50, // home - 37: 0xFF51, // left arrow - 38: 0xFF52, // up arrow - 39: 0xFF53, // right arrow - 40: 0xFF54, // down arrow - 45: 0xFF63, // insert - 46: 0xFFFF, // delete - 91: 0xFFEB, // left window key (super_l) - 92: 0xFF67, // right window key (menu key?) - 93: null, // select key - 112: 0xFFBE, // f1 - 113: 0xFFBF, // f2 - 114: 0xFFC0, // f3 - 115: 0xFFC1, // f4 - 116: 0xFFC2, // f5 - 117: 0xFFC3, // f6 - 118: 0xFFC4, // f7 - 119: 0xFFC5, // f8 - 120: 0xFFC6, // f9 - 121: 0xFFC7, // f10 - 122: 0xFFC8, // f11 - 123: 0xFFC9, // f12 - 144: 0xFF7F, // num lock - 145: 0xFF14 // scroll lock + 8: [0xFF08], // backspace + 9: [0xFF09], // tab + 13: [0xFF0D], // enter + 16: [0xFFE1, 0xFFE1, 0xFFE2], // shift + 17: [0xFFE3, 0xFFE3, 0xFFE4], // ctrl + 18: [0xFFE9, 0xFFE9, 0xFFEA], // alt + 19: [0xFF13], // pause/break + 20: [0xFFE5], // caps lock + 27: [0xFF1B], // escape + 32: [0x0020], // space + 33: [0xFF55], // page up + 34: [0xFF56], // page down + 35: [0xFF57], // end + 36: [0xFF50], // home + 37: [0xFF51], // left arrow + 38: [0xFF52], // up arrow + 39: [0xFF53], // right arrow + 40: [0xFF54], // down arrow + 45: [0xFF63], // insert + 46: [0xFFFF], // delete + 91: [0xFFEB], // left window key (super_l) + 92: [0xFF67], // right window key (menu key?) + 93: null, // select key + 112: [0xFFBE], // f1 + 113: [0xFFBF], // f2 + 114: [0xFFC0], // f3 + 115: [0xFFC1], // f4 + 116: [0xFFC2], // f5 + 117: [0xFFC3], // f6 + 118: [0xFFC4], // f7 + 119: [0xFFC5], // f8 + 120: [0xFFC6], // f9 + 121: [0xFFC7], // f10 + 122: [0xFFC8], // f11 + 123: [0xFFC9], // f12 + 144: [0xFF7F], // num lock + 145: [0xFF14] // scroll lock }; /** @@ -126,80 +126,80 @@ Guacamole.Keyboard = function(element) { * @private */ var keyidentifier_keysym = { - "AllCandidates": 0xFF3D, - "Alphanumeric": 0xFF30, - "Alt": 0xFFE9, - "Attn": 0xFD0E, - "AltGraph": 0xFFEA, - "CapsLock": 0xFFE5, - "Clear": 0xFF0B, - "Convert": 0xFF21, - "Copy": 0xFD15, - "Crsel": 0xFD1C, - "CodeInput": 0xFF37, - "Control": 0xFFE3, - "Down": 0xFF54, - "End": 0xFF57, - "Enter": 0xFF0D, - "EraseEof": 0xFD06, - "Execute": 0xFF62, - "Exsel": 0xFD1D, - "F1": 0xFFBE, - "F2": 0xFFBF, - "F3": 0xFFC0, - "F4": 0xFFC1, - "F5": 0xFFC2, - "F6": 0xFFC3, - "F7": 0xFFC4, - "F8": 0xFFC5, - "F9": 0xFFC6, - "F10": 0xFFC7, - "F11": 0xFFC8, - "F12": 0xFFC9, - "F13": 0xFFCA, - "F14": 0xFFCB, - "F15": 0xFFCC, - "F16": 0xFFCD, - "F17": 0xFFCE, - "F18": 0xFFCF, - "F19": 0xFFD0, - "F20": 0xFFD1, - "F21": 0xFFD2, - "F22": 0xFFD3, - "F23": 0xFFD4, - "F24": 0xFFD5, - "Find": 0xFF68, + "AllCandidates": [0xFF3D], + "Alphanumeric": [0xFF30], + "Alt": [0xFFE9, 0xFFE9, 0xFFEA], + "Attn": [0xFD0E], + "AltGraph": [0xFFEA], + "CapsLock": [0xFFE5], + "Clear": [0xFF0B], + "Convert": [0xFF21], + "Copy": [0xFD15], + "Crsel": [0xFD1C], + "CodeInput": [0xFF37], + "Control": [0xFFE3, 0xFFE3, 0xFFE4], + "Down": [0xFF54], + "End": [0xFF57], + "Enter": [0xFF0D], + "EraseEof": [0xFD06], + "Execute": [0xFF62], + "Exsel": [0xFD1D], + "F1": [0xFFBE], + "F2": [0xFFBF], + "F3": [0xFFC0], + "F4": [0xFFC1], + "F5": [0xFFC2], + "F6": [0xFFC3], + "F7": [0xFFC4], + "F8": [0xFFC5], + "F9": [0xFFC6], + "F10": [0xFFC7], + "F11": [0xFFC8], + "F12": [0xFFC9], + "F13": [0xFFCA], + "F14": [0xFFCB], + "F15": [0xFFCC], + "F16": [0xFFCD], + "F17": [0xFFCE], + "F18": [0xFFCF], + "F19": [0xFFD0], + "F20": [0xFFD1], + "F21": [0xFFD2], + "F22": [0xFFD3], + "F23": [0xFFD4], + "F24": [0xFFD5], + "Find": [0xFF68], "FullWidth": null, "HalfWidth": null, - "HangulMode": 0xFF31, - "HanjaMode": 0xFF34, - "Help": 0xFF6A, - "Hiragana": 0xFF25, - "Home": 0xFF50, - "Insert": 0xFF63, - "JapaneseHiragana": 0xFF25, - "JapaneseKatakana": 0xFF26, - "JapaneseRomaji": 0xFF24, - "JunjaMode": 0xFF38, - "KanaMode": 0xFF2D, - "KanjiMode": 0xFF21, - "Katakana": 0xFF26, - "Left": 0xFF51, - "Meta": 0xFFE7, - "NumLock": 0xFF7F, - "PageDown": 0xFF55, - "PageUp": 0xFF56, - "Pause": 0xFF13, - "PreviousCandidate": 0xFF3E, - "PrintScreen": 0xFD1D, - "Right": 0xFF53, + "HangulMode": [0xFF31], + "HanjaMode": [0xFF34], + "Help": [0xFF6A], + "Hiragana": [0xFF25], + "Home": [0xFF50], + "Insert": [0xFF63], + "JapaneseHiragana": [0xFF25], + "JapaneseKatakana": [0xFF26], + "JapaneseRomaji": [0xFF24], + "JunjaMode": [0xFF38], + "KanaMode": [0xFF2D], + "KanjiMode": [0xFF21], + "Katakana": [0xFF26], + "Left": [0xFF51], + "Meta": [0xFFE7], + "NumLock": [0xFF7F], + "PageDown": [0xFF55], + "PageUp": [0xFF56], + "Pause": [0xFF13], + "PreviousCandidate": [0xFF3E], + "PrintScreen": [0xFD1D], + "Right": [0xFF53], "RomanCharacters": null, - "Scroll": 0xFF14, - "Select": 0xFF60, - "Shift": 0xFFE1, - "Up": 0xFF52, - "Undo": 0xFF65, - "Win": 0xFFEB + "Scroll": [0xFF14], + "Select": [0xFF60], + "Shift": [0xFFE1, 0xFFE1, 0xFFE2], + "Up": [0xFF52], + "Undo": [0xFF65], + "Win": [0xFFEB] }; /** @@ -210,7 +210,7 @@ Guacamole.Keyboard = function(element) { * @private */ var shiftedKeysym = { - 18: 0xFFE7 // alt + 18: [0xFFE7, 0xFFE7, 0xFFEA] // alt }; /** @@ -218,9 +218,12 @@ Guacamole.Keyboard = function(element) { * @private */ var no_repeat = { - 0xFFE1: true, - 0xFFE3: true, - 0xFFE9: true + 0xFFE1: true, // Left shift + 0xFFE2: true, // Right shift + 0xFFE3: true, // Left ctrl + 0xFFE4: true, // Right ctrl + 0xFFE9: true, // Left alt + 0xFFEA: true // Right alt (or AltGr) }; /** @@ -276,7 +279,22 @@ Guacamole.Keyboard = function(element) { */ var key_repeat_interval = null; - function keysym_from_key_identifier(shifted, keyIdentifier) { + /** + * Given an array of keysyms indexed by location, returns the keysym + * for the given location, or the keysym for the standard location if + * undefined. + * + * @param {Array} keysyms An array of keysyms, where the index of the + * keysym in the array is the location value. + * @param {Number} location The location on the keyboard corresponding to + * the key pressed, as defined at: + * http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent + */ + function get_keysym(keysyms, location) { + return keysyms[location] || keysyms[0]; + } + + function keysym_from_key_identifier(shifted, keyIdentifier, location) { var unicodePrefixLocation = keyIdentifier.indexOf("U+"); if (unicodePrefixLocation >= 0) { @@ -298,7 +316,7 @@ Guacamole.Keyboard = function(element) { } - return keyidentifier_keysym[keyIdentifier]; + return get_keysym(keyidentifier_keysym[keyIdentifier], location); } @@ -323,16 +341,19 @@ Guacamole.Keyboard = function(element) { } - function keysym_from_keycode(keyCode) { + function keysym_from_keycode(keyCode, location) { - var keysym = null; - if (!guac_keyboard.modifiers.shift) keysym = unshiftedKeysym[keyCode]; - else { - keysym = shiftedKeysym[keyCode]; - if (keysym == null) keysym = unshiftedKeysym[keyCode]; - } + var keysyms; - return keysym; + // If not shifted, just return unshifted keysym + if (!guac_keyboard.modifiers.shift) + keysyms = unshiftedKeysym[keyCode]; + + // Otherwise, return shifted keysym, if defined + else + keysyms = shiftedKeysym[keyCode] || unshiftedKeysym[keyCode]; + + return get_keysym(keysyms, location); } @@ -430,6 +451,9 @@ Guacamole.Keyboard = function(element) { if (window.event) keynum = window.event.keyCode; else if (e.which) keynum = e.which; + // Get key location + var location = e.location || e.keyLocation || 0; + // Ignore any unknown key events if (keynum == 0 && !e.keyIdentifier) { e.preventDefault(); @@ -443,7 +467,7 @@ Guacamole.Keyboard = function(element) { else if (keynum == 91) guac_keyboard.modifiers.meta = true; // Try to get keysym from keycode - var keysym = keysym_from_keycode(keynum); + var keysym = keysym_from_keycode(keynum, location); // By default, we expect a corresponding keypress event var expect_keypress = true; @@ -456,7 +480,8 @@ Guacamole.Keyboard = function(element) { if (e.keyIdentifier) { keysym = keysym || - keysym_from_key_identifier(guac_keyboard.modifiers.shift, e.keyIdentifier); + keysym_from_key_identifier(guac_keyboard.modifiers.shift, + e.keyIdentifier, location); // Prevent default if non-typable character or if modifier combination // likely to be eaten by browser otherwise (NOTE: We must not prevent