mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 13:17:41 +00:00
Massive reorganization. Separate all objects into individual files. Remove duplicate namespace declarations.
This commit is contained in:
@@ -20,12 +20,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for all Guacamole JavaScript objects.
|
||||
* @ignore
|
||||
* @namespace
|
||||
*/
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
@@ -20,371 +20,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for all Guacamole JavaScript objects.
|
||||
* @namespace
|
||||
*/
|
||||
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 (length == NaN)
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* An input stream abstraction used by the Guacamole client to facilitate
|
||||
* transfer of files or other binary data.
|
||||
*
|
||||
* @constructor
|
||||
* @param {String} mimetype The mimetype of the data this stream will receive.
|
||||
*/
|
||||
Guacamole.InputStream = function(mimetype) {
|
||||
|
||||
/**
|
||||
* Reference to this Guacamole.InputStream.
|
||||
* @private
|
||||
*/
|
||||
var guac_stream = this;
|
||||
|
||||
/**
|
||||
* The length of this Guacamole.InputStream in bytes.
|
||||
* @private
|
||||
*/
|
||||
var length = 0;
|
||||
|
||||
/**
|
||||
* The mimetype of the data contained within this blob.
|
||||
*/
|
||||
this.mimetype = mimetype;
|
||||
|
||||
// Get blob builder
|
||||
var blob_builder;
|
||||
if (window.BlobBuilder) blob_builder = new BlobBuilder();
|
||||
else if (window.WebKitBlobBuilder) blob_builder = new WebKitBlobBuilder();
|
||||
else if (window.MozBlobBuilder) blob_builder = new MozBlobBuilder();
|
||||
else
|
||||
blob_builder = new (function() {
|
||||
|
||||
var blobs = [];
|
||||
|
||||
/** @ignore */
|
||||
this.append = function(data) {
|
||||
blobs.push(new Blob([data], {"type": mimetype}));
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
this.getBlob = function() {
|
||||
return new Blob(blobs, {"type": mimetype});
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
/**
|
||||
* Receives the given ArrayBuffer, storing its data within this
|
||||
* Guacamole.InputStream.
|
||||
*
|
||||
* @param {ArrayBuffer} buffer An ArrayBuffer containing the data to be
|
||||
* received.
|
||||
*/
|
||||
this.receive = function(buffer) {
|
||||
|
||||
blob_builder.append(buffer);
|
||||
length += buffer.byteLength;
|
||||
|
||||
// Call handler, if present
|
||||
if (guac_stream.onreceive)
|
||||
guac_stream.onreceive(buffer.byteLength);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes this Guacamole.InputStream such that no further data will be
|
||||
* written.
|
||||
*/
|
||||
this.close = function() {
|
||||
|
||||
// Call handler, if present
|
||||
if (guac_stream.onclose)
|
||||
guac_stream.onclose();
|
||||
|
||||
// NOTE: Currently not enforced.
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current length of this Guacamole.InputStream, in bytes.
|
||||
* @return {Number} The current length of this Guacamole.InputStream.
|
||||
*/
|
||||
this.getLength = function() {
|
||||
return length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the contents of this Guacamole.InputStream as a Blob.
|
||||
* @return {Blob} The contents of this Guacamole.InputStream.
|
||||
*/
|
||||
this.getBlob = function() {
|
||||
return blob_builder.getBlob();
|
||||
};
|
||||
|
||||
/**
|
||||
* Fired once for every blob of data received.
|
||||
*
|
||||
* @event
|
||||
* @param {Number} length The number of bytes received.
|
||||
*/
|
||||
this.onreceive = null;
|
||||
|
||||
/**
|
||||
* Fired once this stream is finished and no further data will be written.
|
||||
* @event
|
||||
*/
|
||||
this.onclose = null;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Integer pool which returns consistently increasing integers while integers
|
||||
* are in use, and previously-used integers when possible.
|
||||
* @constructor
|
||||
*/
|
||||
Guacamole.IntegerPool = function() {
|
||||
|
||||
/**
|
||||
* Reference to this integer pool.
|
||||
*/
|
||||
var guac_pool = this;
|
||||
|
||||
/**
|
||||
* Array of available integers.
|
||||
* @type Number[]
|
||||
*/
|
||||
var pool = [];
|
||||
|
||||
/**
|
||||
* The next integer to return if no more integers remain.
|
||||
* @type Number
|
||||
*/
|
||||
this.next_int = 0;
|
||||
|
||||
/**
|
||||
* Returns the next available integer in the pool. If possible, a previously
|
||||
* used integer will be returned.
|
||||
*
|
||||
* @return {Number} The next available integer.
|
||||
*/
|
||||
this.next = function() {
|
||||
|
||||
// If free'd integers exist, return one of those
|
||||
if (pool.length > 0)
|
||||
return pool.shift();
|
||||
|
||||
// Otherwise, return a new integer
|
||||
return guac_pool.next_int++;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Frees the given integer, allowing it to be reused.
|
||||
*
|
||||
* @param {Number} integer The integer to free.
|
||||
*/
|
||||
this.free = function(integer) {
|
||||
pool.push(integer);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract stream which can receive data.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Guacamole.Client} client The client owning this stream.
|
||||
* @param {Number} index The index of this stream.
|
||||
*/
|
||||
Guacamole.OutputStream = function(client, index) {
|
||||
|
||||
/**
|
||||
* Reference to this stream.
|
||||
* @private
|
||||
*/
|
||||
var guac_stream = this;
|
||||
|
||||
/**
|
||||
* The index of this stream.
|
||||
* @type Number
|
||||
*/
|
||||
this.index = index;
|
||||
|
||||
/**
|
||||
* Fired when the stream is being closed due to an error.
|
||||
*
|
||||
* @param {String} reason A human-readable reason describing the error.
|
||||
* @param {Number} code The error code associated with the error.
|
||||
*/
|
||||
this.onerror = null;
|
||||
|
||||
/**
|
||||
* Fired whenever an acknowledgement is received from the server, indicating
|
||||
* that a stream operation has completed.
|
||||
*
|
||||
* @event
|
||||
* @param {String} message A human-readable status message related to the
|
||||
* operation performed.
|
||||
* @param {Number} code The error code associated with the operation.
|
||||
*/
|
||||
this.onack = null;
|
||||
|
||||
/**
|
||||
* Writes the given base64-encoded data to this stream as a blob.
|
||||
*
|
||||
* @param {String} data The base64-encoded data to send.
|
||||
*/
|
||||
this.write = function(data) {
|
||||
client.sendBlob(guac_stream.index, data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes this stream.
|
||||
*/
|
||||
this.close = function() {
|
||||
client.endStream(guac_stream.index);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Guacamole protocol client. Given a display element and {@link Guacamole.Tunnel},
|
||||
* automatically handles incoming and outgoing Guacamole instructions via the
|
135
guacamole-common-js/src/main/resources/modules/InputStream.js
Normal file
135
guacamole-common-js/src/main/resources/modules/InputStream.js
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
||||
* An input stream abstraction used by the Guacamole client to facilitate
|
||||
* transfer of files or other binary data.
|
||||
*
|
||||
* @constructor
|
||||
* @param {String} mimetype The mimetype of the data this stream will receive.
|
||||
*/
|
||||
Guacamole.InputStream = function(mimetype) {
|
||||
|
||||
/**
|
||||
* Reference to this Guacamole.InputStream.
|
||||
* @private
|
||||
*/
|
||||
var guac_stream = this;
|
||||
|
||||
/**
|
||||
* The length of this Guacamole.InputStream in bytes.
|
||||
* @private
|
||||
*/
|
||||
var length = 0;
|
||||
|
||||
/**
|
||||
* The mimetype of the data contained within this blob.
|
||||
*/
|
||||
this.mimetype = mimetype;
|
||||
|
||||
// Get blob builder
|
||||
var blob_builder;
|
||||
if (window.BlobBuilder) blob_builder = new BlobBuilder();
|
||||
else if (window.WebKitBlobBuilder) blob_builder = new WebKitBlobBuilder();
|
||||
else if (window.MozBlobBuilder) blob_builder = new MozBlobBuilder();
|
||||
else
|
||||
blob_builder = new (function() {
|
||||
|
||||
var blobs = [];
|
||||
|
||||
/** @ignore */
|
||||
this.append = function(data) {
|
||||
blobs.push(new Blob([data], {"type": mimetype}));
|
||||
};
|
||||
|
||||
/** @ignore */
|
||||
this.getBlob = function() {
|
||||
return new Blob(blobs, {"type": mimetype});
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
/**
|
||||
* Receives the given ArrayBuffer, storing its data within this
|
||||
* Guacamole.InputStream.
|
||||
*
|
||||
* @param {ArrayBuffer} buffer An ArrayBuffer containing the data to be
|
||||
* received.
|
||||
*/
|
||||
this.receive = function(buffer) {
|
||||
|
||||
blob_builder.append(buffer);
|
||||
length += buffer.byteLength;
|
||||
|
||||
// Call handler, if present
|
||||
if (guac_stream.onreceive)
|
||||
guac_stream.onreceive(buffer.byteLength);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes this Guacamole.InputStream such that no further data will be
|
||||
* written.
|
||||
*/
|
||||
this.close = function() {
|
||||
|
||||
// Call handler, if present
|
||||
if (guac_stream.onclose)
|
||||
guac_stream.onclose();
|
||||
|
||||
// NOTE: Currently not enforced.
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the current length of this Guacamole.InputStream, in bytes.
|
||||
* @return {Number} The current length of this Guacamole.InputStream.
|
||||
*/
|
||||
this.getLength = function() {
|
||||
return length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the contents of this Guacamole.InputStream as a Blob.
|
||||
* @return {Blob} The contents of this Guacamole.InputStream.
|
||||
*/
|
||||
this.getBlob = function() {
|
||||
return blob_builder.getBlob();
|
||||
};
|
||||
|
||||
/**
|
||||
* Fired once for every blob of data received.
|
||||
*
|
||||
* @event
|
||||
* @param {Number} length The number of bytes received.
|
||||
*/
|
||||
this.onreceive = null;
|
||||
|
||||
/**
|
||||
* Fired once this stream is finished and no further data will be written.
|
||||
* @event
|
||||
*/
|
||||
this.onclose = null;
|
||||
|
||||
};
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
||||
* Integer pool which returns consistently increasing integers while integers
|
||||
* are in use, and previously-used integers when possible.
|
||||
* @constructor
|
||||
*/
|
||||
Guacamole.IntegerPool = function() {
|
||||
|
||||
/**
|
||||
* Reference to this integer pool.
|
||||
*/
|
||||
var guac_pool = this;
|
||||
|
||||
/**
|
||||
* Array of available integers.
|
||||
* @type Number[]
|
||||
*/
|
||||
var pool = [];
|
||||
|
||||
/**
|
||||
* The next integer to return if no more integers remain.
|
||||
* @type Number
|
||||
*/
|
||||
this.next_int = 0;
|
||||
|
||||
/**
|
||||
* Returns the next available integer in the pool. If possible, a previously
|
||||
* used integer will be returned.
|
||||
*
|
||||
* @return {Number} The next available integer.
|
||||
*/
|
||||
this.next = function() {
|
||||
|
||||
// If free'd integers exist, return one of those
|
||||
if (pool.length > 0)
|
||||
return pool.shift();
|
||||
|
||||
// Otherwise, return a new integer
|
||||
return guac_pool.next_int++;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Frees the given integer, allowing it to be reused.
|
||||
*
|
||||
* @param {Number} integer The integer to free.
|
||||
*/
|
||||
this.free = function(integer) {
|
||||
pool.push(integer);
|
||||
};
|
||||
|
||||
};
|
@@ -20,12 +20,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for all Guacamole JavaScript objects.
|
||||
* @ignore
|
||||
* @namespace
|
||||
*/
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
@@ -20,12 +20,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for all Guacamole JavaScript objects.
|
||||
* @ignore
|
||||
* @namespace
|
||||
*/
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
@@ -20,12 +20,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for all Guacamole JavaScript objects.
|
||||
* @ignore
|
||||
* @namespace
|
||||
*/
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
||||
@@ -311,6 +305,113 @@ Guacamole.Mouse = function(element) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple container for properties describing the state of a mouse.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Number} x The X position of the mouse pointer in pixels.
|
||||
* @param {Number} y The Y position of the mouse pointer in pixels.
|
||||
* @param {Boolean} left Whether the left mouse button is pressed.
|
||||
* @param {Boolean} middle Whether the middle mouse button is pressed.
|
||||
* @param {Boolean} right Whether the right mouse button is pressed.
|
||||
* @param {Boolean} up Whether the up mouse button is pressed (the fourth
|
||||
* button, usually part of a scroll wheel).
|
||||
* @param {Boolean} down Whether the down mouse button is pressed (the fifth
|
||||
* button, usually part of a scroll wheel).
|
||||
*/
|
||||
Guacamole.Mouse.State = function(x, y, left, middle, right, up, down) {
|
||||
|
||||
/**
|
||||
* Reference to this Guacamole.Mouse.State.
|
||||
* @private
|
||||
*/
|
||||
var guac_state = this;
|
||||
|
||||
/**
|
||||
* The current X position of the mouse pointer.
|
||||
* @type Number
|
||||
*/
|
||||
this.x = x;
|
||||
|
||||
/**
|
||||
* The current Y position of the mouse pointer.
|
||||
* @type Number
|
||||
*/
|
||||
this.y = y;
|
||||
|
||||
/**
|
||||
* Whether the left mouse button is currently pressed.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.left = left;
|
||||
|
||||
/**
|
||||
* Whether the middle mouse button is currently pressed.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.middle = middle
|
||||
|
||||
/**
|
||||
* Whether the right mouse button is currently pressed.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.right = right;
|
||||
|
||||
/**
|
||||
* Whether the up mouse button is currently pressed. This is the fourth
|
||||
* mouse button, associated with upward scrolling of the mouse scroll
|
||||
* wheel.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.up = up;
|
||||
|
||||
/**
|
||||
* Whether the down mouse button is currently pressed. This is the fifth
|
||||
* mouse button, associated with downward scrolling of the mouse scroll
|
||||
* wheel.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.down = down;
|
||||
|
||||
/**
|
||||
* Updates the position represented within this state object by the given
|
||||
* element and clientX/clientY coordinates (commonly available within event
|
||||
* objects). Position is translated from clientX/clientY (relative to
|
||||
* viewport) to element-relative coordinates.
|
||||
*
|
||||
* @param {Element} element The element the coordinates should be relative
|
||||
* to.
|
||||
* @param {Number} clientX The X coordinate to translate, viewport-relative.
|
||||
* @param {Number} clientY The Y coordinate to translate, viewport-relative.
|
||||
*/
|
||||
this.fromClientPosition = function(element, clientX, clientY) {
|
||||
|
||||
guac_state.x = clientX - element.offsetLeft;
|
||||
guac_state.y = clientY - element.offsetTop;
|
||||
|
||||
// This is all JUST so we can get the mouse position within the element
|
||||
var parent = element.offsetParent;
|
||||
while (parent && !(parent === document.body)) {
|
||||
guac_state.x -= parent.offsetLeft - parent.scrollLeft;
|
||||
guac_state.y -= parent.offsetTop - parent.scrollTop;
|
||||
|
||||
parent = parent.offsetParent;
|
||||
}
|
||||
|
||||
// Element ultimately depends on positioning within document body,
|
||||
// take document scroll into account.
|
||||
if (parent) {
|
||||
var documentScrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
|
||||
var documentScrollTop = document.body.scrollTop || document.documentElement.scrollTop;
|
||||
|
||||
guac_state.x -= parent.offsetLeft - documentScrollLeft;
|
||||
guac_state.y -= parent.offsetTop - documentScrollTop;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides cross-browser relative touch event translation for a given element.
|
||||
*
|
||||
@@ -712,110 +813,3 @@ Guacamole.Mouse.Touchscreen = function(element) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple container for properties describing the state of a mouse.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Number} x The X position of the mouse pointer in pixels.
|
||||
* @param {Number} y The Y position of the mouse pointer in pixels.
|
||||
* @param {Boolean} left Whether the left mouse button is pressed.
|
||||
* @param {Boolean} middle Whether the middle mouse button is pressed.
|
||||
* @param {Boolean} right Whether the right mouse button is pressed.
|
||||
* @param {Boolean} up Whether the up mouse button is pressed (the fourth
|
||||
* button, usually part of a scroll wheel).
|
||||
* @param {Boolean} down Whether the down mouse button is pressed (the fifth
|
||||
* button, usually part of a scroll wheel).
|
||||
*/
|
||||
Guacamole.Mouse.State = function(x, y, left, middle, right, up, down) {
|
||||
|
||||
/**
|
||||
* Reference to this Guacamole.Mouse.State.
|
||||
* @private
|
||||
*/
|
||||
var guac_state = this;
|
||||
|
||||
/**
|
||||
* The current X position of the mouse pointer.
|
||||
* @type Number
|
||||
*/
|
||||
this.x = x;
|
||||
|
||||
/**
|
||||
* The current Y position of the mouse pointer.
|
||||
* @type Number
|
||||
*/
|
||||
this.y = y;
|
||||
|
||||
/**
|
||||
* Whether the left mouse button is currently pressed.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.left = left;
|
||||
|
||||
/**
|
||||
* Whether the middle mouse button is currently pressed.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.middle = middle
|
||||
|
||||
/**
|
||||
* Whether the right mouse button is currently pressed.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.right = right;
|
||||
|
||||
/**
|
||||
* Whether the up mouse button is currently pressed. This is the fourth
|
||||
* mouse button, associated with upward scrolling of the mouse scroll
|
||||
* wheel.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.up = up;
|
||||
|
||||
/**
|
||||
* Whether the down mouse button is currently pressed. This is the fifth
|
||||
* mouse button, associated with downward scrolling of the mouse scroll
|
||||
* wheel.
|
||||
* @type Boolean
|
||||
*/
|
||||
this.down = down;
|
||||
|
||||
/**
|
||||
* Updates the position represented within this state object by the given
|
||||
* element and clientX/clientY coordinates (commonly available within event
|
||||
* objects). Position is translated from clientX/clientY (relative to
|
||||
* viewport) to element-relative coordinates.
|
||||
*
|
||||
* @param {Element} element The element the coordinates should be relative
|
||||
* to.
|
||||
* @param {Number} clientX The X coordinate to translate, viewport-relative.
|
||||
* @param {Number} clientY The Y coordinate to translate, viewport-relative.
|
||||
*/
|
||||
this.fromClientPosition = function(element, clientX, clientY) {
|
||||
|
||||
guac_state.x = clientX - element.offsetLeft;
|
||||
guac_state.y = clientY - element.offsetTop;
|
||||
|
||||
// This is all JUST so we can get the mouse position within the element
|
||||
var parent = element.offsetParent;
|
||||
while (parent && !(parent === document.body)) {
|
||||
guac_state.x -= parent.offsetLeft - parent.scrollLeft;
|
||||
guac_state.y -= parent.offsetTop - parent.scrollTop;
|
||||
|
||||
parent = parent.offsetParent;
|
||||
}
|
||||
|
||||
// Element ultimately depends on positioning within document body,
|
||||
// take document scroll into account.
|
||||
if (parent) {
|
||||
var documentScrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
|
||||
var documentScrollTop = document.body.scrollTop || document.documentElement.scrollTop;
|
||||
|
||||
guac_state.x -= parent.offsetLeft - documentScrollLeft;
|
||||
guac_state.y -= parent.offsetTop - documentScrollTop;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
@@ -20,12 +20,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for all Guacamole JavaScript objects.
|
||||
* @ignore
|
||||
* @namespace
|
||||
*/
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
||||
* Abstract stream which can receive data.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Guacamole.Client} client The client owning this stream.
|
||||
* @param {Number} index The index of this stream.
|
||||
*/
|
||||
Guacamole.OutputStream = function(client, index) {
|
||||
|
||||
/**
|
||||
* Reference to this stream.
|
||||
* @private
|
||||
*/
|
||||
var guac_stream = this;
|
||||
|
||||
/**
|
||||
* The index of this stream.
|
||||
* @type Number
|
||||
*/
|
||||
this.index = index;
|
||||
|
||||
/**
|
||||
* Fired when the stream is being closed due to an error.
|
||||
*
|
||||
* @param {String} reason A human-readable reason describing the error.
|
||||
* @param {Number} code The error code associated with the error.
|
||||
*/
|
||||
this.onerror = null;
|
||||
|
||||
/**
|
||||
* Fired whenever an acknowledgement is received from the server, indicating
|
||||
* that a stream operation has completed.
|
||||
*
|
||||
* @event
|
||||
* @param {String} message A human-readable status message related to the
|
||||
* operation performed.
|
||||
* @param {Number} code The error code associated with the operation.
|
||||
*/
|
||||
this.onack = null;
|
||||
|
||||
/**
|
||||
* Writes the given base64-encoded data to this stream as a blob.
|
||||
*
|
||||
* @param {String} data The base64-encoded data to send.
|
||||
*/
|
||||
this.write = function(data) {
|
||||
client.sendBlob(guac_stream.index, data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Closes this stream.
|
||||
*/
|
||||
this.close = function() {
|
||||
client.endStream(guac_stream.index);
|
||||
};
|
||||
|
||||
};
|
159
guacamole-common-js/src/main/resources/modules/Parser.js
Normal file
159
guacamole-common-js/src/main/resources/modules/Parser.js
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
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 (length == NaN)
|
||||
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;
|
||||
|
||||
};
|
@@ -20,12 +20,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for all Guacamole JavaScript objects.
|
||||
* @ignore
|
||||
* @namespace
|
||||
*/
|
||||
var Guacamole = Guacamole || {};
|
||||
|
||||
/**
|
@@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Namespace for all Guacamole JavaScript objects.
|
||||
* @ignore
|
||||
* @namespace
|
||||
*/
|
||||
var Guacamole = Guacamole || {};
|
Reference in New Issue
Block a user