Allow logout button to work where no Java app used
[guacamole.git] / src / main / webapp / client.xhtml
index 43fbefa..66d6184 100644 (file)
@@ -25,6 +25,8 @@
         <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>
 
 
             <!-- 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>
 
         </div>
 
+        <!-- Touch-specific menu -->
+        <div id="touchMenu"><img id="touchShowClipboard" src="images/menu-icons/tango/edit-paste.png"/><img id="touchShowKeyboard" src="images/menu-icons/tango/input-keyboard.png"/><img id="touchLogout" src="images/menu-icons/tango/system-log-out.png"/></div>
+
+        <!-- Touch-specific clipboard -->
+        <div id="touchClipboardDiv">
+            <h2>Clipboard</h2>
+            <p>
+            Text copied/cut within Guacamole will appear here. Changes to the text will affect the remote clipboard, and will be pastable within the remote desktop. Use the textbox below as an interface between the client and server clipboards.
+            </p>
+            <textarea rows="10" cols="40" id="touchClipboard"></textarea>
+        </div>
+
+        <!-- Keyboard event target for platforms with native OSKs -->
+        <textarea id="eventTarget"></textarea>
 
         <!-- 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>
 
-        <!-- Error Dialog-->
-        <div id="errorDialog" class="errorDialogOuter">
-            <div class="errorDialogMiddle">
-                <div class="errorDialog">
-                    <p id="errorText"></p>
+        <!-- Dimensional clone of viewport -->
+        <div id="viewportClone"/>
+
+        <!-- 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")
-            );
+            // Start connect after control returns from onload (allow browser
+            // to consider the page loaded).
+            window.onload = function() {
+                window.setTimeout(function() {
 
-            var menu = document.getElementById("menu");
-            var logo = document.getElementById("status-logo");
+                    var tunnel;
 
-            var errorDialog = document.getElementById("errorDialog");
-            var errorDialogText = document.getElementById("errorText");
-
-            // 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";
+                    function getParameter (paramName, defaultValue) {
+                       var regex = new RegExp('[?][^#]*' + paramName + '=([^&#]*)');
+                       if (typeof defaultValue === 'undefined') {
+                           defaultValue = null;
+                       }
+                       return (window.location.href.match(regex) || ['', defaultValue])[1];
                     }
-            };
-
-            // 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;
 
+                    var tunneltype = getParameter("tunnel");
+                    var wsendpoint = getParameter("wsendpoint", "websocket-tunnel");
+                    var httpendpoint = getParameter("httpendpoint", "tunnel");
+                     /* Should Window close on logout */
+                    window.SELF_CLOSE = getParameter("selfclose", 0); /* if 1 then the window will close on logout if 0 then the logout will redirect, defaults to 0 */
+
+                    switch (tunneltype) {
+                      case 'http':
+                        tunnel = new Guacamole.HTTPTunnel(httpendpoint);
+                        break;
+                      case 'ws':
+                        if (window.WebSocket)
+                            tunnel = new Guacamole.WebSocketTunnel(wsendpoint);
+                        break;
+                      case 'chained':
+                        if (window.WebSocket)
+                            tunnel = new Guacamole.ChainedTunnel(
+                                new Guacamole.WebSocketTunnel(wsendpoint),
+                                new Guacamole.HTTPTunnel(httpendpoint)
+                            );
+                        break;
+                      default:
+                        // Try to guess what tunnel we are using
+                        // If WebSocket available, try to use it.
+                        if (window.WebSocket)
+                            tunnel = new Guacamole.ChainedTunnel(
+                                new Guacamole.WebSocketTunnel(wsendpoint),
+                                new Guacamole.HTTPTunnel(httpendpoint)
+                            );
+                        // If no WebSocket, then use HTTP.
+                        else
+                            tunnel = new Guacamole.HTTPTunnel(httpendpoint);
+                        break;
                     }
 
-                }
+                    // Instantiate client
+                    var guac = new Guacamole.Client(tunnel);
 
-            };
+                    // Add client to UI
+                    guac.getDisplay().className = "software-cursor";
+                    GuacamoleUI.display.appendChild(guac.getDisplay());
 
-            // 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();
-            }
+                    // Tie UI to client
+                    GuacamoleUI.attach(guac);
 
-            // Handle clipboard events
-            var clipboardElement = document.getElementById("clipboard");
-            clipboardElement.onchange = function() {
+                    try {
 
-                var text = clipboardElement.value;
-                guac.setClipboard(text);
+                        // Get entire query string, and pass to connect().
+                        // Normally, only the "id" parameter is required, but
+                        // all parameters should be preserved and passed on for
+                        // the sake of authentication.
 
-            };
+                        var connect_string = window.location.search.substring(1);
+                        guac.connect(connect_string);
 
-            // 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);
-            };
-
-            // Logout
-            var logout = document.getElementById("logout");
 
-            logout.onclick = function() {
-                window.location.href = "logout";
+                }, 0);
             };
 
-            try {
-
-                // Get ID
-                var url = window.location.href;
-                var query = url.indexOf("?");
-                var id = url.substring(query+1);
-
-                // Connect client
-                guac.connect("id=" + id);
-
-            }
-            catch (e) {
-                // TODO: Handle exception ...
-            }
-
-
-            /* ]]> */ </script>
+        /* ]]> */ </script>
 
     </body>