mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Removed old Java client, added new experimental PHP client.
This commit is contained in:
270
guacamole/client/javascript/keyboard.js
Normal file
270
guacamole/client/javascript/keyboard.js
Normal file
@@ -0,0 +1,270 @@
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
function GuacamoleKeyboard(element) {
|
||||
|
||||
/*****************************************/
|
||||
/*** Keyboard Handler ***/
|
||||
/*****************************************/
|
||||
|
||||
// Single key state/modifier buffer
|
||||
var modShift = 0;
|
||||
var modCtrl = 0;
|
||||
var modAlt = 0;
|
||||
|
||||
var keydownChar = new Array();
|
||||
|
||||
|
||||
// ID of routine repeating keystrokes. -1 = not repeating.
|
||||
var repeatKeyTimeoutId = -1;
|
||||
var repeatKeyIntervalId = -1;
|
||||
|
||||
// Starts repeating keystrokes
|
||||
function startRepeat(keySym) {
|
||||
repeatKeyIntervalId = setInterval(function() {
|
||||
sendKeyReleased(keySym);
|
||||
sendKeyPressed(keySym);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
// Stops repeating keystrokes
|
||||
function stopRepeat() {
|
||||
if (repeatKeyTimeoutId != -1) clearInterval(repeatKeyTimeoutId);
|
||||
if (repeatKeyIntervalId != -1) clearInterval(repeatKeyIntervalId);
|
||||
}
|
||||
|
||||
|
||||
function getKeySymFromKeyIdentifier(shifted, keyIdentifier) {
|
||||
|
||||
var unicodePrefixLocation = keyIdentifier.indexOf("U+");
|
||||
if (unicodePrefixLocation >= 0) {
|
||||
|
||||
var hex = keyIdentifier.substring(unicodePrefixLocation+2);
|
||||
var codepoint = parseInt(hex, 16);
|
||||
var typedCharacter;
|
||||
|
||||
// Convert case if shifted
|
||||
if (shifted == 0)
|
||||
typedCharacter = String.fromCharCode(codepoint).toLowerCase();
|
||||
else
|
||||
typedCharacter = String.fromCharCode(codepoint).toUpperCase();
|
||||
|
||||
// Get codepoint
|
||||
codepoint = typedCharacter.charCodeAt(0);
|
||||
|
||||
return getKeySymFromCharCode(codepoint);
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
function getKeySymFromCharCode(keyCode) {
|
||||
|
||||
if (keyCode >= 0x0000 && keyCode <= 0x00FF)
|
||||
return keyCode;
|
||||
|
||||
if (keyCode >= 0x0100 && keyCode <= 0x10FFFF)
|
||||
return 0x01000000 | keyCode;
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
function getKeySymFromKeyCode(keyCode) {
|
||||
|
||||
var keysym = null;
|
||||
if (modShift == 0) keysym = unshiftedKeySym[keyCode];
|
||||
else {
|
||||
keysym = shiftedKeySym[keyCode];
|
||||
if (keysym == null) keysym = unshiftedKeySym[keyCode];
|
||||
}
|
||||
|
||||
return keysym;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Sends a single keystroke over the network
|
||||
function sendKeyPressed(keysym) {
|
||||
if (keysym != null && keyPressedHandler)
|
||||
keyPressedHandler(keysym);
|
||||
}
|
||||
|
||||
// Sends a single keystroke over the network
|
||||
function sendKeyReleased(keysym) {
|
||||
if (keysym != null)
|
||||
keyReleasedHandler(keysym);
|
||||
}
|
||||
|
||||
|
||||
var KEYDOWN = 1;
|
||||
var KEYPRESS = 2;
|
||||
|
||||
var keySymSource = null;
|
||||
|
||||
// When key pressed
|
||||
var keydownCode = null;
|
||||
element.onkeydown = function(e) {
|
||||
|
||||
// Only intercept if handler set
|
||||
if (!keyPressedHandler) return true;
|
||||
|
||||
var keynum;
|
||||
if (window.event) keynum = window.event.keyCode;
|
||||
else if (e.which) keynum = e.which;
|
||||
|
||||
// Ctrl/Alt/Shift
|
||||
if (keynum == 16)
|
||||
modShift = 1;
|
||||
else if (keynum == 17)
|
||||
modCtrl = 1;
|
||||
else if (keynum == 18)
|
||||
modAlt = 1;
|
||||
|
||||
var keysym = getKeySymFromKeyCode(keynum);
|
||||
if (keysym) {
|
||||
// Get keysyms and events from KEYDOWN
|
||||
keySymSource = KEYDOWN;
|
||||
}
|
||||
|
||||
// If modifier keys are held down, and we have keyIdentifier
|
||||
else if ((modCtrl == 1 || modAlt == 1) && e.keyIdentifier) {
|
||||
|
||||
// Get keysym from keyIdentifier
|
||||
keysym = getKeySymFromKeyIdentifier(modShift, e.keyIdentifier);
|
||||
|
||||
// Get keysyms and events from KEYDOWN
|
||||
keySymSource = KEYDOWN;
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
// Get keysyms and events from KEYPRESS
|
||||
keySymSource = KEYPRESS;
|
||||
|
||||
keydownCode = keynum;
|
||||
|
||||
// Ignore key if we don't need to use KEYPRESS.
|
||||
// Send key event here
|
||||
if (keySymSource == KEYDOWN) {
|
||||
|
||||
if (keydownChar[keynum] != keysym) {
|
||||
|
||||
// Send event
|
||||
keydownChar[keynum] = keysym;
|
||||
sendKeyPressed(keysym);
|
||||
|
||||
// Clear old key repeat, if any.
|
||||
stopRepeat();
|
||||
|
||||
// Start repeating (if not a modifier key) after a short delay
|
||||
if (keynum != 16 && keynum != 17 && keynum != 18)
|
||||
repeatKeyTimeoutId = setTimeout(function() { startRepeat(keysym); }, 500);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// When key pressed
|
||||
element.onkeypress = function(e) {
|
||||
|
||||
// Only intercept if handler set
|
||||
if (!keyPressedHandler) return true;
|
||||
|
||||
if (keySymSource != KEYPRESS) return false;
|
||||
|
||||
var keynum;
|
||||
if (window.event) keynum = window.event.keyCode;
|
||||
else if (e.which) keynum = e.which;
|
||||
|
||||
var keysym = getKeySymFromCharCode(keynum);
|
||||
if (keysym && keydownChar[keynum] != keysym) {
|
||||
|
||||
// If this button already pressed, release first
|
||||
var lastKeyDownChar = keydownChar[keydownCode];
|
||||
if (lastKeyDownChar)
|
||||
sendKeyReleased(lastKeyDownChar);
|
||||
|
||||
keydownChar[keydownCode] = keysym;
|
||||
|
||||
// Clear old key repeat, if any.
|
||||
stopRepeat();
|
||||
|
||||
// Send key event
|
||||
sendKeyPressed(keysym);
|
||||
|
||||
// Start repeating (if not a modifier key) after a short delay
|
||||
repeatKeyTimeoutId = setTimeout(function() { startRepeat(keysym); }, 500);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// When key released
|
||||
element.onkeyup = function(e) {
|
||||
|
||||
// Only intercept if handler set
|
||||
if (!keyReleasedHandler) return true;
|
||||
|
||||
var keynum;
|
||||
if (window.event) keynum = window.event.keyCode;
|
||||
else if (e.which) keynum = e.which;
|
||||
|
||||
// Ctrl/Alt/Shift
|
||||
if (keynum == 16)
|
||||
modShift = 0;
|
||||
else if (keynum == 17)
|
||||
modCtrl = 0;
|
||||
else if (keynum == 18)
|
||||
modAlt = 0;
|
||||
else
|
||||
stopRepeat();
|
||||
|
||||
// Get corresponding character
|
||||
var lastKeyDownChar = keydownChar[keynum];
|
||||
|
||||
// Clear character record
|
||||
keydownChar[keynum] = null;
|
||||
|
||||
// Send release event
|
||||
sendKeyReleased(lastKeyDownChar);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// When focus is lost, clear modifiers.
|
||||
var docOnblur = element.onblur;
|
||||
element.onblur = function() {
|
||||
modAlt = 0;
|
||||
modCtrl = 0;
|
||||
modShift = 0;
|
||||
if (docOnblur != null) docOnblur();
|
||||
};
|
||||
|
||||
var keyPressedHandler = null;
|
||||
var keyReleasedHandler = null;
|
||||
|
||||
this.setKeyPressedHandler = function(kh) { keyPressedHandler = kh; };
|
||||
this.setKeyReleasedHandler = function(kh) { keyReleasedHandler = kh; };
|
||||
|
||||
}
|
Reference in New Issue
Block a user