From 321e24c4176750384dacbc16cff30d9c35da6c20 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Thu, 26 Sep 2013 22:49:45 -0700 Subject: [PATCH] Add actual handlers for file/blob/end. --- src/libguac/client-handlers.c | 71 ++++++++++++++++++++++++++--- src/libguac/guacamole/client.h | 83 ++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 6 deletions(-) diff --git a/src/libguac/client-handlers.c b/src/libguac/client-handlers.c index ee3475c8..dc82bbb1 100644 --- a/src/libguac/client-handlers.c +++ b/src/libguac/client-handlers.c @@ -130,20 +130,79 @@ int __guac_handle_size(guac_client* client, guac_instruction* instruction) { } int __guac_handle_file(guac_client* client, guac_instruction* instruction) { - /* STUB */ - guac_client_log_info(client, "STUB: file"); + + if (client->file_handler) { + + /* 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) { + /* TODO: Return failing ack */ + return 0; + } + + /* Initialize stream */ + stream = &(client->__streams[stream_index]); + stream->index = stream_index; + + return client->file_handler( + client, + stream, + instruction->argv[1], /* mimetype */ + instruction->argv[2] /* filename */ + ); + } + + /* TODO: Return failing ack */ return 0; } int __guac_handle_blob(guac_client* client, guac_instruction* instruction) { - /* STUB */ - guac_client_log_info(client, "STUB: blob"); + + if (client->blob_handler) { + + /* Validate stream index */ + int stream_index = atoi(instruction->argv[0]); + if (stream_index < 0 || stream_index >= GUAC_CLIENT_MAX_STREAMS) { + /* TODO: Return failing ack */ + return 0; + } + + /* TODO: Actually decode blob */ + + return client->blob_handler( + client, + &(client->__streams[stream_index]), + "TODO", + 4 + ); + + } + + /* TODO: Return failing ack */ return 0; } int __guac_handle_end(guac_client* client, guac_instruction* instruction) { - /* STUB */ - guac_client_log_info(client, "STUB: end"); + + if (client->end_handler) { + + /* Pull corresponding stream */ + int stream_index = atoi(instruction->argv[0]); + + /* Validate stream index */ + if (stream_index < 0 || stream_index >= GUAC_CLIENT_MAX_STREAMS) + return 0; + + return client->end_handler( + client, + &(client->__streams[stream_index]) + ); + + } + return 0; } diff --git a/src/libguac/guacamole/client.h b/src/libguac/guacamole/client.h index 0e2e78ea..fc58506e 100644 --- a/src/libguac/guacamole/client.h +++ b/src/libguac/guacamole/client.h @@ -54,6 +54,11 @@ * @file client.h */ +/** + * The maximum number of inbound streams supported by any one guac_client. + */ +#define GUAC_CLIENT_MAX_STREAMS 64 + typedef struct guac_client guac_client; /** @@ -83,6 +88,23 @@ typedef int guac_client_clipboard_handler(guac_client* client, char* copied); typedef int guac_client_size_handler(guac_client* client, int width, int height); +/** + * Handler for Guacamole file transfer events. + */ +typedef int guac_client_file_handler(guac_client* client, guac_stream* stream, + char* mimetype, char* filename); + +/** + * Handler for Guacamole stream blob events. + */ +typedef int guac_client_blob_handler(guac_client* client, guac_stream* stream, + void* data, int length); + +/** + * Handler for Guacamole stream end events. + */ +typedef int guac_client_end_handler(guac_client* client, guac_stream* stream); + /** * Handler for Guacamole audio format events. */ @@ -355,6 +377,62 @@ struct guac_client { */ guac_client_size_handler* size_handler; + /** + * Handler for file 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 file being transferred, and the filename. + * + * Example: + * @code + * int file_handler(guac_client* client, guac_stream* stream, + * char* mimetype, char* filename); + * + * int guac_client_init(guac_client* client, int argc, char** argv) { + * client->file_handler = file_handler; + * } + * @endcode + */ + guac_client_file_handler* file_handler; + + /** + * Handler for blob 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, an arbitrary buffer + * containing the blob, and the length of the blob. + * + * Example: + * @code + * int blob_handler(guac_client* client, guac_stream* stream, + * void* data, int length); + * + * int guac_client_init(guac_client* client, int argc, char** argv) { + * client->blob_handler = blob_handler; + * } + * @endcode + */ + guac_client_blob_handler* blob_handler; + + /** + * Handler for stream end events sent by the Guacamole web-client. + * + * The handler takes only a guac_stream which contains the stream index. + * This guac_stream will be disposed of immediately after this event is + * finished. + * + * Example: + * @code + * int end_handler(guac_client* client, guac_stream* stream); + * + * int guac_client_init(guac_client* client, int argc, char** argv) { + * client->end_handler = end_handler; + * } + * @endcode + */ + guac_client_end_handler* end_handler; + /** * Handler for freeing data when the client is being unloaded. * @@ -446,6 +524,11 @@ struct guac_client { */ guac_pool* __stream_pool; + /** + * All available input streams (data coming from connected client). + */ + guac_stream __streams[GUAC_CLIENT_MAX_STREAMS]; + }; /**