Implement pipe instruction and handlers.
This commit is contained in:
parent
a6a72d950c
commit
d0d34a63b9
@ -39,6 +39,7 @@ __guac_instruction_handler_mapping __guac_instruction_handler_map[] = {
|
||||
{"disconnect", __guac_handle_disconnect},
|
||||
{"size", __guac_handle_size},
|
||||
{"file", __guac_handle_file},
|
||||
{"pipe", __guac_handle_pipe},
|
||||
{"ack", __guac_handle_ack},
|
||||
{"blob", __guac_handle_blob},
|
||||
{"end", __guac_handle_end},
|
||||
@ -153,6 +154,43 @@ int __guac_handle_file(guac_client* client, guac_instruction* instruction) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __guac_handle_pipe(guac_client* client, guac_instruction* instruction) {
|
||||
|
||||
/* Pull corresponding stream */
|
||||
int stream_index = atoi(instruction->argv[0]);
|
||||
guac_stream* stream;
|
||||
|
||||
/* Validate stream index */
|
||||
if (stream_index < 0 || stream_index >= GUAC_CLIENT_MAX_STREAMS) {
|
||||
|
||||
guac_stream dummy_stream;
|
||||
dummy_stream.index = stream_index;
|
||||
|
||||
guac_protocol_send_ack(client->socket, &dummy_stream,
|
||||
"Invalid stream index", GUAC_PROTOCOL_STATUS_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize stream */
|
||||
stream = &(client->__input_streams[stream_index]);
|
||||
stream->index = stream_index;
|
||||
stream->data = NULL;
|
||||
|
||||
/* If supported, call handler */
|
||||
if (client->pipe_handler)
|
||||
return client->pipe_handler(
|
||||
client,
|
||||
stream,
|
||||
instruction->argv[1], /* mimetype */
|
||||
instruction->argv[2] /* name */
|
||||
);
|
||||
|
||||
/* Otherwise, abort */
|
||||
guac_protocol_send_ack(client->socket, stream,
|
||||
"Named pipes unsupported", GUAC_PROTOCOL_STATUS_UNSUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __guac_handle_ack(guac_client* client, guac_instruction* instruction) {
|
||||
|
||||
guac_stream* stream;
|
||||
|
@ -94,6 +94,13 @@ int __guac_handle_clipboard(guac_client* client, guac_instruction* instruction);
|
||||
*/
|
||||
int __guac_handle_file(guac_client* client, guac_instruction* instruction);
|
||||
|
||||
/**
|
||||
* Internal initial handler for the pipe instruction. When a pipe instruction
|
||||
* is received, this handler will be called. The client's pipe handler will
|
||||
* be invoked if defined.
|
||||
*/
|
||||
int __guac_handle_pipe(guac_client* client, guac_instruction* instruction);
|
||||
|
||||
/**
|
||||
* Internal initial handler for the ack instruction. When a ack instruction
|
||||
* is received, this handler will be called. The client's ack handler will
|
||||
|
@ -85,6 +85,12 @@ typedef int guac_client_size_handler(guac_client* client,
|
||||
typedef int guac_client_file_handler(guac_client* client, guac_stream* stream,
|
||||
char* mimetype, char* filename);
|
||||
|
||||
/**
|
||||
* Handler for Guacamole pipe events.
|
||||
*/
|
||||
typedef int guac_client_pipe_handler(guac_client* client, guac_stream* stream,
|
||||
char* mimetype, char* name);
|
||||
|
||||
/**
|
||||
* Handler for Guacamole stream blob events.
|
||||
*/
|
||||
@ -402,6 +408,25 @@ struct guac_client {
|
||||
*/
|
||||
guac_client_file_handler* file_handler;
|
||||
|
||||
/**
|
||||
* Handler for pipe events sent by the Guacamole web-client.
|
||||
*
|
||||
* The handler takes a guac_stream which contains the stream index and
|
||||
* will persist through the duration of the transfer, the mimetype of
|
||||
* the data being transferred, and the pipe name.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* int pipe_handler(guac_client* client, guac_stream* stream,
|
||||
* char* mimetype, char* name);
|
||||
*
|
||||
* int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
* client->pipe_handler = pipe_handler;
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
guac_client_pipe_handler* pipe_handler;
|
||||
|
||||
/**
|
||||
* Handler for ack events sent by the Guacamole web-client.
|
||||
*
|
||||
|
@ -412,6 +412,21 @@ int guac_protocol_send_audio(guac_socket* socket, const guac_stream* stream,
|
||||
int guac_protocol_send_file(guac_socket* socket, const guac_stream* stream,
|
||||
const char* mimetype, const char* name);
|
||||
|
||||
/**
|
||||
* Sends a pipe instruction over the given guac_socket connection.
|
||||
*
|
||||
* If an error occurs sending the instruction, a non-zero value is
|
||||
* returned, and guac_error is set appropriately.
|
||||
*
|
||||
* @param socket The guac_socket connection to use.
|
||||
* @param stream The stream to use.
|
||||
* @param mimetype The mimetype of the data being sent.
|
||||
* @param name An arbitrary name uniquely identifying this pipe.
|
||||
* @return Zero on success, non-zero on error.
|
||||
*/
|
||||
int guac_protocol_send_pipe(guac_socket* socket, const guac_stream* stream,
|
||||
const char* mimetype, const char* name);
|
||||
|
||||
/**
|
||||
* Writes a block of data to the currently in-progress blob which was already
|
||||
* created.
|
||||
|
@ -982,6 +982,26 @@ int guac_protocol_send_nop(guac_socket* socket) {
|
||||
|
||||
}
|
||||
|
||||
int guac_protocol_send_pipe(guac_socket* socket, const guac_stream* stream,
|
||||
const char* mimetype, const char* name) {
|
||||
|
||||
int ret_val;
|
||||
|
||||
guac_socket_instruction_begin(socket);
|
||||
ret_val =
|
||||
guac_socket_write_string(socket, "4.pipe,")
|
||||
|| __guac_socket_write_length_int(socket, stream->index)
|
||||
|| guac_socket_write_string(socket, ",")
|
||||
|| __guac_socket_write_length_string(socket, mimetype)
|
||||
|| guac_socket_write_string(socket, ",")
|
||||
|| __guac_socket_write_length_string(socket, name)
|
||||
|| guac_socket_write_string(socket, ";");
|
||||
|
||||
guac_socket_instruction_end(socket);
|
||||
return ret_val;
|
||||
|
||||
}
|
||||
|
||||
int guac_protocol_send_png(guac_socket* socket, guac_composite_mode mode,
|
||||
const guac_layer* layer, int x, int y, cairo_surface_t* surface) {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user