</div>
- <!-- Scripts -->
+ <!-- guacamole-common-js scripts -->
<script type="text/javascript" src="guacamole-common-js/keyboard.js"></script>
<script type="text/javascript" src="guacamole-common-js/mouse.js"></script>
<script type="text/javascript" src="guacamole-common-js/layer.js"></script>
<script type="text/javascript" src="guacamole-common-js/tunnel.js"></script>
<script type="text/javascript" src="guacamole-common-js/guacamole.js"></script>
<script type="text/javascript" src="guacamole-common-js/oskeyboard.js"></script>
+
+ <!-- guacamole-default-webapp scripts -->
<script type="text/javascript" src="scripts/interface.js"></script>
<!-- Init -->
<script type="text/javascript"> /* <![CDATA[ */
- var display = document.getElementById("display");
-
// Instantiate client
var guac = new Guacamole.Client(
- display,
+ GuacamoleUI.display,
new Guacamole.HTTPTunnel("tunnel")
);
- var menu = document.getElementById("menu");
- var logo = document.getElementById("status-logo");
-
- var errorDialog = document.getElementById("errorDialog");
- var errorDialogText = document.getElementById("errorText");
-
- var state = document.getElementById("state");
- guac.onstatechange = function(clientState) {
-
- switch (clientState) {
- case 0:
- state.textContent = "Idle."
- break;
- case 1:
- state.textContent = "Connecting...";
- break;
- case 2:
- state.textContent = "Connected, waiting for first update...";
- break;
- case 3:
- display.className = display.className.replace(/guac-loading/, '');
- menu.className = "connected";
- state.textContent = "Connected.";
- shadeMenu();
- break;
- case 4:
- state.textContent = "Disconnecting...";
- break;
- case 5:
- state.textContent = "Disconnected.";
- break;
- default:
- state.textContent = "Unknown";
- }
- };
-
- // Cache error image (might not be available when error occurs)
- var guacErrorImage = new Image();
- guacErrorImage.src = "images/noguacamole-logo-24.png";
-
- guac.onname = function(name) {
- document.title = name;
- };
-
- guac.onerror = function(error) {
-
- guac.disconnect();
-
- menu.className = "error";
- display.className += " guac-error";
-
- logo.src = guacErrorImage.src;
- errorDialogText.textContent = error;
- errorDialog.style.visibility = "visible";
-
- // Show error by desaturating display
- var layers = guac.getLayers();
- for (var i=0; i<layers.length; i++) {
- layers[i].filter(desaturateFilter);
- }
-
- // Filter for desaturation
- function desaturateFilter(data, width, height) {
-
- for (var i=0; i<data.length; i+=4) {
-
- // Get RGB values
- var r = data[i];
- var g = data[i+1];
- var b = data[i+2];
-
- // Desaturate
- var v = Math.max(r, g, b) / 2;
- data[i] = v;
- data[i+1] = v;
- data[i+2] = v;
-
- }
-
- }
-
- };
-
- // Mouse
- var mouse = new Guacamole.Mouse(display);
- mouse.onmousedown = mouse.onmouseup = mouse.onmousemove =
- function(mouseState) {
-
- if (mouseState.y <= 5)
- showMenu();
-
- guac.sendMouseState(mouseState);
- };
-
- // Keyboard
- var keyboard = new Guacamole.Keyboard(document);
-
- function disableKeyboard() {
- keyboard.onkeydown = null;
- keyboard.onkeyup = null;
- }
-
- function enableKeyboard() {
- keyboard.onkeydown =
- function (keysym) {
- guac.sendKeyEvent(1, keysym);
- };
-
- keyboard.onkeyup =
- function (keysym) {
- guac.sendKeyEvent(0, keysym);
- };
- }
-
- // Enable keyboard by default
- enableKeyboard();
-
- // Reconnect button
- var reconnect = document.getElementById("reconnect");
- reconnect.onclick = function() {
- window.location.reload();
- };
-
- // Disconnect on close
- window.onunload = function() {
- guac.disconnect();
- };
-
- // Handle clipboard events
- var clipboardElement = document.getElementById("clipboard");
- clipboardElement.onchange = function() {
-
- var text = clipboardElement.value;
- guac.setClipboard(text);
-
- };
-
- // Ignore keypresses when clipboard is focused
- clipboardElement.onfocus = function() {
- disableKeyboard();
- };
-
- // Capture keypresses when clipboard is not focused
- clipboardElement.onblur = function() {
- enableKeyboard();
- };
-
- // Server copy handler
- guac.onclipboard = function(data) {
- clipboardElement.value = data;
- };
-
-
- // Show/Hide clipboard
- var clipboardDiv = document.getElementById("clipboardDiv");
- var showClipboard = document.getElementById("showClipboard");
- showClipboard.onclick = function() {
-
- var displayed = clipboardDiv.style.display;
- if (displayed != "block") {
- clipboardDiv.style.display = "block";
- showClipboard.innerHTML = "Hide Clipboard";
- }
- else {
- clipboardDiv.style.display = "none";
- showClipboard.innerHTML = "Show Clipboard";
- clipboardElement.onchange();
- }
-
- };
-
-
- // Show/Hide keyboard
- var keyboardContainer = document.getElementById("keyboardContainer");
- var showKeyboard = document.getElementById("showKeyboard");
- showKeyboard.onclick = function() {
-
- var displayed = keyboardContainer.style.display;
- if (displayed != "block") {
- keyboardContainer.style.display = "block";
- showKeyboard.textContent = "Hide Keyboard";
- }
- else {
- keyboardContainer.style.display = "none";
- showKeyboard.textContent = "Show Keyboard";
- }
-
- };
-
- // On-screen keyboard
- var osKeyboard = new Guacamole.OnScreenKeyboard("layouts/en-us-qwerty.xml");
- keyboardContainer.appendChild(osKeyboard);
-
- osKeyboard.setKeyPressedHandler(
- function(keysym) {
- guac.sendKeyEvent(1, keysym);
- }
- );
-
- osKeyboard.setKeyReleasedHandler(
- function(keysym) {
- guac.sendKeyEvent(0, keysym);
- }
- );
-
- // Send Ctrl-Alt-Delete
- var ctrlAltDelete = document.getElementById("ctrlAltDelete");
-
- ctrlAltDelete.onclick = function() {
-
- var KEYSYM_CTRL = 0xFFE3;
- var KEYSYM_ALT = 0xFFE9;
- var KEYSYM_DELETE = 0xFFFF;
-
- guac.sendKeyEvent(1, KEYSYM_CTRL);
- guac.sendKeyEvent(1, KEYSYM_ALT);
- guac.sendKeyEvent(1, KEYSYM_DELETE);
- guac.sendKeyEvent(0, KEYSYM_DELETE);
- guac.sendKeyEvent(0, KEYSYM_ALT);
- guac.sendKeyEvent(0, KEYSYM_CTRL);
- };
-
- // Logout
- var logout = document.getElementById("logout");
-
- logout.onclick = function() {
- window.location.href = "logout";
- };
+ // Tie UI to client
+ GuacamoleUI.attach(guac);
try {
}
catch (e) {
- // TODO: Handle exception ...
+ GuacamoleUI.showError(e.message);
}
- display.onmouseout = function() {
- showMenu();
- };
-
- display.onmouseover = function() {
- shadeMenu();
- };
-
-
/* ]]> */ </script>
</body>
-var menu_shaded = false;
+// UI Definition
+var GuacamoleUI = {
-var shade_interval = null;
-var show_interval = null;
+ "display": document.getElementById("display"),
+ "menu" : document.getElementById("menu"),
+ "logo" : document.getElementById("status-logo"),
+ "state" : document.getElementById("state"),
-function shadeMenu() {
+ "buttons": {
- if (!menu_shaded) {
+ "showClipboard": document.getElementById("showClipboard"),
+ "showKeyboard" : document.getElementById("showKeyboard"),
+ "ctrlAltDelete": document.getElementById("ctrlAltDelete"),
+ "reconnect" : document.getElementById("reconnect"),
+ "logout" : document.getElementById("logout")
- var step = Math.floor(menu.offsetHeight / 5) + 1;
- var offset = 0;
- menu_shaded = true;
+ },
- window.clearInterval(show_interval);
- shade_interval = window.setInterval(function() {
+ "containers": {
+ "error" : document.getElementById("errorDialog"),
+ "clipboard": document.getElementById("clipboardDiv"),
+ "keyboard" : document.getElementById("keyboardContainer")
+ },
+
+ "error" : document.getElementById("errorText"),
+ "clipboard" : document.getElementById("clipboard")
- offset -= step;
- menu.style.top = offset + "px";
+};
- if (offset <= -menu.offsetHeight) {
- window.clearInterval(shade_interval);
- menu.style.visiblity = "hidden";
- }
+// Constant UI initialization and behavior
+(function() {
+
+ var menu_shaded = false;
+
+ var shade_interval = null;
+ var show_interval = null;
+
+ // Cache error image (might not be available when error occurs)
+ var guacErrorImage = new Image();
+ guacErrorImage.src = "images/noguacamole-logo-24.png";
+
+ GuacamoleUI.showError = function(error) {
+
+ GuacamoleUI.menu.className = "error";
+ GuacamoleUI.display.className += " guac-error";
+
+ GuacamoleUI.logo.src = guacErrorImage.src;
+ GuacamoleUI.error.textContent = error;
+ GuacamoleUI.containers.error.style.visibility = "visible";
+
+ };
+
+ GuacamoleUI.shadeMenu = function() {
+
+ if (!menu_shaded) {
+
+ var step = Math.floor(GuacamoleUI.menu.offsetHeight / 5) + 1;
+ var offset = 0;
+ menu_shaded = true;
+
+ window.clearInterval(show_interval);
+ shade_interval = window.setInterval(function() {
+
+ offset -= step;
+ GuacamoleUI.menu.style.top = offset + "px";
+
+ if (offset <= -GuacamoleUI.menu.offsetHeight) {
+ window.clearInterval(shade_interval);
+ GuacamoleUI.menu.style.visiblity = "hidden";
+ }
+
+ }, 30);
+ }
+
+ };
+
+ GuacamoleUI.showMenu = function() {
+
+ if (menu_shaded) {
+
+ var step = Math.floor(GuacamoleUI.menu.offsetHeight / 5) + 1;
+ var offset = -GuacamoleUI.menu.offsetHeight;
+ menu_shaded = false;
+ GuacamoleUI.menu.style.visiblity = "";
+
+ window.clearInterval(shade_interval);
+ show_interval = window.setInterval(function() {
+
+ offset += step;
+
+ if (offset >= 0) {
+ offset = 0;
+ window.clearInterval(show_interval);
+ }
+
+ GuacamoleUI.menu.style.top = offset + "px";
+
+ }, 30);
+ }
+
+ };
+
+ // Show/Hide clipboard
+ GuacamoleUI.buttons.showClipboard.onclick = function() {
+
+ var displayed = GuacamoleUI.containers.clipboard.style.display;
+ if (displayed != "block") {
+ GuacamoleUI.containers.clipboard.style.display = "block";
+ GuacamoleUI.buttons.showClipboard.innerHTML = "Hide Clipboard";
+ }
+ else {
+ GuacamoleUI.containers.clipboard.style.display = "none";
+ GuacamoleUI.buttons.showClipboard.innerHTML = "Show Clipboard";
+ GuacamoleUI.clipboard.onchange();
+ }
+
+ };
+
+ // Show/Hide keyboard
+ GuacamoleUI.buttons.showKeyboard.onclick = function() {
+
+ var displayed = GuacamoleUI.containers.keyboard.style.display;
+ if (displayed != "block") {
+ GuacamoleUI.containers.keyboard.style.display = "block";
+ GuacamoleUI.buttons.showKeyboard.textContent = "Hide Keyboard";
+ }
+ else {
+ GuacamoleUI.containers.keyboard.style.display = "none";
+ GuacamoleUI.buttons.showKeyboard.textContent = "Show Keyboard";
+ }
+
+ };
+
+ // Logout
+ GuacamoleUI.buttons.logout.onclick = function() {
+ window.location.href = "logout";
+ };
+
+ GuacamoleUI.display.onmouseout = function() {
+ GuacamoleUI.showMenu();
+ };
+
+ GuacamoleUI.display.onmouseover = function() {
+ GuacamoleUI.shadeMenu();
+ };
+
+ // Reconnect button
+ GuacamoleUI.buttons.reconnect.onclick = function() {
+ window.location.reload();
+ };
- }, 30);
+ // On-screen keyboard
+ GuacamoleUI.keyboard = new Guacamole.OnScreenKeyboard("layouts/en-us-qwerty.xml");
+ GuacamoleUI.containers.keyboard.appendChild(GuacamoleUI.keyboard);
+
+})();
+
+// Tie UI events / behavior to a specific Guacamole client
+GuacamoleUI.attach = function(guac) {
+
+ // Mouse
+ var mouse = new Guacamole.Mouse(GuacamoleUI.display);
+ mouse.onmousedown = mouse.onmouseup = mouse.onmousemove =
+ function(mouseState) {
+
+ if (mouseState.y <= 5)
+ GuacamoleUI.showMenu();
+
+ guac.sendMouseState(mouseState);
+ };
+
+ // Keyboard
+ var keyboard = new Guacamole.Keyboard(document);
+
+ function disableKeyboard() {
+ keyboard.onkeydown = null;
+ keyboard.onkeyup = null;
+ }
+
+ function enableKeyboard() {
+ keyboard.onkeydown =
+ function (keysym) {
+ guac.sendKeyEvent(1, keysym);
+ };
+
+ keyboard.onkeyup =
+ function (keysym) {
+ guac.sendKeyEvent(0, keysym);
+ };
}
-}
+ // Enable keyboard by default
+ enableKeyboard();
+
+ // Handle client state change
+ guac.onstatechange = function(clientState) {
+ switch (clientState) {
+
+ // Idle
+ case 0:
+ GuacamoleUI.state.textContent = "Idle."
+ break;
+
+ // Connecting
+ case 1:
+ GuacamoleUI.state.textContent = "Connecting...";
+ break;
+
+ // Connected + waiting
+ case 2:
+ GuacamoleUI.state.textContent = "Connected, waiting for first update...";
+ break;
+
+ // Connected
+ case 3:
+
+ GuacamoleUI.display.className =
+ GuacamoleUI.display.className.replace(/guac-loading/, '');
+
+ GuacamoleUI.menu.className = "connected";
+ GuacamoleUI.state.textContent = "Connected.";
+ GuacamoleUI.shadeMenu();
+ break;
+
+ // Disconnecting
+ case 4:
+ GuacamoleUI.state.textContent = "Disconnecting...";
+ break;
+
+ // Disconnected
+ case 5:
+ GuacamoleUI.state.textContent = "Disconnected.";
+ break;
-function showMenu() {
+ // Unknown status code
+ default:
+ GuacamoleUI.state.textContent = "Unknown";
- if (menu_shaded) {
+ }
+ };
- var step = Math.floor(menu.offsetHeight / 5) + 1;
- var offset = -menu.offsetHeight;
- menu_shaded = false;
- menu.style.visiblity = "";
+ // Name instruction handler
+ guac.onname = function(name) {
+ document.title = name;
+ };
- window.clearInterval(shade_interval);
- show_interval = window.setInterval(function() {
+ // Error handler
+ guac.onerror = function(error) {
- offset += step;
+ // Disconnect, if connected
+ guac.disconnect();
+
+ // Display error message
+ GuacamoleUI.showError(error);
+
+ // Show error by desaturating display
+ var layers = guac.getLayers();
+ for (var i=0; i<layers.length; i++) {
+ layers[i].filter(desaturateFilter);
+ }
+
+ // Filter for desaturation
+ function desaturateFilter(data, width, height) {
+
+ for (var i=0; i<data.length; i+=4) {
+
+ // Get RGB values
+ var r = data[i];
+ var g = data[i+1];
+ var b = data[i+2];
+
+ // Desaturate
+ var v = Math.max(r, g, b) / 2;
+ data[i] = v;
+ data[i+1] = v;
+ data[i+2] = v;
- if (offset >= 0) {
- offset = 0;
- window.clearInterval(show_interval);
}
- menu.style.top = offset + "px";
+ }
+
+ };
- }, 30);
- }
+ // Disconnect on close
+ window.onunload = function() {
+ guac.disconnect();
+ };
+
+ // Handle clipboard events
+ GuacamoleUI.clipboard.onchange = function() {
+
+ var text = GuacamoleUI.clipboard.value;
+ guac.setClipboard(text);
+
+ };
+
+ // Ignore keypresses when clipboard is focused
+ GuacamoleUI.clipboard.onfocus = function() {
+ disableKeyboard();
+ };
+
+ // Capture keypresses when clipboard is not focused
+ GuacamoleUI.clipboard.onblur = function() {
+ enableKeyboard();
+ };
+
+ // Server copy handler
+ guac.onclipboard = function(data) {
+ GuacamoleUI.clipboard.value = data;
+ };
+
+ GuacamoleUI.keyboard.setKeyPressedHandler(
+ function(keysym) {
+ guac.sendKeyEvent(1, keysym);
+ }
+ );
+
+ GuacamoleUI.keyboard.setKeyReleasedHandler(
+ function(keysym) {
+ guac.sendKeyEvent(0, keysym);
+ }
+ );
+
+ // Send Ctrl-Alt-Delete
+ GuacamoleUI.buttons.ctrlAltDelete.onclick = function() {
+
+ var KEYSYM_CTRL = 0xFFE3;
+ var KEYSYM_ALT = 0xFFE9;
+ var KEYSYM_DELETE = 0xFFFF;
-}
+ guac.sendKeyEvent(1, KEYSYM_CTRL);
+ guac.sendKeyEvent(1, KEYSYM_ALT);
+ guac.sendKeyEvent(1, KEYSYM_DELETE);
+ guac.sendKeyEvent(0, KEYSYM_DELETE);
+ guac.sendKeyEvent(0, KEYSYM_ALT);
+ guac.sendKeyEvent(0, KEYSYM_CTRL);
+ };
+};
\ No newline at end of file