diff --git a/guacamole-common-js/src/main/webapp/modules/Client.js b/guacamole-common-js/src/main/webapp/modules/Client.js index c95dcf80e..b000045d4 100644 --- a/guacamole-common-js/src/main/webapp/modules/Client.js +++ b/guacamole-common-js/src/main/webapp/modules/Client.js @@ -284,6 +284,24 @@ Guacamole.Client = function(tunnel) { tunnel.sendMessage("file", index, mimetype, filename); }; + /** + * Opens a new pipe for writing, having the given index, mimetype and + * name. + * + * @param {Number} index The index of the pipe to write to. This index must + * be unused. + * @param {String} mimetype The mimetype of the data being sent. + * @param {String} name The name of the pipe. + */ + this.beginPipeStream = function(index, mimetype, name) { + + // Do not send requests if not connected + if (!isConnected()) + return; + + tunnel.sendMessage("pipe", index, mimetype, name); + }; + /** * Given the index of a file, writes a blob of data to that file. * @@ -342,6 +360,34 @@ Guacamole.Client = function(tunnel) { }; + /** + * Opens a new pipe for writing, having the given name and mimetype. + * + * @param {String} mimetype The mimetype of the data being sent. + * @param {String} name The name of the pipe. + */ + this.createPipeStream = function(mimetype, name) { + + // Allocate index + var index = stream_indices.next(); + + // Create new stream + guac_client.beginPipeStream(index, mimetype, name); + var stream = output_streams[index] = new Guacamole.OutputStream(guac_client, index); + + // Override close() of stream to automatically free index + var old_close = stream.close; + stream.close = function() { + old_close(); + stream_indices.free(index); + delete output_streams[index]; + }; + + // Return new, overridden stream + return stream; + + }; + /** * Fired whenever the state of this Guacamole.Client changes. * @@ -398,6 +444,18 @@ Guacamole.Client = function(tunnel) { */ this.onfile = null; + /** + * Fired when a pipe stream is created. The stream provided to this event + * handler will contain its own event handlers for received data and the + * close event. + * + * @event + * @param {String} name The name of the pipe. + * @param {Guacamole.InputStream} stream A stream that will receive + * data from the server. + */ + this.onpipe = null; + /** * Fired whenever a sync instruction is received from the server, indicating * that the server is finished processing any input from the client and @@ -878,6 +936,25 @@ Guacamole.Client = function(tunnel) { parser.receive(parameters[1]); }, + "pipe": function(parameters) { + + var stream_index = parseInt(parameters[0]); + var mimetype = parameters[1]; + var name = parameters[2]; + + // Create stream + var stream = streams[stream_index] = + new Guacamole.InputStream(mimetype); + + // Call handler now that pipe stream is created + if (guac_client.onpipe) + guac_client.onpipe(name, stream); + + // Send success response + tunnel.sendMessage("ack", stream_index, "OK", 0x0000); + + }, + "png": function(parameters) { var channelMask = parseInt(parameters[0]);