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},
|
{"disconnect", __guac_handle_disconnect},
|
||||||
{"size", __guac_handle_size},
|
{"size", __guac_handle_size},
|
||||||
{"file", __guac_handle_file},
|
{"file", __guac_handle_file},
|
||||||
|
{"pipe", __guac_handle_pipe},
|
||||||
{"ack", __guac_handle_ack},
|
{"ack", __guac_handle_ack},
|
||||||
{"blob", __guac_handle_blob},
|
{"blob", __guac_handle_blob},
|
||||||
{"end", __guac_handle_end},
|
{"end", __guac_handle_end},
|
||||||
@ -153,6 +154,43 @@ int __guac_handle_file(guac_client* client, guac_instruction* instruction) {
|
|||||||
return 0;
|
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) {
|
int __guac_handle_ack(guac_client* client, guac_instruction* instruction) {
|
||||||
|
|
||||||
guac_stream* stream;
|
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);
|
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
|
* Internal initial handler for the ack instruction. When a ack instruction
|
||||||
* is received, this handler will be called. The client's ack handler will
|
* 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,
|
typedef int guac_client_file_handler(guac_client* client, guac_stream* stream,
|
||||||
char* mimetype, char* filename);
|
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.
|
* Handler for Guacamole stream blob events.
|
||||||
*/
|
*/
|
||||||
@ -402,6 +408,25 @@ struct guac_client {
|
|||||||
*/
|
*/
|
||||||
guac_client_file_handler* file_handler;
|
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.
|
* 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,
|
int guac_protocol_send_file(guac_socket* socket, const guac_stream* stream,
|
||||||
const char* mimetype, const char* name);
|
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
|
* Writes a block of data to the currently in-progress blob which was already
|
||||||
* created.
|
* 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,
|
int guac_protocol_send_png(guac_socket* socket, guac_composite_mode mode,
|
||||||
const guac_layer* layer, int x, int y, cairo_surface_t* surface) {
|
const guac_layer* layer, int x, int y, cairo_surface_t* surface) {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user