<link rel="icon" type="image/png" href="images/guacamole-logo-64.png"/>
<link rel="stylesheet" type="text/css" href="styles/client.css"/>
<link rel="stylesheet" type="text/css" href="styles/keyboard.css"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi"/>
+ <meta name="apple-mobile-web-app-capable" content="yes"/>
<title>Guacamole ${project.version}</title>
</head>
<button id="showKeyboard">Show Keyboard</button>
<button id="ctrlAltDelete">Ctrl-Alt-Delete</button>
+ <button id="logout">Logout</button>
<!-- Logo and status -->
<img id="status-logo" class="logo" src="images/guacamole-logo-24.png" alt="Guacamole" title="Guacamole ${project.version}"/>
- <span id="state"></span>
- <a href="logout">Logout</a>
</div>
<!-- Display -->
- <div id="display" class="guac-display guac-loading">
- <!-- On-screen keyboard -->
- <div id="keyboardContainer"></div>
+ <div id="display">
+
+ <!-- Menu trigger -->
+ <div id="menuControl"></div>
+
</div>
+ <!-- On-screen keyboard -->
+ <div id="keyboardContainer"></div>
+
+ <!-- Dimensional clone of viewport -->
+ <div id="viewportClone"/>
- <!-- Error Dialog-->
- <div id="errorDialog" class="errorDialogOuter">
- <div class="errorDialogMiddle">
- <div class="errorDialog">
- <p id="errorText"></p>
+ <!-- Dialogs -->
+ <div class="dialogOuter">
+ <div class="dialogMiddle">
+
+ <!-- Status Dialog -->
+ <div id="statusDialog" class="dialog">
+ <p id="statusText"></p>
<div class="buttons"><button id="reconnect">Reconnect</button></div>
</div>
+
</div>
</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/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,
- new Guacamole.HTTPTunnel("tunnel")
- );
-
- var menu = document.getElementById("menu");
- var logo = document.getElementById("status-logo");
+ // Start connect after control returns from onload (allow browser
+ // to consider the page loaded).
+ window.onload = function() {
+ window.setTimeout(function() {
- var errorDialog = document.getElementById("errorDialog");
- var errorDialogText = document.getElementById("errorText");
+ var tunnel;
- // Position display correctly
- window.onresize = function() {
- display.style.top = menu.offsetHeight + "px";
- };
-
- window.onresize();
-
- 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.";
- 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;
- };
+ // If WebSocket available, try to use it.
+ if (window.WebSocket)
+ tunnel = new Guacamole.WebSocketTunnel("websocket-tunnel")
- guac.onerror = function(error) {
+ // If no WebSocket, then use HTTP.
+ else
+ tunnel = new Guacamole.HTTPTunnel("tunnel")
- guac.disconnect();
+ // Instantiate client
+ var guac = new Guacamole.Client(tunnel);
- menu.className = "error";
- display.className += " guac-error";
+ // Add client to UI
+ guac.getDisplay().className = "software-cursor";
+ GuacamoleUI.display.appendChild(guac.getDisplay());
- logo.src = guacErrorImage.src;
- errorDialogText.textContent = error;
- errorDialog.style.visibility = "visible";
+ // Tie UI to client
+ GuacamoleUI.attach(guac);
- // Show error by desaturating display
- var layers = guac.getLayers();
- for (var i=0; i<layers.length; i++) {
- layers[i].filter(desaturateFilter);
- }
+ try {
- // Filter for desaturation
- function desaturateFilter(data, width, height) {
+ // Get ID
+ var id = window.location.search.substring(1);
- 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;
+ // Connect client
+ guac.connect("id=" + id);
}
-
- }
-
- };
-
- // Mouse
- var mouse = new Guacamole.Mouse(display);
- mouse.onmousedown = mouse.onmouseup = mouse.onmousemove =
- function(mouseState) {
- 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);
+ catch (e) {
+ GuacamoleUI.showError(e.message);
}
- );
-
- // Send Ctrl-Alt-Delete
- var ctrlAltDelete = document.getElementById("ctrlAltDelete");
-
- ctrlAltDelete.onclick = function() {
-
- var KEYSYM_CTRL = 0xFF03;
- 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);
- }
-
-
- try {
-
- // Get ID
- var url = window.location.href;
- var query = url.indexOf("?");
- var id = url.substring(query+1);
-
- // Connect client
- guac.connect("id=" + encodeURIComponent(id));
-
- }
- catch (e) {
- // TODO: Handle exception ...
- }
+ }, 0);
+ };
- /* ]]> */ </script>
+ /* ]]> */ </script>
</body>