http://git-wip-us.apache.org/repos/asf/incubator-guacamole-website/blob/eff0fb8d/content/doc/0.9.13-incubating/guacamole-common-js/Parser.js.html ---------------------------------------------------------------------- diff --git a/content/doc/0.9.13-incubating/guacamole-common-js/Parser.js.html b/content/doc/0.9.13-incubating/guacamole-common-js/Parser.js.html new file mode 100644 index 0000000..5844060 --- /dev/null +++ b/content/doc/0.9.13-incubating/guacamole-common-js/Parser.js.html @@ -0,0 +1,217 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>JSDoc: Source: Parser.js</title> + + <script src="scripts/prettify/prettify.js"> </script> + <script src="scripts/prettify/lang-css.js"> </script> + <!--[if lt IE 9]> + <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> + <![endif]--> + <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> + <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> +</head> + +<body> + +<div id="main"> + + <h1 class="page-title">Source: Parser.js</h1> + + + + + + + <section> + <article> + <pre class="prettyprint source linenums"><code>/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var Guacamole = Guacamole || {}; + +/** + * Simple Guacamole protocol parser that invokes an oninstruction event when + * full instructions are available from data received via receive(). + * + * @constructor + */ +Guacamole.Parser = function() { + + /** + * Reference to this parser. + * @private + */ + var parser = this; + + /** + * Current buffer of received data. This buffer grows until a full + * element is available. After a full element is available, that element + * is flushed into the element buffer. + * + * @private + */ + var buffer = ""; + + /** + * Buffer of all received, complete elements. After an entire instruction + * is read, this buffer is flushed, and a new instruction begins. + * + * @private + */ + var element_buffer = []; + + // The location of the last element's terminator + var element_end = -1; + + // Where to start the next length search or the next element + var start_index = 0; + + /** + * Appends the given instruction data packet to the internal buffer of + * this Guacamole.Parser, executing all completed instructions at + * the beginning of this buffer, if any. + * + * @param {String} packet The instruction data to receive. + */ + this.receive = function(packet) { + + // Truncate buffer as necessary + if (start_index > 4096 && element_end >= start_index) { + + buffer = buffer.substring(start_index); + + // Reset parse relative to truncation + element_end -= start_index; + start_index = 0; + + } + + // Append data to buffer + buffer += packet; + + // While search is within currently received data + while (element_end < buffer.length) { + + // If we are waiting for element data + if (element_end >= start_index) { + + // We now have enough data for the element. Parse. + var element = buffer.substring(start_index, element_end); + var terminator = buffer.substring(element_end, element_end+1); + + // Add element to array + element_buffer.push(element); + + // If last element, handle instruction + if (terminator == ";") { + + // Get opcode + var opcode = element_buffer.shift(); + + // Call instruction handler. + if (parser.oninstruction != null) + parser.oninstruction(opcode, element_buffer); + + // Clear elements + element_buffer.length = 0; + + } + else if (terminator != ',') + throw new Error("Illegal terminator."); + + // Start searching for length at character after + // element terminator + start_index = element_end + 1; + + } + + // Search for end of length + var length_end = buffer.indexOf(".", start_index); + if (length_end != -1) { + + // Parse length + var length = parseInt(buffer.substring(element_end+1, length_end)); + if (isNaN(length)) + throw new Error("Non-numeric character in element length."); + + // Calculate start of element + start_index = length_end + 1; + + // Calculate location of element terminator + element_end = start_index + length; + + } + + // If no period yet, continue search when more data + // is received + else { + start_index = buffer.length; + break; + } + + } // end parse loop + + }; + + /** + * Fired once for every complete Guacamole instruction received, in order. + * + * @event + * @param {String} opcode The Guacamole instruction opcode. + * @param {Array} parameters The parameters provided for the instruction, + * if any. + */ + this.oninstruction = null; + +}; +</code></pre> + </article> + </section> + + + + +</div> + +<nav> + <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Client</a></li><li><a href="Guacamole.DataURIReader.html">DataURIReader</a></li><li><a href="Guacamole.Display.html">Display</a></li><li><a href="Guacamole.Display.VisibleLayer.html">VisibleLayer</a></li><li><a href="Guacamole.HTTPTunnel.html">HTTPTunnel</a></li><li><a href="Guacamole.InputStream.html">InputStream</a></li><li><a href="Guacamole.IntegerPool.html">IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">JSONReader</a></li> <li><a href="Guacamole.Keyboard.html">Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">ModifierState</a></li><li><a href="Guacamole.Layer.html">Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Pixel</a></li><li><a href="Guacamole.Mouse.html">Mouse</a></li><li><a href="Guacamole.Mouse.State.html">State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Touchscreen</a></li><li><a href="Guacamole.Object.html">Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Layout</a></li><li><a href="Guacamole.OutputStream.html">OutputStream</a></li><li><a href="Guacamole.Parser.html">Parser</a></li><li><a href="Guacamole.RawAudioFormat.html">RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioR ecorder.html">RawAudioRecorder</a></li><li><a href="Guacamole.SessionRecording.html">SessionRecording</a></li><li><a href="Guacamole.StaticHTTPTunnel.html">StaticHTTPTunnel</a></li><li><a href="Guacamole.Status.html">Status</a></li><li><a href="Guacamole.StringReader.html">StringReader</a></li><li><a href="Guacamole.StringWriter.html">StringWriter</a></li><li><a href="Guacamole.Tunnel.html">Tunnel</a></li><li><a href="Guacamole.VideoPlayer.html">VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">onend</a></li>< li><a href="Guacamole.BlobReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">onack</a></li><li><a href="Guacamole.BlobWriter.html#event:oncomplete">oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onaudio">onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onna me">onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">onpipe</a></li><li><a href="Guacamole.Client.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">onresize</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.InputStream.html#event:onblob">onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">onprog ress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.html#event:onmouseout">onmouseout</a></li><li><a href="Guacamole.Mouse.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">onbody</a></li>< li><a href="Guacamole.Object.html#event:onundefine">onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.SessionRecording.html#event:onpause">onpause</a></li><li><a href="Guacamole.SessionRecording.html#event:onplay">onplay</a></li><li><a href="Guacamole .SessionRecording.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.SessionRecording.html#event:onseek">onseek</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.StringReader.html#event:onend">onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">onack</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamol e.WebSocketTunnel.html#event:onstatechange">onstatechange</a></li></ul><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">AudioContextFactory</a></li></ul> +</nav> + +<br class="clear"> + +<footer> + Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Sun Jul 02 2017 12:09:53 GMT-0700 (PDT) +</footer> + +<script> prettyPrint(); </script> +<script src="scripts/linenumber.js"> </script> + <!-- Google Analytics --> + <script type="text/javascript"> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-75289145-1', 'auto'); + ga('send', 'pageview'); + </script> +</body> +</html>
http://git-wip-us.apache.org/repos/asf/incubator-guacamole-website/blob/eff0fb8d/content/doc/0.9.13-incubating/guacamole-common-js/RawAudioFormat.js.html ---------------------------------------------------------------------- diff --git a/content/doc/0.9.13-incubating/guacamole-common-js/RawAudioFormat.js.html b/content/doc/0.9.13-incubating/guacamole-common-js/RawAudioFormat.js.html new file mode 100644 index 0000000..e47fa64 --- /dev/null +++ b/content/doc/0.9.13-incubating/guacamole-common-js/RawAudioFormat.js.html @@ -0,0 +1,207 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>JSDoc: Source: RawAudioFormat.js</title> + + <script src="scripts/prettify/prettify.js"> </script> + <script src="scripts/prettify/lang-css.js"> </script> + <!--[if lt IE 9]> + <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> + <![endif]--> + <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> + <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> +</head> + +<body> + +<div id="main"> + + <h1 class="page-title">Source: RawAudioFormat.js</h1> + + + + + + + <section> + <article> + <pre class="prettyprint source linenums"><code>/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var Guacamole = Guacamole || {}; + +/** + * A description of the format of raw PCM audio, such as that used by + * Guacamole.RawAudioPlayer and Guacamole.RawAudioRecorder. This object + * describes the number of bytes per sample, the number of channels, and the + * overall sample rate. + * + * @constructor + * @param {Guacamole.RawAudioFormat|Object} template + * The object whose properties should be copied into the corresponding + * properties of the new Guacamole.RawAudioFormat. + */ +Guacamole.RawAudioFormat = function RawAudioFormat(template) { + + /** + * The number of bytes in each sample of audio data. This value is + * independent of the number of channels. + * + * @type {Number} + */ + this.bytesPerSample = template.bytesPerSample; + + /** + * The number of audio channels (ie: 1 for mono, 2 for stereo). + * + * @type {Number} + */ + this.channels = template.channels; + + /** + * The number of samples per second, per channel. + * + * @type {Number} + */ + this.rate = template.rate; + +}; + +/** + * Parses the given mimetype, returning a new Guacamole.RawAudioFormat + * which describes the type of raw audio data represented by that mimetype. If + * the mimetype is not a supported raw audio data mimetype, null is returned. + * + * @param {String} mimetype + * The audio mimetype to parse. + * + * @returns {Guacamole.RawAudioFormat} + * A new Guacamole.RawAudioFormat which describes the type of raw + * audio data represented by the given mimetype, or null if the given + * mimetype is not supported. + */ +Guacamole.RawAudioFormat.parse = function parseFormat(mimetype) { + + var bytesPerSample; + + // Rate is absolutely required - if null is still present later, the + // mimetype must not be supported + var rate = null; + + // Default for both "audio/L8" and "audio/L16" is one channel + var channels = 1; + + // "audio/L8" has one byte per sample + if (mimetype.substring(0, 9) === 'audio/L8;') { + mimetype = mimetype.substring(9); + bytesPerSample = 1; + } + + // "audio/L16" has two bytes per sample + else if (mimetype.substring(0, 10) === 'audio/L16;') { + mimetype = mimetype.substring(10); + bytesPerSample = 2; + } + + // All other types are unsupported + else + return null; + + // Parse all parameters + var parameters = mimetype.split(','); + for (var i = 0; i < parameters.length; i++) { + + var parameter = parameters[i]; + + // All parameters must have an equals sign separating name from value + var equals = parameter.indexOf('='); + if (equals === -1) + return null; + + // Parse name and value from parameter string + var name = parameter.substring(0, equals); + var value = parameter.substring(equals+1); + + // Handle each supported parameter + switch (name) { + + // Number of audio channels + case 'channels': + channels = parseInt(value); + break; + + // Sample rate + case 'rate': + rate = parseInt(value); + break; + + // All other parameters are unsupported + default: + return null; + + } + + }; + + // The rate parameter is required + if (rate === null) + return null; + + // Return parsed format details + return new Guacamole.RawAudioFormat({ + bytesPerSample : bytesPerSample, + channels : channels, + rate : rate + }); + +}; +</code></pre> + </article> + </section> + + + + +</div> + +<nav> + <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Client</a></li><li><a href="Guacamole.DataURIReader.html">DataURIReader</a></li><li><a href="Guacamole.Display.html">Display</a></li><li><a href="Guacamole.Display.VisibleLayer.html">VisibleLayer</a></li><li><a href="Guacamole.HTTPTunnel.html">HTTPTunnel</a></li><li><a href="Guacamole.InputStream.html">InputStream</a></li><li><a href="Guacamole.IntegerPool.html">IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">JSONReader</a></li> <li><a href="Guacamole.Keyboard.html">Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">ModifierState</a></li><li><a href="Guacamole.Layer.html">Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Pixel</a></li><li><a href="Guacamole.Mouse.html">Mouse</a></li><li><a href="Guacamole.Mouse.State.html">State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Touchscreen</a></li><li><a href="Guacamole.Object.html">Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Layout</a></li><li><a href="Guacamole.OutputStream.html">OutputStream</a></li><li><a href="Guacamole.Parser.html">Parser</a></li><li><a href="Guacamole.RawAudioFormat.html">RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioR ecorder.html">RawAudioRecorder</a></li><li><a href="Guacamole.SessionRecording.html">SessionRecording</a></li><li><a href="Guacamole.StaticHTTPTunnel.html">StaticHTTPTunnel</a></li><li><a href="Guacamole.Status.html">Status</a></li><li><a href="Guacamole.StringReader.html">StringReader</a></li><li><a href="Guacamole.StringWriter.html">StringWriter</a></li><li><a href="Guacamole.Tunnel.html">Tunnel</a></li><li><a href="Guacamole.VideoPlayer.html">VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">onend</a></li>< li><a href="Guacamole.BlobReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">onack</a></li><li><a href="Guacamole.BlobWriter.html#event:oncomplete">oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onaudio">onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onna me">onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">onpipe</a></li><li><a href="Guacamole.Client.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">onresize</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.InputStream.html#event:onblob">onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">onprog ress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.html#event:onmouseout">onmouseout</a></li><li><a href="Guacamole.Mouse.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">onbody</a></li>< li><a href="Guacamole.Object.html#event:onundefine">onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.SessionRecording.html#event:onpause">onpause</a></li><li><a href="Guacamole.SessionRecording.html#event:onplay">onplay</a></li><li><a href="Guacamole .SessionRecording.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.SessionRecording.html#event:onseek">onseek</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.StringReader.html#event:onend">onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">onack</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamol e.WebSocketTunnel.html#event:onstatechange">onstatechange</a></li></ul><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">AudioContextFactory</a></li></ul> +</nav> + +<br class="clear"> + +<footer> + Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Sun Jul 02 2017 12:09:53 GMT-0700 (PDT) +</footer> + +<script> prettyPrint(); </script> +<script src="scripts/linenumber.js"> </script> + <!-- Google Analytics --> + <script type="text/javascript"> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-75289145-1', 'auto'); + ga('send', 'pageview'); + </script> +</body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-guacamole-website/blob/eff0fb8d/content/doc/0.9.13-incubating/guacamole-common-js/SessionRecording.js.html ---------------------------------------------------------------------- diff --git a/content/doc/0.9.13-incubating/guacamole-common-js/SessionRecording.js.html b/content/doc/0.9.13-incubating/guacamole-common-js/SessionRecording.js.html new file mode 100644 index 0000000..8308401 --- /dev/null +++ b/content/doc/0.9.13-incubating/guacamole-common-js/SessionRecording.js.html @@ -0,0 +1,810 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>JSDoc: Source: SessionRecording.js</title> + + <script src="scripts/prettify/prettify.js"> </script> + <script src="scripts/prettify/lang-css.js"> </script> + <!--[if lt IE 9]> + <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> + <![endif]--> + <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> + <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> +</head> + +<body> + +<div id="main"> + + <h1 class="page-title">Source: SessionRecording.js</h1> + + + + + + + <section> + <article> + <pre class="prettyprint source linenums"><code>/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var Guacamole = Guacamole || {}; + +/** + * A recording of a Guacamole session. Given a {@link Guacamole.Tunnel}, the + * Guacamole.SessionRecording automatically handles incoming Guacamole + * instructions, storing them for playback. Playback of the recording may be + * controlled through function calls to the Guacamole.SessionRecording, even + * while the recording has not yet finished being created or downloaded. + * + * @constructor + * @param {Guacamole.Tunnel} tunnel + * The Guacamole.Tunnel from which the instructions of the recording should + * be read. + */ +Guacamole.SessionRecording = function SessionRecording(tunnel) { + + /** + * Reference to this Guacamole.SessionRecording. + * + * @private + * @type {Guacamole.SessionRecording} + */ + var recording = this; + + /** + * The minimum number of characters which must have been read between + * keyframes. + * + * @private + * @constant + * @type {Number} + */ + var KEYFRAME_CHAR_INTERVAL = 16384; + + /** + * The minimum number of milliseconds which must elapse between keyframes. + * + * @private + * @constant + * @type {Number} + */ + var KEYFRAME_TIME_INTERVAL = 5000; + + /** + * All frames parsed from the provided tunnel. + * + * @private + * @type {Guacamole.SessionRecording._Frame[]} + */ + var frames = []; + + /** + * All instructions which have been read since the last frame was added to + * the frames array. + * + * @private + * @type {Guacamole.SessionRecording._Frame.Instruction[]} + */ + var instructions = []; + + /** + * The approximate number of characters which have been read from the + * provided tunnel since the last frame was flagged for use as a keyframe. + * + * @private + * @type {Number} + */ + var charactersSinceLastKeyframe = 0; + + /** + * The timestamp of the last frame which was flagged for use as a keyframe. + * If no timestamp has yet been flagged, this will be 0. + * + * @private + * @type {Number} + */ + var lastKeyframeTimestamp = 0; + + /** + * Tunnel which feeds arbitrary instructions to the client used by this + * Guacamole.SessionRecording for playback of the session recording. + * + * @private + * @type {Guacamole.SessionRecording._PlaybackTunnel} + */ + var playbackTunnel = new Guacamole.SessionRecording._PlaybackTunnel(); + + /** + * Guacamole.Client instance used for visible playback of the session + * recording. + * + * @private + * @type {Guacamole.Client} + */ + var playbackClient = new Guacamole.Client(playbackTunnel); + + /** + * The current frame rendered within the playback client. If no frame is + * yet rendered, this will be -1. + * + * @private + * @type {Number} + */ + var currentFrame = -1; + + /** + * The timestamp of the frame when playback began, in milliseconds. If + * playback is not in progress, this will be null. + * + * @private + * @type {Number} + */ + var startVideoTimestamp = null; + + /** + * The real-world timestamp when playback began, in milliseconds. If + * playback is not in progress, this will be null. + * + * @private + * @type {Number} + */ + var startRealTimestamp = null; + + /** + * The ID of the timeout which will play the next frame, if playback is in + * progress. If playback is not in progress, the ID stored here (if any) + * will not be valid. + * + * @private + * @type {Number} + */ + var playbackTimeout = null; + + // Start playback client connected + playbackClient.connect(); + + // Hide cursor unless mouse position is received + playbackClient.getDisplay().showCursor(false); + + // Read instructions from provided tunnel, extracting each frame + tunnel.oninstruction = function handleInstruction(opcode, args) { + + // Store opcode and arguments for received instruction + var instruction = new Guacamole.SessionRecording._Frame.Instruction(opcode, args.slice()); + instructions.push(instruction); + charactersSinceLastKeyframe += instruction.getSize(); + + // Once a sync is received, store all instructions since the last + // frame as a new frame + if (opcode === 'sync') { + + // Parse frame timestamp from sync instruction + var timestamp = parseInt(args[0]); + + // Add a new frame containing the instructions read since last frame + var frame = new Guacamole.SessionRecording._Frame(timestamp, instructions); + frames.push(frame); + + // This frame should eventually become a keyframe if enough data + // has been processed and enough recording time has elapsed, or if + // this is the absolute first frame + if (frames.length === 1 || (charactersSinceLastKeyframe >= KEYFRAME_CHAR_INTERVAL + && timestamp - lastKeyframeTimestamp >= KEYFRAME_TIME_INTERVAL)) { + frame.keyframe = true; + lastKeyframeTimestamp = timestamp; + charactersSinceLastKeyframe = 0; + } + + // Clear set of instructions in preparation for next frame + instructions = []; + + // Notify that additional content is available + if (recording.onprogress) + recording.onprogress(recording.getDuration()); + + } + + }; + + /** + * Converts the given absolute timestamp to a timestamp which is relative + * to the first frame in the recording. + * + * @private + * @param {Number} timestamp + * The timestamp to convert to a relative timestamp. + * + * @returns {Number} + * The difference in milliseconds between the given timestamp and the + * first frame of the recording, or zero if no frames yet exist. + */ + var toRelativeTimestamp = function toRelativeTimestamp(timestamp) { + + // If no frames yet exist, all timestamps are zero + if (frames.length === 0) + return 0; + + // Calculate timestamp relative to first frame + return timestamp - frames[0].timestamp; + + }; + + /** + * Searches through the given region of frames for the frame having a + * relative timestamp closest to the timestamp given. + * + * @private + * @param {Number} minIndex + * The index of the first frame in the region (the frame having the + * smallest timestamp). + * + * @param {Number} maxIndex + * The index of the last frame in the region (the frame having the + * largest timestamp). + * + * @param {Number} timestamp + * The relative timestamp to search for, where zero denotes the first + * frame in the recording. + * + * @returns {Number} + * The index of the frame having a relative timestamp closest to the + * given value. + */ + var findFrame = function findFrame(minIndex, maxIndex, timestamp) { + + // Do not search if the region contains only one element + if (minIndex === maxIndex) + return minIndex; + + // Split search region into two halves + var midIndex = Math.floor((minIndex + maxIndex) / 2); + var midTimestamp = toRelativeTimestamp(frames[midIndex].timestamp); + + // If timestamp is within lesser half, search again within that half + if (timestamp < midTimestamp && midIndex > minIndex) + return findFrame(minIndex, midIndex - 1, timestamp); + + // If timestamp is within greater half, search again within that half + if (timestamp > midTimestamp && midIndex < maxIndex) + return findFrame(midIndex + 1, maxIndex, timestamp); + + // Otherwise, we lucked out and found a frame with exactly the + // desired timestamp + return midIndex; + + }; + + /** + * Replays the instructions associated with the given frame, sending those + * instructions to the playback client. + * + * @private + * @param {Number} index + * The index of the frame within the frames array which should be + * replayed. + */ + var replayFrame = function replayFrame(index) { + + var frame = frames[index]; + + // Replay all instructions within the retrieved frame + for (var i = 0; i < frame.instructions.length; i++) { + var instruction = frame.instructions[i]; + playbackTunnel.receiveInstruction(instruction.opcode, instruction.args); + } + + // Store client state if frame is flagged as a keyframe + if (frame.keyframe && !frame.clientState) { + playbackClient.exportState(function storeClientState(state) { + frame.clientState = state; + }); + } + + }; + + /** + * Moves the playback position to the given frame, resetting the state of + * the playback client and replaying frames as necessary. + * + * @private + * @param {Number} index + * The index of the frame which should become the new playback + * position. + */ + var seekToFrame = function seekToFrame(index) { + + var startIndex; + + // Back up until startIndex represents current state + for (startIndex = index; startIndex >= 0; startIndex--) { + + var frame = frames[startIndex]; + + // If we've reached the current frame, startIndex represents + // current state by definition + if (startIndex === currentFrame) + break; + + // If frame has associated absolute state, make that frame the + // current state + if (frame.clientState) { + playbackClient.importState(frame.clientState); + break; + } + + } + + // Advance to frame index after current state + startIndex++; + + // Replay any applicable incremental frames + for (; startIndex <= index; startIndex++) + replayFrame(startIndex); + + // Current frame is now at requested index + currentFrame = index; + + // Notify of changes in position + if (recording.onseek) + recording.onseek(recording.getPosition()); + + }; + + /** + * Advances playback to the next frame in the frames array and schedules + * playback of the frame following that frame based on their associated + * timestamps. If no frames exist after the next frame, playback is paused. + * + * @private + */ + var continuePlayback = function continuePlayback() { + + // Advance to next frame + seekToFrame(currentFrame + 1); + + // If frames remain after advancing, schedule next frame + if (currentFrame + 1 < frames.length) { + + // Pull the upcoming frame + var next = frames[currentFrame + 1]; + + // Calculate the real timestamp corresponding to when the next + // frame begins + var nextRealTimestamp = next.timestamp - startVideoTimestamp + startRealTimestamp; + + // Calculate the relative delay between the current time and + // the next frame start + var delay = Math.max(nextRealTimestamp - new Date().getTime(), 0); + + // Advance to next frame after enough time has elapsed + playbackTimeout = window.setTimeout(function frameDelayElapsed() { + continuePlayback(); + }, delay); + + } + + // Otherwise stop playback + else + recording.pause(); + + }; + + /** + * Fired when new frames have become available while the recording is + * being downloaded. + * + * @event + * @param {Number} duration + * The new duration of the recording, in milliseconds. + */ + this.onprogress = null; + + /** + * Fired whenever playback of the recording has started. + * + * @event + */ + this.onplay = null; + + /** + * Fired whenever playback of the recording has been paused. This may + * happen when playback is explicitly paused with a call to pause(), or + * when playback is implicitly paused due to reaching the end of the + * recording. + * + * @event + */ + this.onpause = null; + + /** + * Fired whenever the playback position within the recording changes. + * + * @event + * @param {Number} position + * The new position within the recording, in milliseconds. + */ + this.onseek = null; + + /** + * Connects the underlying tunnel, beginning download of the Guacamole + * session. Playback of the Guacamole session cannot occur until at least + * one frame worth of instructions has been downloaded. + * + * @param {String} data + * The data to send to the tunnel when connecting. + */ + this.connect = function connect(data) { + tunnel.connect(data); + }; + + /** + * Disconnects the underlying tunnel, stopping further download of the + * Guacamole session. + */ + this.disconnect = function disconnect() { + tunnel.disconnect(); + }; + + /** + * Returns the underlying display of the Guacamole.Client used by this + * Guacamole.SessionRecording for playback. The display contains an Element + * which can be added to the DOM, causing the display (and thus playback of + * the recording) to become visible. + * + * @return {Guacamole.Display} + * The underlying display of the Guacamole.Client used by this + * Guacamole.SessionRecording for playback. + */ + this.getDisplay = function getDisplay() { + return playbackClient.getDisplay(); + }; + + /** + * Returns whether playback is currently in progress. + * + * @returns {Boolean} + * true if playback is currently in progress, false otherwise. + */ + this.isPlaying = function isPlaying() { + return !!startVideoTimestamp; + }; + + /** + * Returns the current playback position within the recording, in + * milliseconds, where zero is the start of the recording. + * + * @returns {Number} + * The current playback position within the recording, in milliseconds. + */ + this.getPosition = function getPosition() { + + // Position is simply zero if playback has not started at all + if (currentFrame === -1) + return 0; + + // Return current position as a millisecond timestamp relative to the + // start of the recording + return toRelativeTimestamp(frames[currentFrame].timestamp); + + }; + + /** + * Returns the duration of this recording, in milliseconds. If the + * recording is still being downloaded, this value will gradually increase. + * + * @returns {Number} + * The duration of this recording, in milliseconds. + */ + this.getDuration = function getDuration() { + + // If no frames yet exist, duration is zero + if (frames.length === 0) + return 0; + + // Recording duration is simply the timestamp of the last frame + return toRelativeTimestamp(frames[frames.length - 1].timestamp); + + }; + + /** + * Begins continuous playback of the recording downloaded thus far. + * Playback of the recording will continue until pause() is invoked or + * until no further frames exist. Playback is initially paused when a + * Guacamole.SessionRecording is created, and must be explicitly started + * through a call to this function. If playback is already in progress, + * this function has no effect. + */ + this.play = function play() { + + // If playback is not already in progress and frames remain, + // begin playback + if (!recording.isPlaying() && currentFrame + 1 < frames.length) { + + // Notify that playback is starting + if (recording.onplay) + recording.onplay(); + + // Store timestamp of playback start for relative scheduling of + // future frames + var next = frames[currentFrame + 1]; + startVideoTimestamp = next.timestamp; + startRealTimestamp = new Date().getTime(); + + // Begin playback of video + continuePlayback(); + + } + + }; + + /** + * Seeks to the given position within the recording. If the recording is + * currently being played back, playback will continue after the seek is + * performed. If the recording is currently paused, playback will be + * paused after the seek is performed. + * + * @param {Number} position + * The position within the recording to seek to, in milliseconds. + */ + this.seek = function seek(position) { + + // Do not seek if no frames exist + if (frames.length === 0) + return; + + // Pause playback, preserving playback state + var originallyPlaying = recording.isPlaying(); + recording.pause(); + + // Perform seek + seekToFrame(findFrame(0, frames.length - 1, position)); + + // Restore playback state + if (originallyPlaying) + recording.play(); + + }; + + /** + * Pauses playback of the recording, if playback is currently in progress. + * If playback is not in progress, this function has no effect. Playback is + * initially paused when a Guacamole.SessionRecording is created, and must + * be explicitly started through a call to play(). + */ + this.pause = function pause() { + + // Stop playback only if playback is in progress + if (recording.isPlaying()) { + + // Notify that playback is stopping + if (recording.onpause) + recording.onpause(); + + // Stop playback + window.clearTimeout(playbackTimeout); + startVideoTimestamp = null; + startRealTimestamp = null; + + } + + }; + +}; + +/** + * A single frame of Guacamole session data. Each frame is made up of the set + * of instructions used to generate that frame, and the timestamp as dictated + * by the "sync" instruction terminating the frame. Optionally, a frame may + * also be associated with a snapshot of Guacamole client state, such that the + * frame can be rendered without replaying all previous frames. + * + * @private + * @constructor + * @param {Number} timestamp + * The timestamp of this frame, as dictated by the "sync" instruction which + * terminates the frame. + * + * @param {Guacamole.SessionRecording._Frame.Instruction[]} instructions + * All instructions which are necessary to generate this frame relative to + * the previous frame in the Guacamole session. + */ +Guacamole.SessionRecording._Frame = function _Frame(timestamp, instructions) { + + /** + * Whether this frame should be used as a keyframe if possible. This value + * is purely advisory. The stored clientState must eventually be manually + * set for the frame to be used as a keyframe. By default, frames are not + * keyframes. + * + * @type {Boolean} + * @default false + */ + this.keyframe = false; + + /** + * The timestamp of this frame, as dictated by the "sync" instruction which + * terminates the frame. + * + * @type {Number} + */ + this.timestamp = timestamp; + + /** + * All instructions which are necessary to generate this frame relative to + * the previous frame in the Guacamole session. + * + * @type {Guacamole.SessionRecording._Frame.Instruction[]} + */ + this.instructions = instructions; + + /** + * A snapshot of client state after this frame was rendered, as returned by + * a call to exportState(). If no such snapshot has been taken, this will + * be null. + * + * @type {Object} + * @default null + */ + this.clientState = null; + +}; + +/** + * A Guacamole protocol instruction. Each Guacamole protocol instruction is + * made up of an opcode and set of arguments. + * + * @private + * @constructor + * @param {String} opcode + * The opcode of this Guacamole instruction. + * + * @param {String[]} args + * All arguments associated with this Guacamole instruction. + */ +Guacamole.SessionRecording._Frame.Instruction = function Instruction(opcode, args) { + + /** + * Reference to this Guacamole.SessionRecording._Frame.Instruction. + * + * @private + * @type {Guacamole.SessionRecording._Frame.Instruction} + */ + var instruction = this; + + /** + * The opcode of this Guacamole instruction. + * + * @type {String} + */ + this.opcode = opcode; + + /** + * All arguments associated with this Guacamole instruction. + * + * @type {String[]} + */ + this.args = args; + + /** + * Returns the approximate number of characters which make up this + * instruction. This value is only approximate as it excludes the length + * prefixes and various delimiters used by the Guacamole protocol; only + * the content of the opcode and each argument is taken into account. + * + * @returns {Number} + * The approximate size of this instruction, in characters. + */ + this.getSize = function getSize() { + + // Init with length of opcode + var size = instruction.opcode.length; + + // Add length of all arguments + for (var i = 0; i < instruction.args.length; i++) + size += instruction.args[i].length; + + return size; + + }; + +}; + +/** + * A read-only Guacamole.Tunnel implementation which streams instructions + * received through explicit calls to its receiveInstruction() function. + * + * @private + * @constructor + * @augments {Guacamole.Tunnel} + */ +Guacamole.SessionRecording._PlaybackTunnel = function _PlaybackTunnel() { + + /** + * Reference to this Guacamole.SessionRecording._PlaybackTunnel. + * + * @private + * @type {Guacamole.SessionRecording._PlaybackTunnel} + */ + var tunnel = this; + + this.connect = function connect(data) { + // Do nothing + }; + + this.sendMessage = function sendMessage(elements) { + // Do nothing + }; + + this.disconnect = function disconnect() { + // Do nothing + }; + + /** + * Invokes this tunnel's oninstruction handler, notifying users of this + * tunnel (such as a Guacamole.Client instance) that an instruction has + * been received. If the oninstruction handler has not been set, this + * function has no effect. + * + * @param {String} opcode + * The opcode of the Guacamole instruction. + * + * @param {String[]} args + * All arguments associated with this Guacamole instruction. + */ + this.receiveInstruction = function receiveInstruction(opcode, args) { + if (tunnel.oninstruction) + tunnel.oninstruction(opcode, args); + }; + +}; +</code></pre> + </article> + </section> + + + + +</div> + +<nav> + <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Client</a></li><li><a href="Guacamole.DataURIReader.html">DataURIReader</a></li><li><a href="Guacamole.Display.html">Display</a></li><li><a href="Guacamole.Display.VisibleLayer.html">VisibleLayer</a></li><li><a href="Guacamole.HTTPTunnel.html">HTTPTunnel</a></li><li><a href="Guacamole.InputStream.html">InputStream</a></li><li><a href="Guacamole.IntegerPool.html">IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">JSONReader</a></li> <li><a href="Guacamole.Keyboard.html">Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">ModifierState</a></li><li><a href="Guacamole.Layer.html">Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Pixel</a></li><li><a href="Guacamole.Mouse.html">Mouse</a></li><li><a href="Guacamole.Mouse.State.html">State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Touchscreen</a></li><li><a href="Guacamole.Object.html">Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Layout</a></li><li><a href="Guacamole.OutputStream.html">OutputStream</a></li><li><a href="Guacamole.Parser.html">Parser</a></li><li><a href="Guacamole.RawAudioFormat.html">RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioR ecorder.html">RawAudioRecorder</a></li><li><a href="Guacamole.SessionRecording.html">SessionRecording</a></li><li><a href="Guacamole.StaticHTTPTunnel.html">StaticHTTPTunnel</a></li><li><a href="Guacamole.Status.html">Status</a></li><li><a href="Guacamole.StringReader.html">StringReader</a></li><li><a href="Guacamole.StringWriter.html">StringWriter</a></li><li><a href="Guacamole.Tunnel.html">Tunnel</a></li><li><a href="Guacamole.VideoPlayer.html">VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">onend</a></li>< li><a href="Guacamole.BlobReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">onack</a></li><li><a href="Guacamole.BlobWriter.html#event:oncomplete">oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onaudio">onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onna me">onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">onpipe</a></li><li><a href="Guacamole.Client.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">onresize</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.InputStream.html#event:onblob">onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">onprog ress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.html#event:onmouseout">onmouseout</a></li><li><a href="Guacamole.Mouse.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">onbody</a></li>< li><a href="Guacamole.Object.html#event:onundefine">onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.SessionRecording.html#event:onpause">onpause</a></li><li><a href="Guacamole.SessionRecording.html#event:onplay">onplay</a></li><li><a href="Guacamole .SessionRecording.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.SessionRecording.html#event:onseek">onseek</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.StringReader.html#event:onend">onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">onack</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamol e.WebSocketTunnel.html#event:onstatechange">onstatechange</a></li></ul><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">AudioContextFactory</a></li></ul> +</nav> + +<br class="clear"> + +<footer> + Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Sun Jul 02 2017 12:09:53 GMT-0700 (PDT) +</footer> + +<script> prettyPrint(); </script> +<script src="scripts/linenumber.js"> </script> + <!-- Google Analytics --> + <script type="text/javascript"> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-75289145-1', 'auto'); + ga('send', 'pageview'); + </script> +</body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-guacamole-website/blob/eff0fb8d/content/doc/0.9.13-incubating/guacamole-common-js/Status.js.html ---------------------------------------------------------------------- diff --git a/content/doc/0.9.13-incubating/guacamole-common-js/Status.js.html b/content/doc/0.9.13-incubating/guacamole-common-js/Status.js.html new file mode 100644 index 0000000..1f66d0f --- /dev/null +++ b/content/doc/0.9.13-incubating/guacamole-common-js/Status.js.html @@ -0,0 +1,295 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>JSDoc: Source: Status.js</title> + + <script src="scripts/prettify/prettify.js"> </script> + <script src="scripts/prettify/lang-css.js"> </script> + <!--[if lt IE 9]> + <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> + <![endif]--> + <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> + <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> +</head> + +<body> + +<div id="main"> + + <h1 class="page-title">Source: Status.js</h1> + + + + + + + <section> + <article> + <pre class="prettyprint source linenums"><code>/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var Guacamole = Guacamole || {}; + +/** + * A Guacamole status. Each Guacamole status consists of a status code, defined + * by the protocol, and an optional human-readable message, usually only + * included for debugging convenience. + * + * @constructor + * @param {Number} code + * The Guacamole status code, as defined by Guacamole.Status.Code. + * + * @param {String} [message] + * An optional human-readable message. + */ +Guacamole.Status = function(code, message) { + + /** + * Reference to this Guacamole.Status. + * @private + */ + var guac_status = this; + + /** + * The Guacamole status code. + * @see Guacamole.Status.Code + * @type {Number} + */ + this.code = code; + + /** + * An arbitrary human-readable message associated with this status, if any. + * The human-readable message is not required, and is generally provided + * for debugging purposes only. For user feedback, it is better to translate + * the Guacamole status code into a message. + * + * @type {String} + */ + this.message = message; + + /** + * Returns whether this status represents an error. + * @returns {Boolean} true if this status represents an error, false + * otherwise. + */ + this.isError = function() { + return guac_status.code < 0 || guac_status.code > 0x00FF; + }; + +}; + +/** + * Enumeration of all Guacamole status codes. + */ +Guacamole.Status.Code = { + + /** + * The operation succeeded. + * + * @type {Number} + */ + "SUCCESS": 0x0000, + + /** + * The requested operation is unsupported. + * + * @type {Number} + */ + "UNSUPPORTED": 0x0100, + + /** + * The operation could not be performed due to an internal failure. + * + * @type {Number} + */ + "SERVER_ERROR": 0x0200, + + /** + * The operation could not be performed as the server is busy. + * + * @type {Number} + */ + "SERVER_BUSY": 0x0201, + + /** + * The operation could not be performed because the upstream server is not + * responding. + * + * @type {Number} + */ + "UPSTREAM_TIMEOUT": 0x0202, + + /** + * The operation was unsuccessful due to an error or otherwise unexpected + * condition of the upstream server. + * + * @type {Number} + */ + "UPSTREAM_ERROR": 0x0203, + + /** + * The operation could not be performed as the requested resource does not + * exist. + * + * @type {Number} + */ + "RESOURCE_NOT_FOUND": 0x0204, + + /** + * The operation could not be performed as the requested resource is + * already in use. + * + * @type {Number} + */ + "RESOURCE_CONFLICT": 0x0205, + + /** + * The operation could not be performed as the requested resource is now + * closed. + * + * @type {Number} + */ + "RESOURCE_CLOSED": 0x0206, + + /** + * The operation could not be performed because the upstream server does + * not appear to exist. + * + * @type {Number} + */ + "UPSTREAM_NOT_FOUND": 0x0207, + + /** + * The operation could not be performed because the upstream server is not + * available to service the request. + * + * @type {Number} + */ + "UPSTREAM_UNAVAILABLE": 0x0208, + + /** + * The session within the upstream server has ended because it conflicted + * with another session. + * + * @type {Number} + */ + "SESSION_CONFLICT": 0x0209, + + /** + * The session within the upstream server has ended because it appeared to + * be inactive. + * + * @type {Number} + */ + "SESSION_TIMEOUT": 0x020A, + + /** + * The session within the upstream server has been forcibly terminated. + * + * @type {Number} + */ + "SESSION_CLOSED": 0x020B, + + /** + * The operation could not be performed because bad parameters were given. + * + * @type {Number} + */ + "CLIENT_BAD_REQUEST": 0x0300, + + /** + * Permission was denied to perform the operation, as the user is not yet + * authorized (not yet logged in, for example). + * + * @type {Number} + */ + "CLIENT_UNAUTHORIZED": 0x0301, + + /** + * Permission was denied to perform the operation, and this permission will + * not be granted even if the user is authorized. + * + * @type {Number} + */ + "CLIENT_FORBIDDEN": 0x0303, + + /** + * The client took too long to respond. + * + * @type {Number} + */ + "CLIENT_TIMEOUT": 0x0308, + + /** + * The client sent too much data. + * + * @type {Number} + */ + "CLIENT_OVERRUN": 0x030D, + + /** + * The client sent data of an unsupported or unexpected type. + * + * @type {Number} + */ + "CLIENT_BAD_TYPE": 0x030F, + + /** + * The operation failed because the current client is already using too + * many resources. + * + * @type {Number} + */ + "CLIENT_TOO_MANY": 0x031D + +}; +</code></pre> + </article> + </section> + + + + +</div> + +<nav> + <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Guacamole.ArrayBufferReader.html">ArrayBufferReader</a></li><li><a href="Guacamole.ArrayBufferWriter.html">ArrayBufferWriter</a></li><li><a href="Guacamole.AudioPlayer.html">AudioPlayer</a></li><li><a href="Guacamole.AudioRecorder.html">AudioRecorder</a></li><li><a href="Guacamole.BlobReader.html">BlobReader</a></li><li><a href="Guacamole.BlobWriter.html">BlobWriter</a></li><li><a href="Guacamole.ChainedTunnel.html">ChainedTunnel</a></li><li><a href="Guacamole.Client.html">Client</a></li><li><a href="Guacamole.DataURIReader.html">DataURIReader</a></li><li><a href="Guacamole.Display.html">Display</a></li><li><a href="Guacamole.Display.VisibleLayer.html">VisibleLayer</a></li><li><a href="Guacamole.HTTPTunnel.html">HTTPTunnel</a></li><li><a href="Guacamole.InputStream.html">InputStream</a></li><li><a href="Guacamole.IntegerPool.html">IntegerPool</a></li><li><a href="Guacamole.JSONReader.html">JSONReader</a></li> <li><a href="Guacamole.Keyboard.html">Keyboard</a></li><li><a href="Guacamole.Keyboard.ModifierState.html">ModifierState</a></li><li><a href="Guacamole.Layer.html">Layer</a></li><li><a href="Guacamole.Layer.Pixel.html">Pixel</a></li><li><a href="Guacamole.Mouse.html">Mouse</a></li><li><a href="Guacamole.Mouse.State.html">State</a></li><li><a href="Guacamole.Mouse.Touchpad.html">Touchpad</a></li><li><a href="Guacamole.Mouse.Touchscreen.html">Touchscreen</a></li><li><a href="Guacamole.Object.html">Object</a></li><li><a href="Guacamole.OnScreenKeyboard.html">OnScreenKeyboard</a></li><li><a href="Guacamole.OnScreenKeyboard.Key.html">Key</a></li><li><a href="Guacamole.OnScreenKeyboard.Layout.html">Layout</a></li><li><a href="Guacamole.OutputStream.html">OutputStream</a></li><li><a href="Guacamole.Parser.html">Parser</a></li><li><a href="Guacamole.RawAudioFormat.html">RawAudioFormat</a></li><li><a href="Guacamole.RawAudioPlayer.html">RawAudioPlayer</a></li><li><a href="Guacamole.RawAudioR ecorder.html">RawAudioRecorder</a></li><li><a href="Guacamole.SessionRecording.html">SessionRecording</a></li><li><a href="Guacamole.StaticHTTPTunnel.html">StaticHTTPTunnel</a></li><li><a href="Guacamole.Status.html">Status</a></li><li><a href="Guacamole.StringReader.html">StringReader</a></li><li><a href="Guacamole.StringWriter.html">StringWriter</a></li><li><a href="Guacamole.Tunnel.html">Tunnel</a></li><li><a href="Guacamole.VideoPlayer.html">VideoPlayer</a></li><li><a href="Guacamole.WebSocketTunnel.html">WebSocketTunnel</a></li></ul><h3>Events</h3><ul><li><a href="Guacamole.ArrayBufferReader.html#event:ondata">ondata</a></li><li><a href="Guacamole.ArrayBufferReader.html#event:onend">onend</a></li><li><a href="Guacamole.ArrayBufferWriter.html#event:onack">onack</a></li><li><a href="Guacamole.AudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.AudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobReader.html#event:onend">onend</a></li>< li><a href="Guacamole.BlobReader.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.BlobWriter.html#event:onack">onack</a></li><li><a href="Guacamole.BlobWriter.html#event:oncomplete">oncomplete</a></li><li><a href="Guacamole.BlobWriter.html#event:onerror">onerror</a></li><li><a href="Guacamole.BlobWriter.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.ChainedTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.ChainedTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onaudio">onaudio</a></li><li><a href="Guacamole.Client.html#event:onclipboard">onclipboard</a></li><li><a href="Guacamole.Client.html#event:onerror">onerror</a></li><li><a href="Guacamole.Client.html#event:onfile">onfile</a></li><li><a href="Guacamole.Client.html#event:onfilesystem">onfilesystem</a></li><li><a href="Guacamole.Client.html#event:onna me">onname</a></li><li><a href="Guacamole.Client.html#event:onpipe">onpipe</a></li><li><a href="Guacamole.Client.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.Client.html#event:onsync">onsync</a></li><li><a href="Guacamole.Client.html#event:onvideo">onvideo</a></li><li><a href="Guacamole.DataURIReader.html#event:onend">onend</a></li><li><a href="Guacamole.Display.html#event:oncursor">oncursor</a></li><li><a href="Guacamole.Display.html#event:onresize">onresize</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.HTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.HTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.InputStream.html#event:onblob">onblob</a></li><li><a href="Guacamole.InputStream.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onend">onend</a></li><li><a href="Guacamole.JSONReader.html#event:onprogress">onprog ress</a></li><li><a href="Guacamole.Keyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.Keyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchpad.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.Touchscreen.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Mouse.html#event:onmousedown">onmousedown</a></li><li><a href="Guacamole.Mouse.html#event:onmousemove">onmousemove</a></li><li><a href="Guacamole.Mouse.html#event:onmouseout">onmouseout</a></li><li><a href="Guacamole.Mouse.html#event:onmouseup">onmouseup</a></li><li><a href="Guacamole.Object.html#event:onbody">onbody</a></li>< li><a href="Guacamole.Object.html#event:onundefine">onundefine</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeydown">onkeydown</a></li><li><a href="Guacamole.OnScreenKeyboard.html#event:onkeyup">onkeyup</a></li><li><a href="Guacamole.OutputStream.html#event:onack">onack</a></li><li><a href="Guacamole.Parser.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onclose">onclose</a></li><li><a href="Guacamole.RawAudioRecorder.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.SessionRecording._PlaybackTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.SessionRecording.html#event:onpause">onpause</a></li><li><a href="Guacamole.SessionRecording.html#event:onplay">onplay</a></li><li><a href="Guacamole .SessionRecording.html#event:onprogress">onprogress</a></li><li><a href="Guacamole.SessionRecording.html#event:onseek">onseek</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.StaticHTTPTunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.StringReader.html#event:onend">onend</a></li><li><a href="Guacamole.StringReader.html#event:ontext">ontext</a></li><li><a href="Guacamole.StringWriter.html#event:onack">onack</a></li><li><a href="Guacamole.Tunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.Tunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamole.Tunnel.html#event:onstatechange">onstatechange</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:onerror">onerror</a></li><li><a href="Guacamole.WebSocketTunnel.html#event:oninstruction">oninstruction</a></li><li><a href="Guacamol e.WebSocketTunnel.html#event:onstatechange">onstatechange</a></li></ul><h3>Namespaces</h3><ul><li><a href="Guacamole.html">Guacamole</a></li><li><a href="Guacamole.AudioContextFactory.html">AudioContextFactory</a></li></ul> +</nav> + +<br class="clear"> + +<footer> + Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Sun Jul 02 2017 12:09:53 GMT-0700 (PDT) +</footer> + +<script> prettyPrint(); </script> +<script src="scripts/linenumber.js"> </script> + <!-- Google Analytics --> + <script type="text/javascript"> + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); + + ga('create', 'UA-75289145-1', 'auto'); + ga('send', 'pageview'); + </script> +</body> +</html>