From 7cfc86ce7433ebb9cfdd5327cc31fda6525047fa Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 21 Jan 2011 03:12:00 -0800 Subject: [PATCH 1/7] Support for newly added ready message --- .../guac-web-lib/javascript/guacamole.js | 18 ++++++++++++++++++ .../webapp/guac-web-lib/javascript/layer.js | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js b/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js index 020e88ac5..1c75e7c4c 100644 --- a/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js +++ b/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js @@ -440,6 +440,21 @@ function GuacamoleClient(display) { var instructionHandlers = { + "ready": function(parameters) { + + // If done drawing, send ready response + if (background.isReady()) + sendMessage("ready;"); + + // If not done drawing, set callback which will send response + else + background.setReadyHandler(function() { + sendMessage("ready;"); + background.setReadyHandler(null); + }); + + }, + "error": function(parameters) { showError(unescapeGuacamoleString(parameters[0])); }, @@ -572,6 +587,9 @@ function GuacamoleClient(display) { setState(STATE_WAITING); handleResponse(makeRequest()); + // Send "ready" message to server + sendMessage("ready;"); + }; diff --git a/guacamole/src/main/webapp/guac-web-lib/javascript/layer.js b/guacamole/src/main/webapp/guac-web-lib/javascript/layer.js index 79080fe15..d6ac25efa 100644 --- a/guacamole/src/main/webapp/guac-web-lib/javascript/layer.js +++ b/guacamole/src/main/webapp/guac-web-lib/javascript/layer.js @@ -31,6 +31,7 @@ function Layer(width, height) { var displayContext = display.getContext("2d"); + var readyHandler = null; var nextUpdateToDraw = 0; var currentUpdate = 0; var updates = new Array(); @@ -47,11 +48,15 @@ function Layer(width, height) { // Draw all pending updates. var updateCallback; - while (updateCallback = updates[++nextUpdateToDraw]) { + while ((updateCallback = updates[++nextUpdateToDraw])) { updateCallback(); delete updates[nextUpdateToDraw]; } + // If done with updates, call ready handler + if (display.isReady() && readyHandler != null) + readyHandler(); + } // If not next to draw, set callback and wait. @@ -60,6 +65,15 @@ function Layer(width, height) { } + display.isReady = function() { + return currentUpdate == nextUpdateToDraw; + } + + display.setReadyHandler = function(handler) { + readyHandler = handler; + } + + display.drawImage = function(x, y, image) { var updateId = currentUpdate++; From b6898abdeaf74e0ff156fd5a4ddc36d7e7588877 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Fri, 21 Jan 2011 20:00:46 -0800 Subject: [PATCH 2/7] Removed experimental ready message --- .../guac-web-lib/javascript/guacamole.js | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js b/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js index 1c75e7c4c..020e88ac5 100644 --- a/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js +++ b/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js @@ -440,21 +440,6 @@ function GuacamoleClient(display) { var instructionHandlers = { - "ready": function(parameters) { - - // If done drawing, send ready response - if (background.isReady()) - sendMessage("ready;"); - - // If not done drawing, set callback which will send response - else - background.setReadyHandler(function() { - sendMessage("ready;"); - background.setReadyHandler(null); - }); - - }, - "error": function(parameters) { showError(unescapeGuacamoleString(parameters[0])); }, @@ -587,9 +572,6 @@ function GuacamoleClient(display) { setState(STATE_WAITING); handleResponse(makeRequest()); - // Send "ready" message to server - sendMessage("ready;"); - }; From afa8c740f63663f6d17bb122305cd60b20dfe740 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sat, 22 Jan 2011 21:53:57 -0800 Subject: [PATCH 3/7] Migrating to separate Guacamole javascript library --- guacamole/pom.xml | 24 + .../webapp/guac-web-lib/css/guacamole.css | 37 -- .../guac-web-lib/javascript/guacamole.js | 601 ------------------ .../guac-web-lib/javascript/keyboard.js | 270 -------- .../webapp/guac-web-lib/javascript/keymap.js | 72 --- .../webapp/guac-web-lib/javascript/layer.js | 142 ----- .../webapp/guac-web-lib/javascript/mouse.js | 205 ------ .../guac-web-lib/javascript/oskeyboard.js | 487 -------------- .../{guac-web-lib => }/images/mouse/blank.cur | Bin .../{guac-web-lib => }/images/mouse/blank.gif | Bin .../{guac-web-lib => }/images/mouse/dot.gif | Bin .../{guac-web-lib => }/images/noimage92.png | Bin .../{guac-web-lib => }/images/spinner92.gif | Bin guacamole/src/main/webapp/index.html | 17 +- .../main/webapp/{ => styles}/guacamole.css | 18 + .../src/main/webapp/{ => styles}/keyboard.css | 0 16 files changed, 50 insertions(+), 1823 deletions(-) delete mode 100644 guacamole/src/main/webapp/guac-web-lib/css/guacamole.css delete mode 100644 guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js delete mode 100644 guacamole/src/main/webapp/guac-web-lib/javascript/keyboard.js delete mode 100644 guacamole/src/main/webapp/guac-web-lib/javascript/keymap.js delete mode 100644 guacamole/src/main/webapp/guac-web-lib/javascript/layer.js delete mode 100644 guacamole/src/main/webapp/guac-web-lib/javascript/mouse.js delete mode 100644 guacamole/src/main/webapp/guac-web-lib/javascript/oskeyboard.js rename guacamole/src/main/webapp/{guac-web-lib => }/images/mouse/blank.cur (100%) rename guacamole/src/main/webapp/{guac-web-lib => }/images/mouse/blank.gif (100%) rename guacamole/src/main/webapp/{guac-web-lib => }/images/mouse/dot.gif (100%) rename guacamole/src/main/webapp/{guac-web-lib => }/images/noimage92.png (100%) rename guacamole/src/main/webapp/{guac-web-lib => }/images/spinner92.gif (100%) rename guacamole/src/main/webapp/{ => styles}/guacamole.css (90%) rename guacamole/src/main/webapp/{ => styles}/keyboard.css (100%) diff --git a/guacamole/pom.xml b/guacamole/pom.xml index 9ba65535f..832a318db 100644 --- a/guacamole/pom.xml +++ b/guacamole/pom.xml @@ -11,6 +11,7 @@ + org.apache.maven.plugins maven-compiler-plugin @@ -19,6 +20,21 @@ 1.6 + + + org.apache.maven.plugins + maven-war-plugin + + + + net.sourceforge.guacamole + guacamole-common-js + zip + + + + + @@ -47,6 +63,14 @@ compile + + net.sourceforge.guacamole + guacamole-common-js + 0.3.0-SNAPSHOT + zip + runtime + + diff --git a/guacamole/src/main/webapp/guac-web-lib/css/guacamole.css b/guacamole/src/main/webapp/guac-web-lib/css/guacamole.css deleted file mode 100644 index 471c2fb3e..000000000 --- a/guacamole/src/main/webapp/guac-web-lib/css/guacamole.css +++ /dev/null @@ -1,37 +0,0 @@ - -/* - * Guacamole - Clientless Remote Desktop - * 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 . - */ - -.guac-display.guac-loading { - border: 1px dotted gray; - background-image: url('../images/spinner92.gif'); - background-position: center; - background-repeat: no-repeat; -} - -.guac-display.guac-error { - border: 1px dotted red; - background-image: url('../images/noimage92.png'); - background-position: center; - background-repeat: no-repeat; -} - -.guac-hide-cursor { - cursor: url('../images/mouse/dot.gif'),url('../images/mouse/blank.cur'),default; -} - diff --git a/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js b/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js deleted file mode 100644 index 020e88ac5..000000000 --- a/guacamole/src/main/webapp/guac-web-lib/javascript/guacamole.js +++ /dev/null @@ -1,601 +0,0 @@ - -/* - * Guacamole - Clientless Remote Desktop - * 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 . - */ - -function GuacamoleClient(display) { - - var STATE_IDLE = 0; - var STATE_CONNECTING = 1; - var STATE_WAITING = 2; - var STATE_CONNECTED = 3; - var STATE_DISCONNECTING = 4; - var STATE_DISCONNECTED = 5; - - var currentState = STATE_IDLE; - var stateChangeHandler = null; - - function setState(state) { - if (state != currentState) { - currentState = state; - if (stateChangeHandler) - stateChangeHandler(currentState); - } - } - - this.setOnStateChangeHandler = function(handler) { - stateChangeHandler = handler; - } - - function isConnected() { - return currentState == STATE_CONNECTED - || currentState == STATE_WAITING; - } - - // Layers - var background = null; - var cursor = null; - - var cursorImage = null; - var cursorHotspotX = 0; - var cursorHotspotY = 0; - - // FIXME: Make object. Clean up. - var cursorRectX = 0; - var cursorRectY = 0; - var cursorRectW = 0; - var cursorRectH = 0; - - var cursorHidden = 0; - - function redrawCursor() { - - // Hide hardware cursor - if (cursorHidden == 0) { - display.className += " guac-hide-cursor"; - cursorHidden = 1; - } - - // Erase old cursor - cursor.clearRect(cursorRectX, cursorRectY, cursorRectW, cursorRectH); - - // Update rect - cursorRectX = mouse.getX() - cursorHotspotX; - cursorRectY = mouse.getY() - cursorHotspotY; - cursorRectW = cursorImage.width; - cursorRectH = cursorImage.height; - - // Draw new cursor - cursor.drawImage(cursorRectX, cursorRectY, cursorImage); - } - - - - - /*****************************************/ - /*** Keyboard ***/ - /*****************************************/ - - var keyboard = new GuacamoleKeyboard(document); - - this.disableKeyboard = function() { - keyboard.setKeyPressedHandler(null); - keyboard.setKeyReleasedHandler(null); - }; - - this.enableKeyboard = function() { - keyboard.setKeyPressedHandler( - function (keysym) { - sendKeyEvent(1, keysym); - } - ); - - keyboard.setKeyReleasedHandler( - function (keysym) { - sendKeyEvent(0, keysym); - } - ); - }; - - // Enable keyboard by default - this.enableKeyboard(); - - function sendKeyEvent(pressed, keysym) { - // Do not send requests if not connected - if (!isConnected()) - return; - - sendMessage("key:" + keysym + "," + pressed + ";"); - } - - this.pressKey = function(keysym) { - sendKeyEvent(1, keysym); - }; - - this.releaseKey = function(keysym) { - sendKeyEvent(0, keysym); - }; - - - /*****************************************/ - /*** Mouse ***/ - /*****************************************/ - - var mouse = new GuacamoleMouse(display); - mouse.setButtonPressedHandler( - function(mouseState) { - sendMouseState(mouseState); - } - ); - - mouse.setButtonReleasedHandler( - function(mouseState) { - sendMouseState(mouseState); - } - ); - - mouse.setMovementHandler( - function(mouseState) { - - // Draw client-side cursor - if (cursorImage != null) { - redrawCursor(); - } - - sendMouseState(mouseState); - } - ); - - - function sendMouseState(mouseState) { - - // Do not send requests if not connected - if (!isConnected()) - return; - - // Build mask - var buttonMask = 0; - if (mouseState.getLeft()) buttonMask |= 1; - if (mouseState.getMiddle()) buttonMask |= 2; - if (mouseState.getRight()) buttonMask |= 4; - if (mouseState.getUp()) buttonMask |= 8; - if (mouseState.getDown()) buttonMask |= 16; - - // Send message - sendMessage("mouse:" + mouseState.getX() + "," + mouseState.getY() + "," + buttonMask + ";"); - } - - var sendingMessages = 0; - var outputMessageBuffer = ""; - - function sendMessage(message) { - - // Add event to queue, restart send loop if finished. - outputMessageBuffer += message; - if (sendingMessages == 0) - sendPendingMessages(); - - } - - function sendPendingMessages() { - - if (outputMessageBuffer.length > 0) { - - sendingMessages = 1; - - var message_xmlhttprequest = new XMLHttpRequest(); - message_xmlhttprequest.open("POST", "inbound"); - message_xmlhttprequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - message_xmlhttprequest.setRequestHeader("Content-length", outputMessageBuffer.length); - - // Once response received, send next queued event. - message_xmlhttprequest.onreadystatechange = function() { - if (message_xmlhttprequest.readyState == 4) - sendPendingMessages(); - } - - message_xmlhttprequest.send(outputMessageBuffer); - outputMessageBuffer = ""; // Clear buffer - - } - else - sendingMessages = 0; - - } - - - /*****************************************/ - /*** Clipboard ***/ - /*****************************************/ - - this.setClipboard = function(data) { - - // Do not send requests if not connected - if (!isConnected()) - return; - - sendMessage("clipboard:" + escapeGuacamoleString(data) + ";"); - } - - - function desaturateFilter(data, width, height) { - - for (var i=0; i= 2 && nextRequest == null) - nextRequest = makeRequest(); - - // Parse stream when data is received and when complete. - if (xmlhttprequest.readyState == 3 || - xmlhttprequest.readyState == 4) { - - // Halt on error during request - if (xmlhttprequest.status == 0) { - showError("Request canceled by browser."); - return; - } - else if (xmlhttprequest.status != 200) { - showError("Error during request (HTTP " + xmlhttprequest.status + "): " + xmlhttprequest.statusText); - return; - } - - var current = xmlhttprequest.responseText; - var instructionEnd; - - while ((instructionEnd = current.indexOf(";", startIndex)) != -1) { - - // Start next search at next instruction - startIndex = instructionEnd+1; - - var instruction = current.substr(instructionStart, - instructionEnd - instructionStart); - - instructionStart = startIndex; - - var opcodeEnd = instruction.indexOf(":"); - - var opcode; - var parameters; - if (opcodeEnd == -1) { - opcode = instruction; - parameters = new Array(); - } - else { - opcode = instruction.substr(0, opcodeEnd); - parameters = instruction.substr(opcodeEnd+1).split(","); - } - - // If we're done parsing, handle the next response. - if (opcode.length == 0) { - - if (isConnected()) { - delete xmlhttprequest; - if (nextRequest) - handleResponse(nextRequest); - } - - break; - } - - // Call instruction handler. - doInstruction(opcode, parameters); - } - - // Start search at end of string. - startIndex = current.length; - - delete instruction; - delete parameters; - - } - - } - - xmlhttprequest.onreadystatechange = parseResponse; - parseResponse(); - - } - - - function makeRequest() { - - // Download self - var xmlhttprequest = new XMLHttpRequest(); - xmlhttprequest.open("POST", "outbound"); - xmlhttprequest.send(null); - - return xmlhttprequest; - - } - - function escapeGuacamoleString(str) { - - var escapedString = ""; - - for (var i=0; i. - */ - -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; }; - -} diff --git a/guacamole/src/main/webapp/guac-web-lib/javascript/keymap.js b/guacamole/src/main/webapp/guac-web-lib/javascript/keymap.js deleted file mode 100644 index 016bf5939..000000000 --- a/guacamole/src/main/webapp/guac-web-lib/javascript/keymap.js +++ /dev/null @@ -1,72 +0,0 @@ - -/* - * Guacamole - Clientless Remote Desktop - * 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 . - */ - - -// Keymap - -var unshiftedKeySym = new Array(); -unshiftedKeySym[8] = 0xFF08; // backspace -unshiftedKeySym[9] = 0xFF09; // tab -unshiftedKeySym[13] = 0xFF0D; // enter -unshiftedKeySym[16] = 0xFFE1; // shift -unshiftedKeySym[17] = 0xFFE3; // ctrl -unshiftedKeySym[18] = 0xFFE9; // alt -unshiftedKeySym[19] = 0xFF13; // pause/break -unshiftedKeySym[20] = 0xFFE5; // caps lock -unshiftedKeySym[27] = 0xFF1B; // escape -unshiftedKeySym[33] = 0xFF55; // page up -unshiftedKeySym[34] = 0xFF56; // page down -unshiftedKeySym[35] = 0xFF57; // end -unshiftedKeySym[36] = 0xFF50; // home -unshiftedKeySym[37] = 0xFF51; // left arrow -unshiftedKeySym[38] = 0xFF52; // up arrow -unshiftedKeySym[39] = 0xFF53; // right arrow -unshiftedKeySym[40] = 0xFF54; // down arrow -unshiftedKeySym[45] = 0xFF63; // insert -unshiftedKeySym[46] = 0xFFFF; // delete -unshiftedKeySym[91] = 0xFFEB; // left window key (super_l) -unshiftedKeySym[92] = 0xFF67; // right window key (menu key?) -unshiftedKeySym[93] = null; // select key -unshiftedKeySym[112] = 0xFFBE; // f1 -unshiftedKeySym[113] = 0xFFBF; // f2 -unshiftedKeySym[114] = 0xFFC0; // f3 -unshiftedKeySym[115] = 0xFFC1; // f4 -unshiftedKeySym[116] = 0xFFC2; // f5 -unshiftedKeySym[117] = 0xFFC3; // f6 -unshiftedKeySym[118] = 0xFFC4; // f7 -unshiftedKeySym[119] = 0xFFC5; // f8 -unshiftedKeySym[120] = 0xFFC6; // f9 -unshiftedKeySym[121] = 0xFFC7; // f10 -unshiftedKeySym[122] = 0xFFC8; // f11 -unshiftedKeySym[123] = 0xFFC9; // f12 -unshiftedKeySym[144] = 0xFF7F; // num lock -unshiftedKeySym[145] = 0xFF14; // scroll lock - -// Shifted versions, IF DIFFERENT FROM UNSHIFTED! -// If any of these are null, the unshifted one will be used. -var shiftedKeySym = new Array(); -shiftedKeySym[18] = 0xFFE7; // alt - -// Constants for keysyms for special keys -var KEYSYM_CTRL = 65507; -var KEYSYM_ALT = 65513; -var KEYSYM_DELETE = 65535; -var KEYSYM_SHIFT = 65505; - - diff --git a/guacamole/src/main/webapp/guac-web-lib/javascript/layer.js b/guacamole/src/main/webapp/guac-web-lib/javascript/layer.js deleted file mode 100644 index d6ac25efa..000000000 --- a/guacamole/src/main/webapp/guac-web-lib/javascript/layer.js +++ /dev/null @@ -1,142 +0,0 @@ - -/* - * Guacamole - Clientless Remote Desktop - * 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 . - */ - -function Layer(width, height) { - - // Off-screen buffer - var display = document.createElement("canvas"); - - display.style.position = "absolute"; - display.style.left = "0px"; - display.style.right = "0px"; - - display.width = width; - display.height = height; - - var displayContext = display.getContext("2d"); - - var readyHandler = null; - var nextUpdateToDraw = 0; - var currentUpdate = 0; - var updates = new Array(); - - // Given an update ID, either call the provided update callback, or - // schedule the update for later. - function setUpdate(updateId, update) { - - // If this update is the next to draw... - if (updateId == nextUpdateToDraw) { - - // Call provided update handler. - update(); - - // Draw all pending updates. - var updateCallback; - while ((updateCallback = updates[++nextUpdateToDraw])) { - updateCallback(); - delete updates[nextUpdateToDraw]; - } - - // If done with updates, call ready handler - if (display.isReady() && readyHandler != null) - readyHandler(); - - } - - // If not next to draw, set callback and wait. - else - updates[updateId] = update; - - } - - display.isReady = function() { - return currentUpdate == nextUpdateToDraw; - } - - display.setReadyHandler = function(handler) { - readyHandler = handler; - } - - - display.drawImage = function(x, y, image) { - var updateId = currentUpdate++; - - setUpdate(updateId, function() { - displayContext.drawImage(image, x, y); - }); - - } - - - display.draw = function(x, y, url) { - var updateId = currentUpdate++; - - var image = new Image(); - image.onload = function() { - setUpdate(updateId, function() { - displayContext.drawImage(image, x, y); - }); - }; - image.src = url; - }; - - - display.copyRect = function(srcx, srcy, w, h, x, y) { - var updateId = currentUpdate++; - - setUpdate(updateId, function() { - displayContext.drawImage(display, srcx, srcy, w, h, x, y, w, h); - }); - - }; - - display.drawRect = function(x, y, w, h, color) { - var updateId = currentUpdate++; - - setUpdate(updateId, function() { - displayContext.fillStyle = color; - displayContext.fillRect(x, y, w, h); - }); - - }; - - display.clearRect = function(x, y, w, h) { - var updateId = currentUpdate++; - - setUpdate(updateId, function() { - displayContext.clearRect(x, y, w, h); - }); - - }; - - display.filter = function(filter) { - var updateId = currentUpdate++; - - setUpdate(updateId, function() { - var imageData = displayContext.getImageData(0, 0, width, height); - filter(imageData.data, width, height); - displayContext.putImageData(imageData, 0, 0); - }); - - }; - - return display; - -} - diff --git a/guacamole/src/main/webapp/guac-web-lib/javascript/mouse.js b/guacamole/src/main/webapp/guac-web-lib/javascript/mouse.js deleted file mode 100644 index 3a1234a0d..000000000 --- a/guacamole/src/main/webapp/guac-web-lib/javascript/mouse.js +++ /dev/null @@ -1,205 +0,0 @@ - -/* - * Guacamole - Clientless Remote Desktop - * 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 . - */ - - -function GuacamoleMouse(element) { - - /*****************************************/ - /*** Mouse Handler ***/ - /*****************************************/ - - - var mouseIndex = 0; - - var mouseLeftButton = 0; - var mouseMiddleButton = 0; - var mouseRightButton = 0; - - var mouseX = 0; - var mouseY = 0; - - var absoluteMouseX = 0; - var absoluteMouseY = 0; - - - function getMouseState(up, down) { - var mouseState = new MouseEvent(mouseX, mouseY, - mouseLeftButton, mouseMiddleButton, mouseRightButton, up, down); - - return mouseState; - } - - - // Block context menu so right-click gets sent properly - element.oncontextmenu = function(e) {return false;}; - - element.onmousemove = function(e) { - - e.stopPropagation(); - - absoluteMouseX = e.pageX; - absoluteMouseY = e.pageY; - - mouseX = absoluteMouseX - element.offsetLeft; - mouseY = absoluteMouseY - element.offsetTop; - - // This is all JUST so we can get the mouse position within the element - var parent = element.offsetParent; - while (parent) { - if (parent.offsetLeft && parent.offsetTop) { - mouseX -= parent.offsetLeft; - mouseY -= parent.offsetTop; - } - parent = parent.offsetParent; - } - - movementHandler(getMouseState(0, 0)); - }; - - - element.onmousedown = function(e) { - - e.stopPropagation(); - - switch (e.button) { - case 0: - mouseLeftButton = 1; - break; - case 1: - mouseMiddleButton = 1; - break; - case 2: - mouseRightButton = 1; - break; - } - - buttonPressedHandler(getMouseState(0, 0)); - }; - - - element.onmouseup = function(e) { - - e.stopPropagation(); - - switch (e.button) { - case 0: - mouseLeftButton = 0; - break; - case 1: - mouseMiddleButton = 0; - break; - case 2: - mouseRightButton = 0; - break; - } - - buttonReleasedHandler(getMouseState(0, 0)); - }; - - // Override selection on mouse event element. - element.onselectstart = function() { - return false; - }; - - // Scroll wheel support - function handleScroll(e) { - - var delta = 0; - if (e.detail) - delta = e.detail; - else if (e.wheelDelta) - delta = -event.wheelDelta; - - // Up - if (delta < 0) { - buttonPressedHandler(getMouseState(1, 0)); - buttonReleasedHandler(getMouseState(0, 0)); - } - - // Down - if (delta > 0) { - buttonPressedHandler(getMouseState(0, 1)); - buttonReleasedHandler(getMouseState(0, 0)); - } - - if (e.preventDefault) - e.preventDefault(); - - e.returnValue = false; - } - - element.addEventListener('DOMMouseScroll', handleScroll, false); - - element.onmousewheel = function(e) { - handleScroll(e); - } - - function MouseEvent(x, y, left, middle, right, up, down) { - - this.getX = function() { - return x; - }; - - this.getY = function() { - return y; - }; - - this.getLeft = function() { - return left; - }; - - this.getMiddle = function() { - return middle; - }; - - this.getRight = function() { - return right; - }; - - this.getUp = function() { - return up; - }; - - this.getDown = function() { - return down; - }; - - this.toString = function() { - return (mouseIndex++) + "," + x + "," + y + "," + left + "," + middle + "," + right + "," + up + "," + down; - }; - - } - - - var buttonPressedHandler = null; - var buttonReleasedHandler = null; - var movementHandler = null; - - this.setButtonPressedHandler = function(mh) {buttonPressedHandler = mh;}; - this.setButtonReleasedHandler = function(mh) {buttonReleasedHandler = mh;}; - this.setMovementHandler = function(mh) {movementHandler = mh;}; - - - this.getX = function() {return mouseX;}; - this.getY = function() {return mouseY;}; - this.getLeftButton = function() {return mouseLeftButton;}; - this.getMiddleButton = function() {return mouseMiddleButton;}; - this.getRightButton = function() {return mouseRightButton;}; - -} diff --git a/guacamole/src/main/webapp/guac-web-lib/javascript/oskeyboard.js b/guacamole/src/main/webapp/guac-web-lib/javascript/oskeyboard.js deleted file mode 100644 index 872bac223..000000000 --- a/guacamole/src/main/webapp/guac-web-lib/javascript/oskeyboard.js +++ /dev/null @@ -1,487 +0,0 @@ - -/* - * Guacamole - Clientless Remote Desktop - * 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 . - */ - - -function GuacamoleOnScreenKeyboard(url) { - - var tabIndex = 1; - var allKeys = new Array(); - var modifierState = new function() {}; - - function getKeySize(size) { - return (5*size) + "ex"; - } - - function getCapSize(size) { - return (5*size - 0.5) + "ex"; - } - - function clearModifiers() { - - // Send key release events for all pressed modifiers - for (var k=0; k 0) - return true; - - return false; - } - - function toggleModifierPressed(modifier) { - if (isModifierActive(modifier)) - setModifierReleased(modifier); - else - setModifierPressed(modifier); - } - - function refreshAllKeysState() { - for (var k=0; k= 0x0000 && charCode <= 0x00FF) - keysym = charCode; - - else if (charCode >= 0x0100 && charCode <= 0x10FFFF) - keysym = 0x01000000 | charCode; - } - - // Required modifiers for this keycap - var reqMod = null; - if (cap.attributes["if"]) - reqMod = cap.attributes["if"].value.split(","); - - - // Modifier represented by this keycap - var modifier = null; - if (cap.attributes["modifier"]) - modifier = cap.attributes["modifier"].value; - - - // Whether this key is sticky (toggles) - // Currently only valid for modifiers. - var sticky = false; - if (cap.attributes["sticky"] && cap.attributes["sticky"].value == "true") - sticky = true; - - this.getDisplayText = function() { - return cap.textContent; - }; - - this.getKeySym = function() { - return keysym; - }; - - this.getRequiredModifiers = function() { - return reqMod; - }; - - this.getModifier = function() { - return modifier; - }; - - this.isSticky = function() { - return sticky; - }; - - } - - var size = null; - if (key.attributes["size"]) - size = parseFloat(key.attributes["size"].value); - - var caps = key.getElementsByTagName("cap"); - var keycaps = new Array(); - for (var i=0; i can contain or - if (child.tagName == "key") { - var key = new Key(child); - keyboardRow.appendChild(key); - allKeys.push(key); - } - else if (child.tagName == "gap") { - var gap = new Gap(child); - keyboardRow.appendChild(gap); - } - else if (child.tagName == "column") { - var col = new Column(child); - keyboardRow.appendChild(col); - } - - } - - return keyboardRow; - - } - - function Column(col) { - - var keyboardCol = document.createElement("div"); - keyboardCol.className = "col"; - - var align = null; - if (col.attributes["align"]) - align = col.attributes["align"].value; - - var children = col.childNodes; - for (var j=0; j can only contain - if (child.tagName == "row") { - var row = new Row(child); - keyboardCol.appendChild(row); - } - - } - - if (align) - keyboardCol.style.textAlign = align; - - return keyboardCol; - - } - - - - // Create keyboard - var keyboard = document.createElement("div"); - keyboard.className = "keyboard"; - - - // Retrieve keyboard XML - var xmlhttprequest = new XMLHttpRequest(); - xmlhttprequest.open("GET", url, false); - xmlhttprequest.send(null); - - var xml = xmlhttprequest.responseXML; - - if (xml) { - - // Parse document - var root = xml.documentElement; - if (root) { - - var children = root.childNodes; - for (var i=0; i can contain or - if (child.tagName == "row") { - keyboard.appendChild(new Row(child)); - } - else if (child.tagName == "column") { - keyboard.appendChild(new Column(child)); - } - - } - - } - - } - - var keyPressedHandler = null; - var keyReleasedHandler = null; - - keyboard.setKeyPressedHandler = function(kh) { keyPressedHandler = kh; }; - keyboard.setKeyReleasedHandler = function(kh) { keyReleasedHandler = kh; }; - - // Do not allow selection or mouse movement to propagate/register. - keyboard.onselectstart = - keyboard.onmousemove = - keyboard.onmouseup = - keyboard.onmousedown = - function(e) { - e.stopPropagation(); - return false; - }; - - return keyboard; -} - diff --git a/guacamole/src/main/webapp/guac-web-lib/images/mouse/blank.cur b/guacamole/src/main/webapp/images/mouse/blank.cur similarity index 100% rename from guacamole/src/main/webapp/guac-web-lib/images/mouse/blank.cur rename to guacamole/src/main/webapp/images/mouse/blank.cur diff --git a/guacamole/src/main/webapp/guac-web-lib/images/mouse/blank.gif b/guacamole/src/main/webapp/images/mouse/blank.gif similarity index 100% rename from guacamole/src/main/webapp/guac-web-lib/images/mouse/blank.gif rename to guacamole/src/main/webapp/images/mouse/blank.gif diff --git a/guacamole/src/main/webapp/guac-web-lib/images/mouse/dot.gif b/guacamole/src/main/webapp/images/mouse/dot.gif similarity index 100% rename from guacamole/src/main/webapp/guac-web-lib/images/mouse/dot.gif rename to guacamole/src/main/webapp/images/mouse/dot.gif diff --git a/guacamole/src/main/webapp/guac-web-lib/images/noimage92.png b/guacamole/src/main/webapp/images/noimage92.png similarity index 100% rename from guacamole/src/main/webapp/guac-web-lib/images/noimage92.png rename to guacamole/src/main/webapp/images/noimage92.png diff --git a/guacamole/src/main/webapp/guac-web-lib/images/spinner92.gif b/guacamole/src/main/webapp/images/spinner92.gif similarity index 100% rename from guacamole/src/main/webapp/guac-web-lib/images/spinner92.gif rename to guacamole/src/main/webapp/images/spinner92.gif diff --git a/guacamole/src/main/webapp/index.html b/guacamole/src/main/webapp/index.html index 8c3e8166b..c2087cdd5 100644 --- a/guacamole/src/main/webapp/index.html +++ b/guacamole/src/main/webapp/index.html @@ -22,9 +22,8 @@ - - - + + Guacamole @@ -112,12 +111,12 @@ - - - - - - + + + + + +